AVAudioRecorder не записывает правильный заголовок файла WAV - PullRequest
9 голосов
/ 09 июня 2011

Я работаю над проектом на iPhone, где записываю звук с микрофона устройства с помощью AVAudioRecorder, а затем буду управлять записью.

Чтобы убедиться, что я правильно читаю сэмплы из файла, я использую волновой модуль python, чтобы проверить, возвращает ли он те же сэмплы.

Тем не менее, волновой модуль python возвращает "fmt chunk и / или chunk data missing" при попытке открыть файл wav, сохраненный AVAudioRecorder.

Это настройки, которые я использую для записи файла:

[audioSettings setObject:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[audioSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[audioSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[audioSettings setObject:[NSNumber numberWithFloat:4096] forKey:AVSampleRateKey];
[audioSettings setObject:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
[audioSettings setObject:[NSNumber numberWithBool:YES] forKey:AVLinearPCMIsNonInterleaved];
[audioSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey]; 

После этого я просто звоню в recordForDuration, чтобы фактически сделать запись.

Запись успешна - я могу воспроизвести файл и т. Д., И я могу прочитать в примерах с помощью сервисов AudioFile, но не могу проверить его, потому что не могу открыть файл с помощью волнового модуля Python.

Вот как выглядят первые 128 байтов файла:

1215N:~/Downloads$ od -c --read-bytes 128 testFile.wav
0000000   R   I   F   F   x   H 001  \0   W   A   V   E   f   m   t    
0000020 020  \0  \0  \0 001  \0 001  \0   @ 037  \0  \0 200   >  \0  \0
0000040 002  \0 020  \0   F   L   L   R 314 017  \0  \0  \0  \0  \0  \0
0000060  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000200

Есть идеи, что мне нужно сделать, чтобы AVAudioRecorder записал правильный WAV-заголовок?

Ответы [ 2 ]

33 голосов
/ 08 июля 2011

Программное обеспечение Apple часто создает файлы WAVE с нестандартным (но совместимым со спецификацией) субчанком "FLLR" после субчанка "fmt " и до субчанка "data". Я предполагаю, что «FLLR» означает «заполнитель», и я предполагаю, что целью подчанка является включение какой-либо оптимизации выравнивания данных. Длина вложенного блока обычно составляет около 4000 байтов, но его фактическая длина может варьироваться в зависимости от длины данных, предшествующих ему.

Добавление произвольных подчастей в файлы WAVE обычно считается спецификационным, поскольку WAVE является подмножеством RIFF , а обычная практика обработки файлов RIFF заключается в игнорировании порций и подразделов, которые имеют нераспознанный идентификатор. Идентификатор "FLLR" является "нестандартным" и поэтому должен игнорироваться любым программным обеспечением, которое встречает его.

Существует достаточное количество программного обеспечения, которое обрабатывает формат WAVE гораздо более жестко, чем следовало бы, и я подозреваю, что используемая вами библиотека может быть одной из тех частей программного обеспечения. Например, я видел программное обеспечение, которое предполагает, что аудио байты всегда начинаются со смещения 44 - это неверное предположение.

На самом деле, поиск аудио байтов в файле WAVE должен быть сделан путем нахождения местоположения и размера субчанка "data" в RIFF; это правильный способ найти аудио байты в файле WAVE.

Правильное чтение файлов WAVE должно начинаться с упражнения по поиску и идентификации фрагментов RIFF. Подразделы RIFF имеют 8-байтовый заголовок: 4 байта для поля идентификатора / имени, которое традиционно заполняется удобочитаемыми символами ASCII (например, "fmt "), и 4-байтовое целое число без знака с прямым порядком байтов, указывающее количество байтов в полезная нагрузка данных субчанка - полезная нагрузка данных субчанка следует сразу после его 8-байтового заголовка.

Формат файла WAVE резервирует определенные идентификаторы подчастей (или «имена») как значимые для формата WAVE. В каждом WAVE-файле всегда должно быть не менее двух подчастей:

  1. "fmt " - подчасть с этим идентификатором имеет полезную нагрузку, которая описывает основную информацию о формате аудио: частоту дискретизации, битовую глубину и т. Д.
  2. "data" - у субчанка с этим идентификатором есть действительные аудио байты в его полезной нагрузке

"fact" - следующий наиболее распространенный идентификатор субчанка. Обычно его можно найти в файлах WAVE, в которых используется сжатый кодек, например μ-закон. Посетите эту веб-страницу для энтузиастов для получения дополнительной информации о некоторых из различных идентификаторов подчастей, используемых сегодня в дикой природе, и информации об их структуре полезной нагрузки.

С точки зрения чисто RIFF подчасти не должны появляться в каком-либо определенном порядке в файле или с любым конкретным фиксированным смещением. Однако на практике почти все программное обеспечение ожидает, что субчанк "fmt " будет первым. Это уступка практичности: в начале потока данных удобно знать, какой формат аудио содержит WAVE - это облегчает, например, воспроизведение волнового файла из сетевого потока. Если файл WAVE использует сжатый формат, такой как μ-закон, обычно предполагается, что субчанк "fact" появится сразу после "fmt ".

После того, как куски, определяющие формат, удалены, предположения о расположении, упорядочении и наименовании подчастей должны быть отброшены. На этом этапе программное обеспечение должно находить ожидаемые фрагменты только по имени (например, "data"). Если встречаются фрагменты с нераспознанными именами (например, "FLLR"), эти фрагменты следует просто пропустить и игнорировать. Пропуск субчанка требует чтения его длины, чтобы вы могли пропустить правильное количество байтов.

То, что Apple сделала с субчанком "FLLR", немного необычно, и я не удивлен, что какое-то программное обеспечение его отключило. Я подозреваю, что используемая вами библиотека просто не подготовлена ​​к тому, чтобы иметь дело с присутствием субчанка "FLLR". Я бы посчитал это дефектом в библиотеке. Авторы библиотеки допустили ошибку, вероятно, что-то вроде:

  1. Возможно, они ожидают, что субчанк "data" появится в первых N байтах начала файла, где N - что-то меньше ~ 4 КБ. Они могут перестать смотреть, если они должны сканировать слишком далеко в файл. Подчанк Apple "FLLR" помещает вложенный блок "data" в положение> ~ 4 КБ в файл.

  2. Они могут ожидать, что у субчанка "data" будет определенная порядковая позиция субчанка или смещение байта в RIFF. Возможно, они ожидают, что "data" появится сразу после "fmt ". Это неправильный способ обработки файла RIFF. Порядковый номер и / или позиция смещения субчанка "data" не должны приниматься.

Пока мы говорим о правильной обработке файла WAVE, я мог бы также напомнить всем, что аудиобайты (полезная нагрузка подкадра data) могут не работать точно до конца файла. Допустимо вставлять подчасти после полезной нагрузки data. Некоторые программы используют это для хранения текстового поля «комментарий» в конце файла. Если вы читаете вслепую с начала полезной нагрузки data до EOF, вы можете вставить некоторые фрагменты метаданных в виде звука, который будет звучать как «щелчок» в конце воспроизведения. Вы должны соблюдать поле длины подчанка data и прекратить чтение аудио, как только вы используете всю полезную нагрузку данных - не останавливаться, когда вы нажимаете EOF.

0 голосов
/ 18 июня 2011

Как называется файл, на который вы записываете на диск?У меня была похожая проблема, и я решил ее, добавив .wav в конец моего имени файла ... Я думаю, AVAudioRecorder нужно расширение, чтобы разобраться.

...