2012-03-15 5 views
0

トーンレンダリングバッファに1つのトーンを周波数で、もう1つに周波数/ 3で充填します。kLinearPCMFormatFlagIsNonInterleavedをクリアする方法、または設定しない方法

コードを実行すると、バッファがインターリーブされていないものとして出力が読み込まれるように見えます。実際それはcreateToneUnitで設定されています。 サウンドは左スピーカーでのみ再生されます。両方の周波数がバッファに書き込まれると、両方のトーンが左スピーカで再生されます。周波数がバッファに書き込まれていない場合、例えば、 leftON = 0、それらは再生されません。バッファ書き込みコードはOKのように見えます。

私は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

、あなただけ実行してフラグを設定できませんでした:

streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat; 

ので、いないビット-OR他のフラグを計算されたフラグに。
(Cのビット単位の演算子とその動作方法を調べる)

+0

質問100%に答えます。それは私がなぜこのことを考えるべきなのか尋ねる優雅な答えの一つです。 – user1251228

関連する問題