3

これまでのところ、このブログ投稿にあるアルゴリズムを実装しましたが、成功は限定的でした。

私のプログラムの概念は、正弦波を初期化し、画面上のマウスの位置に応じて周波数を変更することです.マウスを上に動かすと正弦波が高くなり、その逆も同様です(本質的にマウスを使用するテルミンタイプの楽器).

これまでに実装した問題は、正弦波の周波数が更新されると、滑らかな周波数スイープを提供する代わりに、離散的な周波数レベルがあるように聞こえるクリック音が発生することです。私はNAudioフォーラムとここで高低を検索してきましたが、NAudioを使用してこの種のことをやろうとしている人や、さらに言えば他のサウンドモジュールを実行しようとしている人は他にないようです。同様に、Kinect のような機器を使用して仮想 MIDI ケーブルと既存のソフトウェア モジュールを使用しますが、外部のソフトウェア パッケージに依存せずに同じ概念を実装したいと考えています。

この問題に関連するコードのセクションを NAudio のフォーラム (こちら) に投稿しました 。ご覧のとおり、MarkHeath の推奨事項に従って、問題の解決策を見つけようとしています。

4

1 に答える 1

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特定の出力周波数fとサンプルレートを計算するにはFs:

delta = FloatToFixed(LUT_SIZE * f / Fs);
于 2011-08-10T09:39:27.810 に答える