7

Audio Unit Framework を使用して、Mac OS X で VOIP アプリを開発しています。私のプログラムでは、入力 AUHAL をセットアップし、デフォルトのストリーム形式 (44.1kHz、32 ビット/チャネル) を使用して、マイクからオーディオをキャプチャします。この場合、私のプログラムは正常に動作します。

コードは次のとおりです。

//The default setting in my program
CheckError(AudioUnitGetProperty(m_audCapUnit,
                                        kAudioUnitProperty_StreamFormat,
                                        kAudioUnitScope_Output,     //the value is 0
                                        inputBus,           //the value is 1
                                        &m_audCapUnitOutputStreamFormat,
                                        &propertySize),
                   "Couldn't get OutputSample ASBD from input unit") ;  

    //the inOutputSampleRate is 44100.0
        m_audCapUnitOutputStreamFormat.mSampleRate = inOutputSampleRate ; 

CheckError(AudioUnitSetProperty(m_audCapUnit,
                                        kAudioUnitProperty_StreamFormat,
                                        kAudioUnitScope_Output,
                                        inputBus,
                                        &m_audCapUnitOutputStreamFormat,
                                        propertySize),
                   "Couldn't set OutputSample ASBD on input unit"); 

//

私は VOIP アプリを開発しているので、既定の形式 (44.1kHz、32 ビット/チャネル) はプログラムに適していないため、サンプル レートを 8kHz に変更したいと考えています。そして、プログラムのフォーマットを変更するために次のコードを書きました。

//......
    inOutputFormat.mSampleRate = 8000.  ;
    inOutputFormat.mFormatID = kAudioFormatLinearPCM ;
    inOutputFormat.mChannelsPerFrame = 2 ;
    inOutputFormat.mBitsPerChannel  = 16 ;
    inOutputFormat.mBytesPerFrame = 2 ;
    inOutputFormat.mBytesPerPacket = 2 ;
    inOutputFormat.mFramesPerPacket = 1 ;
    inOutputFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical ;   
    inOutputFormat.mReserved = 0 ;



    CheckError(AudioUnitSetProperty(m_audCapUnit,
                                    kAudioUnitProperty_StreamFormat,
                                    kAudioUnitScope_Output,
                                    inputBus, 
                                    &inOutputFormat, 
                                    ui32PropSize),
               "Couldn't set AUHAL Unit Output Format") ;

//.......

AudioUnitRenderこの場合、プログラムがコールバック関数で を呼び出すまで、プログラムは正常に動作します。ドキュメントで意味 AudioUnitRenderするエラーコードでを呼び出すことができません。エラー コードがとても気になったので、ググってみましたが、有益な情報は見つかりませんでした。エラーが実際に何を意味するのか誰か教えてもらえますか?-10876kAudioUnitErr_NoConnection

これで終わりではありません。次のコードでフォーマットを再度変更しました。

//.....
    inOutputFormat.mSampleRate = 8000.  ;
    inOutputFormat.mFormatID = kAudioFormatLinearPCM ;
    inOutputFormat.mChannelsPerFrame = 2 ;
    inOutputFormat.mBitsPerChannel  = 32 ;
    inOutputFormat.mBytesPerFrame = 4 ;
    inOutputFormat.mBytesPerPacket = 4 ;
    inOutputFormat.mFramesPerPacket = 1 ;
    inOutputFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical ;   
    inOutputFormat.mReserved = 0 ;



    CheckError(AudioUnitSetProperty(m_audCapUnit,
                                    kAudioUnitProperty_StreamFormat,
                                    kAudioUnitScope_Output,
                                    inputBus, 
                                    &inOutputFormat, 
                                    ui32PropSize),
               "Couldn't set AUHAL Unit Output Format") ;
//........

この場合、プログラムは をAudioUnitRender再度呼び出すことができず、別のエラー コード を返しまし-10863(kAudioUnitErr_CannotDoInCurrentContext)た。私はそれをググったが、 何か役に立つものを見つけた. そこの情報を読んだ後、AUHAL で設定したサンプルレートまたはフォーマットがハードウェアでサポートされていない可能性があると推測します。

そこで、デフォルトの入力デバイスで使用可能なサンプル レートを確認するコードをいくつか書きました。

//..........
    UInt32 propertySize = sizeof(AudioDeviceID) ;
    Boolean isWritable = false ;

    CheckError(AudioDeviceGetPropertyInfo(inDeviceID,       //the inDeviceID is the default input device
                                          0,
                                          true,
                                          kAudioDevicePropertyAvailableNominalSampleRates,
                                          &propertySize, 
                                          &isWritable), 
               "Get the Available Sample Rate Count Failed") ;

    m_valueCount = propertySize / sizeof(AudioValueRange) ;
    printf("Available %d Sample Rate\n",m_valueCount) ;

    CheckError(AudioDeviceGetProperty(inDeviceID,
                                      0,
                                      false,
                                      kAudioDevicePropertyAvailableNominalSampleRates, 
                                      &propertySize, 
                                      m_valueTabe), 
               "Get the Available Sample Rate Count Failed") ;


    for(UInt32 i = 0 ; i < m_valueCount ; ++i)
    {
        printf("Available Sample Rate value : %ld\n",(long)m_valueTabe[i].mMinimum) ;
    }
//..............

そして、利用可能なサンプルレートが 8000、16000、32000、44100、48000、88200、および 96000 であることを発見しました。

8000 サンプル レートは先ほど設定したものですが、 を呼び出すとエラー コードが表示されAudioUnitRenderます。

私はグーグルをたくさん持っていて、多くのドキュメントも読んでいましたが、答えが得られません.誰かが私が遭遇したこの問題を解決できますか?</p>

言い換えると; 入力のみの AUHAL でサンプル レートまたはフォーマットを変更するにはどうすればよいですか?</p>

4

3 に答える 3

4

最後に、昨日この問題を自分で修正しました。

これが私の解決策です:

  1. まず、AudioDeviceGetPropertyデフォルトの入力デバイスで使用可能なフォーマット リストを取得するために使用します。次に、使用可能なフォーマット リストに次のものが含まれていることがわかりました8khz, 16khz, 32khz, 44.1khz, 48khz, 88.2khz,96khz
  2. 次に、最初のステップで取得した使用可能な形式の 1 つを選択します。私のプログラムを例にとる と、フォーマットを選択し、それ(8khz,32bits/Channel)を使用AudioDeviceSetProperty してデフォルトのデバイスに設定しますが、AUHAL には設定しません。これは、AUHAL (OutputScope 、inputBus) にフォーマットを設定した後にプログラムが正常に動作するための鍵です。
  3. 最後のステップで、 を使用してAudioUnitSetProperty必要なフォーマットを設定すると、プログラムは正常に動作します。

この問題と解決策を通じて、入力専用の AUHAL でフォーマットを設定したい場合、フォーマットは一致する必要があるか、入力デバイスが使用している利用可能なフォーマットにシフトできると思います。ですから、最初に入力デバイスでフォーマットを設定し、次に入力専用の AUHAL でフォーマットを設定する必要があります。

于 2013-08-10T02:17:58.120 に答える