Чтение аудио с помощью расширенных файловых сервисов аудио (ExtAudioFileRead) - PullRequest
4 голосов
/ 15 марта 2010

Я работаю над пониманием Core Audio, а точнее: Расширенные аудиофайлы

Здесь я хочу использовать ExtAudioFileRead() для чтения некоторых аудиоданных из файла.
Это прекрасно работает, пока я использую один огромный буфер для хранения своих аудиоданных (то есть один AudioBuffer). Как только я использую более одного AudioBuffer, ExtAudioFileRead() возвращает код ошибки -50 («ошибка в списке параметров»). Насколько я могу понять, это означает, что один из аргументов ExtAudioFileRead() неверен. Вероятно, audioBufferList.

Я не могу использовать один огромный буфер, потому что тогда dataByteSize переполнит диапазон UInt32 -интеграторов огромными файлами.

Вот код для создания audioBufferList:

AudioBufferList *audioBufferList;
audioBufferList = malloc(sizeof(AudioBufferList) + (numBuffers-1)*sizeof(AudioBuffer));
audioBufferList->mNumberBuffers = numBuffers;
for (int bufferIdx = 0; bufferIdx<numBuffers; bufferIdx++ ) {
    audioBufferList->mBuffers[bufferIdx].mNumberChannels = numChannels;
    audioBufferList->mBuffers[bufferIdx].mDataByteSize = dataByteSize;
    audioBufferList->mBuffers[bufferIdx].mData = malloc(dataByteSize);
}

А вот рабочий, но переполненный код:

UInt32 dataByteSize = fileLengthInFrames * bytesPerFrame; // this will overflow
AudioBufferList *audioBufferList = malloc(sizeof(audioBufferList));
audioBufferList->mNumberBuffers = 1;
audioBufferList->mBuffers[0].mNumberChannels = numChannels;
audioBufferList->mBuffers[0].mDataByteSize = dataByteSize;
audioBufferList->mBuffers[0].mData = malloc(dataByteSize);

И, наконец, вызов ExtAudioFileRead() (должен работать с обеими версиями):

UInt32 numFrames = fileLengthInFrames;
error = ExtAudioFileRead(extAudioFileRef,
                         &numFrames,
                         audioBufferList);

Вы знаете, что я здесь не так делаю?

Ответы [ 4 ]

5 голосов
/ 26 марта 2010

Я думаю, вы неправильно понимаете цель поля mNumberBuffers.Обычно это 1 для моно и чередующихся стерео данных.Единственная причина, по которой вы установите его на что-то другое, - это многодорожечные данные, где каждый канал находится в отдельном буфере данных.

Если вы хотите прочитать часть файла, вы должны установить dataByteSize буферадо разумного размера, и когда вы читаете файл, скажите API только, чтобы дать вам столько байтов, и зациклите его.

1 голос
/ 06 апреля 2010

У меня тоже была такая же проблема с mNumberBuffers> 1 ,, ... Моя работа заключалась в создании собственного внутреннего буфера:

что-то вроде:

char buffer1 [byteSize]; char buffer2 [byteSize]; ......

Вы также можете использовать указатели, чтобы упростить задачу, например:

буфер [индекс] [byteSize];

тогда вам придется выполнять их итерацию вручную и заполнять их в главном потоке, чтобы избежать сбоев в аудио.

ExtAudioFileRead будет заполнять только буфер [0] в AudioBufferList, тогда вы могли бы указывать на разные буферы, выделенные вручную при воспроизведении аудио.

надеюсь, это поможет.

0 голосов
/ 21 марта 2017

mNumberBuffers == 2, когда вы имеете дело с не чередованным стерео. Это количество аудиоканалов, если они не чередуются.

0 голосов
/ 16 марта 2010

Какао просто, кажется, не принимает mNumberBuffers> 1. Это позор, потому что делает всю структуру бесполезной. (Надеюсь, это правильно ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...