2011-08-10 4 views
3

これまでのところ、このblog postで見つかったアルゴリズムは限定された成功率で実装されています。NAudioリアルタイムで周波数をスムーズに変化させることができる正弦波を再生するアルゴリズム

私のプログラムのコンセプトは、正弦波を初期化し、スクリーン上のマウスの位置に応じて周波数を変更することです。マウスを上に動かすと正弦波が高くなります(本質的にテルミン型ハツカネズミ)。

私がこれまで実装してきた問題は、正弦波の周波数が更新されると、スムーズな周波数スイープを提供する代わりに、離散周波数レベル。 NAudioのフォーラムやここでは高低を探していますが、NAudioや他のサウンドモジュールを使ってこのようなことをしようとしている人はいないようです。 Kinectは仮想ミッドケーブルや既存のソフトウェアモジュールなどの機器を使用して同様に動作しますが、私は外部ソフトウェアパッケージに依存することなく同じコンセプトを実装したいと考えています。

この問題に関連するコードのセクションをNAudioのフォーラムhereに掲載しました。ご覧のとおり、私はMarkHeathの提案を参考にして問題を解決しています。

+0

は、あなたが例を投稿することができます:与えられた出力周波数fとサンプル・レートFsためdeltaを計算しますオーディオの? – Shannon

答えて

9

出力波形の不連続性を避ける必要があります(これはあなたが聞こえるクリックです)。これを行う最も簡単な方法は、LUTベースの波形発生器を使用することです。これは、任意の周期的な波形(つまり、純粋な正弦波だけでなく)にも有効です。通常、現在の出力周波数に対応するデルタ値で新しいサンプルごとにインクリメントされる固定小数点位相アキュムレータを使用します。デルタは安全に修正できますが、波形は引き続き連続しています。

擬似コード(1つの出力サンプル用):

const int LUT_SIZE; 
const int LUT[LUT_SIZE]; // waveform lookup table (typically 2^N, N >= 8) 
Fixed index; // current index into LUT (integer + fraction) 
Fixed delta; // delta controls output frequency 

output_value = LUT[(int)index]; 
    // NB: for higher quality use the fractional part of index to interpolate 
    //  between LUT[(int)index] and LUT[(int)index + 1], rather than just 
    //  truncating the index and using LUT[(int)index] only. Depends on both 
    //  LUT_SIZE and required output quality. 
index = (index + delta) % LUT_SIZE; 


注:

delta = FloatToFixed(LUT_SIZE * f/Fs); 
+0

ポールありがとう、私はこれを試してみましょう!あなたはそれを実装する方法を見てみることができる任意のウェブサイト/チュートリアルを知っていますか? –

+0

実装の詳細のいくつかはお使いのOSやオーディオAPIに特有のものですが、Googleで「波形ルックアップテーブルの合成」などをお試しいただいている場合は、たくさんのヒットが得られるはずです。 –

+0

最後の行のインデックスを 'output_index'にするべきではありませんか? –

関連する問題