2015-02-10 3 views
0

У меня есть кое-что действительно странное (по крайней мере, для меня, но я - нуб).Почему аргумент ioNumBytes из AudioFileReadPacketData вызывает сбой?

UInt32 numBytesReadFromFile; 
OSStatus err = AudioFileReadPacketData(
            audioFile, // The audio file whose audio packets you want to read. 
            NO, // is cache set? 
            &numBytesReadFromFile, // On output, the number of bytes of audio data that were read from the audio file. 
            (AudioStreamPacketDescription *)_packetDescriptions, // array of packet descriptions of data that was read from the audio file (for CBR null) 
            currentPacket, // the next packet to be read into buffer 
            &numPackets, // number of actually read buffers 
            _audioQueueBuffer->mAudioData 
            ); 

AudioFileReadPacketData считывает данные из аудиофайла и помещает его в буфер.

Итак, мой вопрос касается аргумента numBytesReadFromFile. Apple writes

numBytesReadFromFile: На выходе число байтов аудиоданных, считанных из звукового файла.

Пока все хорошо. Apple объявляет numBytesReadFromFile, как в приведенном выше примере кода, но для меня эта строка сбоев кода! Я получаю EXC BAD ACCESS.

UInt32 numBytesReadFromFile; 

мне нужно объявить numBytesReadFromFile как это и все работает отлично:

UInt32 numBytesReadFromFile = 2048; // 2048 = size of my buffer 

Однако это выходит из строя слишком

UInt32 numBytesReadFromFile = 12 
UInt32 numBytesReadFromFile = sizeof(UInt32) 

но это не

UInt32 numBytesReadFromFile = 1021; // a random number 

Я нахожусь не очень опытный но насколько я знаю, я резервирую некоторую память, объявляя numBytesReadFromFile, и метод audiofilereadpacketdata записывает свои данные в адрес переменной. Пожалуйста, поправьте меня, если я ошибаюсь.

Так почему же он падает? Я думаю, что я не исправил настоящую проблему.

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

UInt32 numBytesReadFromFile; 

работает отлично. Я запускаю воспроизведение звука, и вызывается обратный вызов, который вызывает AudioFilereadPacketData во внутреннем фоновом потоке аудио очереди, и возникает ошибка, описанная выше. Если мое предположение верно, может кто-нибудь объяснить мне вопрос немного более подробно, поскольку я не испытываю многопоточности.

Спасибо.

+0

Пожалуйста, размещайте больше кода. Что такое 'ioNumBytes' изначально? Соответствует ли ваш размер буфера? – sbooth

+0

Больше нет кода. Все настроено для AudioFileReadDataPack. Необходимо объявить только numBytesReadFromFile, и это делается до того, как вызывается AudioFileReadDataPack. – Duc

ответ

2

Параметр ioNumBytes - AudioFileReadPacketData - это параметр ввода/вывода. documentation говорит:

Ввод, размер параметра outBuffer, в байтах. На выходе количество фактически прочитанных байтов.

Вы увидите разницу в значениях входных и выходных, если размер байт для числа пакетов вы запрашиваете в ioNumPackets параметра меньше, чем размер буфера вы передаете в параметре outBuffer . В этом случае выходное значение для этого параметра равно меньше его входного значения.

Значение, вызываемое функцией, определяет, сколько данных будет записано в буфер. Если код, который вы отправили правильно, numBytesReadFromFile никогда не инициализируется размером _audioQueueBuffer->mAudioData, и программа вылетает из-за того, что пытается записать неопределенный объем данных в _audioQueueBuffer->mAudioData. Попробуйте установить параметр перед вызовом функции:

UInt32 numBytesReadFromFile = _audioQueueBuffer->mAudioDataByteSize; 
OSStatus err = AudioFileReadPacketData(
            audioFile, // The audio file whose audio packets you want to read. 
            NO, // is cache set? 
            &numBytesReadFromFile, // On output, the number of bytes of audio data that were read from the audio file. 
            (AudioStreamPacketDescription *)_packetDescriptions, // array of packet descriptions of data that was read from the audio file (for CBR null) 
            currentPacket, // the next packet to be read into buffer 
            &numPackets, // number of actually read buffers 
            _audioQueueBuffer->mAudioData 
            ); 
+0

Спасибо, но проблема в том, что Apple не инициализирует numBytesReadFromFile тоже. Вот руководство: [link] (https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AQPlayback/PlayingAudio.html#//apple_ref/doc/uid/TP40005343-CH3-SW2) Листинг 3-4. Итак, вы можете уточнить, что означает Apple со входом и выходом? Означает ли это: сначала он считывает значение, хранящееся в numBytesreadFromFile, а затем сохраняет значение в numBytesReadFromFile? – Duc

+1

В примере, который вы использовали, используется 'AudioFileReadPackets', который является более старым API с другой семантикой. С помощью 'AudioFileReadPacketData' необходимо установить' ioNumBytes' количество байтов, которое буфер может удерживать * перед * вызовом функции, и если функция не встретит ошибку, она заменит это значение на возврат с количеством байтов фактически прочитал. – sbooth

+0

Спасибо! Я не заметил, что есть разница. – Duc