Зацикливание файла AAC с ExtAudioFileRead - ошибка?

Читая аудиофайлы на iOS с помощью ExtAudioFileRead, кажется, что достижение 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).

Ура,

Gregzo

1 ответ

Решение

Woozah!

Попался злой AudioBufferList Tinkerer.

Таким образом, в дополнение к информированию клиента о количестве фактически прочитанных кадров, ExtAudioFileRead также устанавливает AudioBuffers AudioBuffers AudioBufferList 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 следующим образом: один или несколько буферов, в которые считываются аудиоданные.

Ура,

Gregzo

Другие вопросы по тегам