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 处可用的帧数,结果相同:一旦读取最后一个数据包,seek 似乎没有任何效果。

在其他情况下愉快地寻求。

漏洞?特征?即将面掌?我非常感谢解决这个问题的任何帮助!

我正在 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 参数描述为:一个或多个缓冲区,音频数据被读取到其中。

干杯,

格雷佐

于 2014-05-10T09:25:09.873 回答