Как очистить или не установить kLinearPCMFormatFlagIsNonInterleaved - PullRequest
0 голосов
/ 15 марта 2012

В toneRender я заполняю буфер одним тоном на частоте, а другой на частоте / 3.

Когда я запускаю код, это выглядит так, как будто вывод читается так, как если бы буфер не чередовался.Как и положено в createToneUnit.Звук воспроизводится только в левом динамике.Когда обе частоты записываются в буфер, оба тона воспроизводятся в левом динамике.Когда частоты не записываются в буфер, например leftON = 0, они не воспроизводятся.поэтому код записи в буфер выглядит нормально.

Поскольку я подозреваю, что мне не следует устанавливать kLinearPCMFormatFlagIsNonInterleaved в createToneUnit, я попытался «очистить» флаг.Я часами читаю документы, но так и не нашел способа сделать это.Эксперименты привели только к сбоям при запуске приложения.

Как очистить kLinearPCMFormatFlagIsNonInterleaved?

Или как я не могу установить kLinearPCMFormatFlagIsNonInterleaved в первую очередь?(Комментирование streamFormat.mFormatFlags также приводит к сбою.)

Возможно, некоторые другие настройки мешают созданию чересстрочного воспроизведения.

OSStatus RenderTone(
                void *inRefCon, 
                AudioUnitRenderActionFlags  *ioActionFlags, 
                const AudioTimeStamp        *inTimeStamp, 
                UInt32                      inBusNumber, 
                UInt32                      inNumberFrames,
                AudioBufferList             *ioData)
{        
    *)inRefCon;
    float sampleRate = viewController->sampleRate;
    float frequency = viewController->frequency;
    // etc.

    float theta_increment = 2.0 * M_PI * frequency /sampleRate;

    float wave;       
    float theta2;
    float wave2;

    float theta_increment2 =0.3 * theta_increment;

    const int channel = 0;
    Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

    for (UInt32 frame = 0; frame < inNumberFrames;) 
    {                
            theta += theta_increment;
            wave = sin(theta) * playVolume;

            theta2 += theta_increment2;
            wave2 = sin(theta2) * playVolume;

            buffer[frame++] = wave * leftON;    // leftON = 1 or 0
            buffer[frame++] = wave2 * rightON;  // rightON = 1 or 0

            if (theta > 2.0 * M_PI)
            {
                    theta -= 2.0 * M_PI;
            }
    }

    // etc.
}


- (void)createToneUnit
{
    AudioComponentDescription defaultOutputDescription;
    defaultOutputDescription.componentType = kAudioUnitType_Output;
    defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
    defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    defaultOutputDescription.componentFlags = 0;
    defaultOutputDescription.componentFlagsMask = 0;

    // etc.
                               kAudioUnitProperty_SetRenderCallback,
                               kAudioUnitScope_Input,
                               0,
                               &input,
                               sizeof(input));

    const int four_bytes_per_float = 4;
    const int eight_bits_per_byte = 8;

    AudioStreamBasicDescription streamFormat;
    streamFormat.mSampleRate = sampleRate;
    streamFormat.mFormatID = kAudioFormatLinearPCM;
    streamFormat.mFormatFlags =
    kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved;
    streamFormat.mBytesPerPacket = four_bytes_per_float;
    streamFormat.mFramesPerPacket = 1;   
    streamFormat.mBytesPerFrame = four_bytes_per_float;       
    streamFormat.mChannelsPerFrame = 2;   // 2= stereo /
    streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
    err = AudioUnitSetProperty (toneUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &streamFormat,
                                sizeof(AudioStreamBasicDescription));
}

1 Ответ

1 голос
/ 15 марта 2012

В вашем случае вы просто не можете установить флаг, выполнив:

streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat;

и, следовательно, не бит-ИЛИ другой флаг в вычисляемом флаге.
(Посмотрите на побитовые операторы Си и как они работают).

...