13

私はWAVファイルを持っているとしましょう。このファイルには、正確な 1 秒間隔の一連のサイン トーンがあります。FFTW ライブラリを使用して、これらのトーンを順番に抽出したいと考えています。これは特に難しいですか?これについてどうすればいいですか?

また、この種の音色を WAV ファイルに書き込むにはどうすればよいでしょうか? 出力には単純なオーディオ ライブラリのみが必要だと思います。

私が選んだ言語は C です

4

3 に答える 3

23

ファイルのセクションのパワー スペクトルを取得するには:

  • N は 2 の累乗です。たとえば、サンプル レートが 44.1 kHz で、1 秒おきにサンプリングしたい場合は、N = 32768 サンプルとします。

  • サンプルに適切なウィンドウ関数を適用します。たとえば、 Hanningです。

  • ウィンドウ処理されたサンプルをFFTルーチンに渡します。理想的には、実数から複素数への FFT が必要ですが、複素数から複素数への FFT しかない場合は、すべての虚数入力部分に 0 を渡します。

  • FFT 出力ビンの 2 乗の大きさを計算します (re * re + im * im)

  • (オプション) 各振幅二乗出力ビンの 10 * log10 を計算して、振幅値をdBで取得します。

パワー スペクトルが得られたので、あとはピークを特定するだけです。適切な S/N 比があれば、これは非常に簡単です。周波数分解能は、N が大きいほど向上することに注意してください。上記のサンプル レートが 44.1 kHz で N = 32768 の例では、各ビンの周波数分解能は 44100 / 32768 = 1.35 Hz です。

于 2010-05-21T21:51:26.477 に答える
3

あなたは基本的にスペクトルを推定することに興味があります.WAVを読んでそれを離散時間信号に変換する段階をすでに過ぎていると仮定します.

さまざまな方法の中で、最も基本的なのはピリオドグラムです。これは、ウィンドウ化された離散フーリエ変換 (FFT を使用) を取得し、その 2 乗の大きさを維持することになります。これはポールの答えに対応しています。検出したい最低周波数のいくつかの期間にまたがるウィンドウが必要です。例: 正弦波が 10 Hz (周期 = 100 ミリ秒) まで低くなる可能性がある場合、200 ミリ秒または 300 ミリ秒程度 (またはそれ以上) のウィンドウを使用する必要があります。ただし、ピリオドグラムにはいくつかの欠点がありますが、計算は簡単で、高精度が必要ない場合は十分すぎるほどです。

生のピリオドグラムは、スペクトル バイアスと、計算で使用されるサンプル数が増加しても特定の周波数での分散が減少しないという事実のために、適切なスペクトル推定ではありません。

ピリオドグラムは、幅を慎重に選択して複数のウィンドウを平均化することにより、パフォーマンスを向上させることができます (バートレット法)。また、スペクトルを推定する方法は他にもたくさんあります (AR モデリング)。

実際には、完全なスペクトルを推定することに正確に関心があるわけではなく、単一の周波数の位置だけに関心があります。これは、推定されたスペクトルのピークを求めることで実行できます (説明したとおりに実行されます) が、より具体的で強力な (そして複雑な)メソッド(Pisarenko、MUSIC アルゴリズム) によっても実行できます。あなたの場合、それらはおそらくやり過ぎでしょう。

于 2010-05-27T12:15:20.967 に答える
2

WAV ファイルには、リニア パルス符号変調 (LPCM)データが含まれています。これは、固定サンプルレートでの一連の振幅値であることを意味します。RIFF ヘッダーはファイルの先頭に含まれており、サンプリング レートやサンプルあたりのビット数などの情報を伝達します(: 8 kHz 符号付き 16 ビット)。

フォーマットは非常にシンプルで、簡単に独自のロールを作成できます。ただし、 libsndfileなど、プロセスを高速化するために使用できるライブラリがいくつかあります。Simple Direct-media Layer (SDL) / SDL_mixerPortAudioは、再生に適した 2 つのライブラリです。

データを FFTW にフィードする場合は、1 秒のチャンクをバッファリングする必要があります (サンプル レートとサンプルあたりのビット数によってサイズを決定します)。次に、すべてのサンプルを IEEE 浮動小数点に変換します (つまりfloat、またはdoubleFFTW の構成によっては、libsndfileで変換できます)。次に、周波数ドメイン出力を保持する別の配列を作成します。最後に、両方のバッファを に渡し、返されたハンドルfftw_plan_dft_r2c_1dで呼び出すことにより、FFTW プランを作成して実行します。fftw_executefftw_plan

于 2010-05-21T14:20:06.947 に答える