4

ExtAudioFileRead を使用して iOS でオーディオ ファイルを読み取ると、eof に達するとリーダーが完全にフリーズするようです… 例では、_abl AudioBufferList と _eaf ExtendedAudioFileRef が割り当てられ、正しく構成されていると仮定します。

- ( void )testRead
{
    UInt32 requestedFrames = 1024;
    UInt32 numFrames = requestedFrames;
    OSStatus error = 0;

    error = ExtAudioFileRead( _eaf, &numFrames, _abl );

    if( numFrames < requestedFrames ) //eof, want to read enough frames from the beginning of the file to reach requestedFrames and loop gaplessly
    {
         requestedFrames = requestedFrames - numFrames;
         numFrames = requestedFrames;
         // move some pointers in _abl's buffers to write at the correct offset
         error = ExtAudioFileSeek( _eaf, 0 );
         error = ExtAudioFileRead( _eaf, &numFrames, _abl );
         if( numFrames != requestedFrames ) //Now this call always sets numFrames to the same value as the previous read call...
         {
             NSLog( @"Oh no!" );
         }
    }
}

エラーは発生せず、リーダーがファイルの最後でスタックしたかのように、常に同じ動作をします。ExtAudioFileTell は要求されたシークを確認します。また、ファイル内の位置を追跡して、eof で利用可能なフレーム数のみを要求しようとしましたが、同じ結果になりました。最後のパケットが読み取られるとすぐに、シークは効果がないようです。

他の状況で喜んで探します。

バグ?特徴?差し迫った顔の手のひら?これを解決するための助けをいただければ幸いです。

これを iPad 3 ( iOS7.1 ) でテストしています。

乾杯、

グレッグゾ

4

1 に答える 1

5

ウーザ!

わかった、邪悪な AudioBufferList のいじくり回し。

そのため、ExtAudioFileRead は、実際に読み取られたフレーム数をクライアントに通知するだけでなく、AudioBufferList の AudioBuffers mDataByteSize を読み取ったバイト数に設定します。読み取りをその値にクランプするため、eof でリセットしないと、要求するよりも少ないフレームを永続的に取得することになります。

そのため、eof に達したら、abl のバッファー サイズをリセットするだけです。

-( void )resetABLBuffersSize: ( AudioBufferList * )alb size: ( UInt32 )size
{
     AudioBuffer * buffer;
     UInt32 i;

     for( i = 0; i < abl->mNumberBuffers; i++ )
     {
         buffer = &( abl->mBuffers[ i ] );
         buffer->mDataByteSize = size;
     }
}

これは文書化されるべきではありませんか?公式ドキュメントでは、AudioBufferList パラメーターについて次のようにしか説明されていません。オーディオ データが読み込まれる 1 つ以上のバッファー。

乾杯、

グレッグゾ

于 2014-05-10T09:25:09.873 に答える