12

AVAudioRecorder を使用してデバイスのマイクからオーディオを録音し、録音を操作する iPhone のプロジェクトに取り組んでいます。

ファイルからサンプルを正しく読み込んでいることを確認するために、python の wave モジュールを使用して、同じサンプルが返されるかどうかを確認しています。

ただし、Python の wave モジュールは、AVAudioRecorder によって保存された wav ファイルを開こうとすると、「fmt チャンクおよび/またはデータ チャンクが見つかりません」を返します。

これらは、ファイルを記録するために使用している設定です。

[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

正しい WAV ヘッダーが AVAudioRecorder によって書き出されることを確認するために何をする必要があるか考えていますか?

4

2 に答える 2

40

"FLLR"Apple ソフトウェアは、サブチャンクの後、"fmt "サブチャンクの前に非標準の (しかし「仕様」に準拠した) サブチャンクを含む WAVE ファイルを作成することがよくあります"data"。「FLLR」は「フィラー」の略であり、サブチャンクの目的は、ある種のデータ配置の最適化を可能にすることだと思います。サブチャンクの長さは通常約 4000 バイトですが、実際の長さはその前のデータの長さによって異なります。

WAVE はRIFFのサブセットであるため、WAVE ファイルに任意のサブチャンクを追加することは、一般に仕様に準拠していると見なされます。RIFFファイル処理の一般的な方法は、認識されない識別子を持つチャンクとサブチャンクを無視することです。識別子"FLLR"は「非標準」であるため、これに遭遇したソフトウェアは無視する必要があります。

WAVE フォーマットを必要以上に厳密に扱うソフトウェアがかなりの数ありますが、あなたが使用しているライブラリはそれらのソフトウェアの 1 つかもしれません。たとえば、オーディオ バイトが常にオフセット 44 で始まると想定しているソフトウェアを見たことがありますが、これは間違った想定です。

実際、WAVE ファイル内のオーディオ バイトを見つけるには"data"、RIFF 内のサブチャンクの場所とサイズを見つける必要があります。これは、WAVE ファイル内のオーディオ バイトを見つける正しい方法です。

WAVE ファイルを適切に読み取ることは、RIFF サブチャンクを見つけて識別する練習として実際に開始する必要があります。RIFF サブチャンクには 8 バイトのヘッダーがあります。4 バイトは、伝統的に人間が読める ASCII 文字で埋められる識別子/名前フィールド用であり (例: "fmt ")、サブチャンクのデータのバイト数を指定する 4 バイトのリトル エンディアンの符号なし整数です。ペイロード -- サブチャンクのデータ ペイロードは、8 バイトのヘッダーの直後に続きます。

WAVE ファイル形式では、特定のサブチャンク識別子 (または「名前」) が WAVE 形式にとって意味のあるものとして予約されています。すべての WAVE ファイルに常に表示される必要があるサブチャンクが少なくとも 2 つあります。

  1. "fmt "- この識別子を持つサブチャンクには、オーディオのフォーマットに関する基本情報 (サンプルレート、ビット深度など) を記述するペイロードがあります。
  2. "data"- この識別子を持つサブチャンクには、ペイロードに実際のオーディオ バイトが含まれます

"fact"次に一般的なサブチャンク識別子です。通常、μ-law などの圧縮コーデックを使用する WAVE ファイルに含まれています。現在、実際に使用されているさまざまなサブチャンク識別子の一部と、それらのペイロード構造に関する情報については、熱心な Web ページを参照してください。

純粋に RIFF の観点から、サブチャンクはファイル内で特定の順序で表示される必要はなく、特定の固定オフセットで表示される必要もありません。ただし、実際には、ほとんどすべてのソフトウェアが、"fmt "サブチャンクが最初のサブチャンクであることを想定しています。これは実用性への譲歩です。データ ストリームの早い段階で、WAVE に含まれるオーディオのフォーマットを知ると便利です。これにより、たとえば、ネットワーク ストリームからの Wave ファイルの再生が容易になります。WAVE ファイルが μ-law などの圧縮形式を使用している場合、通常、"fact"サブチャンクは の直後に現れると想定され"fmt "ます。

フォーマットを指定するチャンクが邪魔にならなくなったら、サブチャンクの場所、順序、および命名に関する仮定を放棄する必要があります。この時点で、ソフトウェアは予想されるサブチャンクを名前だけで検索する必要があります (例: "data")。認識されない名前 (例: "FLLR") を持つサブチャンクに遭遇した場合、それらのサブチャンクは単純にスキップして無視する必要があります。サブチャンクをスキップするには、正しいバイト数をスキップできるように、その長さを読み取る必要があります。

Apple が"FLLR"サブチャンクで行ったことは少し変わっているし、一部のソフトウェアがそれによってつまずいたとしても、私は驚かない。あなたが使用しているライブラリは、"FLLR"サブチャンクの存在を処理する準備ができていないだけだと思います。これはライブラリの欠陥だと思います。ライブラリの作成者が犯した間違いは、おそらく次のようなものです。

  1. "data"サブチャンクがファイルの先頭の最初の N バイト (N は ~4kB 未満) 内に現れることを期待している可能性があります。ファイルの奥までスキャンしなければならない場合は、検索をあきらめる可能性があります。Appleサブチャンクは、サブチャンクをファイル内の >~4kB の位置に"FLLR"プッシュします。"data"

  2. 彼らは、"data"サブチャンクがRIFF内の特定の序数のサブチャンク位置またはバイトオフセットを持つことを期待しているかもしれません。"data"おそらく、彼らはの直後に現れることを期待しています"fmt "。ただし、これは RIFF ファイルを処理する方法としては正しくありません。サブチャンクの順序位置および/またはオフセット位置は"data"想定されるべきではありません。

正しい WAVE ファイル処理について話している限り、オーディオ バイト (dataサブチャンクのペイロード) がファイルの最後まで正確に実行されない可能性があることを皆さんに思い出してもらいたいと思います。ペイロードの後に​​サブチャンクを挿入することは許容されdataます。一部のプログラムは、これを使用して、ファイルの末尾にテキストの「コメント」フィールドを保存します。ペイロードの開始からdataEOF までやみくもに読み取ると、一部のメタデータ サブチャンクをオーディオとして取り込むことができ、再生の最後に「クリック」のように聞こえます。サブチャンクの長さフィールドを尊重し、dataデータ ペイロード全体を消費したらオーディオの読み取りを停止する必要があります。EOF に達したときに停止するのではありません。

于 2011-07-08T00:52:34.877 に答える
1

ディスクに記録しているファイルの名前は何ですか? 同様の問題があり、ファイル名の最後に追加することで解決しました...物事を理解するには拡張子が必要.wavだと思います。AVAudioRecorder

于 2011-06-17T20:31:18.770 に答える