3

AudioQueue サービスの使用に関して少し問題があります。Apple の Web サイトにあるガイドに従っていますが、Audio Queue を起動して実行すると、「AudioConverterNew が -50 を返しました」というメッセージが表示されます。これで、エラー コード -50 は、パラメーターが正しくないことを意味することがわかりました。ただし、どのパラメーターが悪いのかはわかりません (Apple に感謝します...) !


だから、ここに私のコードがあります。

cPlayerCocoaという名前の私のクラスのパラメータは次のとおりです

AudioQueueRef                   mQueue;
AudioQueueBufferRef             mBuffers[NUMBER_BUFFERS];    // NUMBER_BUFFERS = 3
uint32                          mBufferByteSize;
AudioStreamBasicDescription     mDataFormat;

最初の関数は次のとおりです。

static void
BuildBuffer( void* iAQData, AudioQueueRef iAQ, AudioQueueBufferRef iBuffer )
{
    cPlayerCocoa* player = (cPlayerCocoa*) iAQData;
    player->HandleOutputBuffer( iAQ, iBuffer );
}

AudioQueue を含む構造体から cPlayerCocoa を作成し、オーディオ バッファーを割り当てる HandleOutputBuffer 関数を呼び出します。

void
cPlayerCocoa::HandleOutputBuffer( AudioQueueRef iAQ, AudioQueueBufferRef iBuffer )
{
    if( mContinue )
    {
        xassert( iBuffer->mAudioDataByteSize == 32768 );
        int startSample = mPlaySampleCurrent;
        int result = 0;

        int samplecount = 32768 / ( mSoundData->BytesPerSample() );    // BytesPerSample, in my case, returns 4
        tErrorCode  error = mSoundData->ReadData( (int16*)(iBuffer->mAudioData), samplecount, &result, startSample );

        AudioQueueEnqueueBuffer( mQueue, iBuffer, 0, 0 );    // I'm using CBR data (PCM), hence the 0 passed into the AudioQueueEnqueueBuffer.
        if( result != samplecount )
            mContinue = false;
        startSample += result;
    }      
    else
    {
        AudioQueueStop( mQueue, false );
    }
}

この次の関数では、AudioQueue が作成されてから開始されます。データ形式のパラメーターの初期化を開始します。次に、AudioQueue を作成し、3 つのバッファーを割り当てます。バッファーが割り当てられたら、AudioQueue を開始し、ループを実行します。

void
cPlayerCocoa::ThreadEntry()
{
    int samplecount = 32768 / ( mSoundData->BytesPerSample() );
    mDataFormat.mSampleRate = mSoundData->SamplingRate();    // Returns 44100
    mDataFormat.mFormatID = kAudioFormatLinearPCM;
    mDataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    mDataFormat.mBytesPerPacket = 32768;
    mDataFormat.mFramesPerPacket = samplecount;
    mDataFormat.mBytesPerFrame = mSoundData->BytesPerSample();    // BytesPerSample returns 4.
    mDataFormat.mChannelsPerFrame = 2;
    mDataFormat.mBitsPerChannel = uint32(mSoundData->BitsPerChannel());
    mDataFormat.mReserved = 0;

    AudioQueueNewOutput( &mDataFormat, BuildBuffer, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue );
    for( int i = 0; i < NUMBER_BUFFERS; ++i )
    {
        AudioQueueAllocateBuffer( mQueue, mBufferByteSize, &mBuffers[i] );
        HandleOutputBuffer( mQueue, mBuffers[i] );
    }

    AudioQueueStart( mQueue, NULL );    // I want the queue to start playing immediately, so I pass NULL
    do {
        CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.25, false );
    } while ( !NeedStopASAP() );

    AudioQueueDispose( mQueue, true );
}

AudioQueueStart の呼び出しが -50 (不正なパラメーター) を返し、何が問題なのかわかりません...助けていただければ幸いです。事前に感謝します :-)

4

1 に答える 1

3

あなたのASBDは疑わしいと思います。PCM 形式にはmBytesPerPacket、 、mBytesPerFrame、およびの予測可能な値がありmFramesPerPacketます。通常の 16 ビット インターリーブ符号付き 44.1 ステレオ オーディオの場合、ASBD は次のようになります。

AudioStreamBasicDescription asbd = {
  .mFormatID = kAudioFormatLinearPCM,
  .mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
  .mSampleRate = 44100,
  .mChannelsPerFrame = 2,
  .mBitsPerChannel = 16,
  .mBytesPerPacket = 4,
  .mFramesPerPacket = 1,
  .mBytesPerFrame = 4,
  .mReserved = 0
};

AudioConverterNewASBD の 1 つがサポートされていない場合、-50 を返します。32768 になるはずの PCM 形式が存在しないmBytesPerPacketため、エラーが発生します。

于 2013-09-05T23:13:59.797 に答える