1

STボードを使って簡単な楽器を作っています。基本的には、動きや立体角を検知し、角度によってピッチや音量が異なる音を出すセンサーを持っています。私はすでにオーディオコーデックのドライバを持っているので、私がする必要があるのは、サウンドサンプルを生成し、それにサンプルを供給することだけです。これでセンサーから角度の読み取り値を取得できるようになりましたが、難しいのは音の生成方法です。これまでのグーグル検索から、センサーからの読み取り値に応じて周波数と振幅(体積)を設定したsin関数を生成する必要があると思います。しかし、私のコーデックはサンプリングレート0f 48KHzを想定しているので、固定サンプリングレートで異なる周波数の正弦波を生成するにはどうすればよいでしょうか。

これまで私はこれを行いました:

 samplingRate = 48000;
 n = 0;  // reset once there is a change in frequency

// this function is called 48000 times a second
int generateSineWave(float frequency, float volume)
{
  int temp = volume*(sin(2*pi*frequency*n);
  n = n + 1; 
  if (n == samplingRate) {
    n = 0;
  }
  if (abs(temp) > MAXVAL) {
    return ERROR_CODE;
  }
  return temp;
}

これは機能しているようです(私は何かを聞いています)が、それが正しい周波数の正弦波を生成しているかどうかはわかりません。また、私が聞いている音はあまり心地よいものではありませんが、複雑な音(たとえばピアノの音など)を生成するにはどうすればよいですか?また、制御変数(空間角度)はローパスフィルター処理する必要があると思います。しかし、それとは別に、私がより聴覚的に心地よい波を生成する方法についてのアイデアはありますか?

4

1 に答える 1

5

48 kHz(1秒あたり48,000サンプル)でサンプリングしているため、1 Hzの正弦波が1サイクルを完了するには、1秒(48,000サンプル)かかります。したがって、サンプリングレートで正規化または除算する必要があります。

temp = volume * sin(2 * pi * n * frequency / samplingRate);

tempは常にからの範囲内にある必要があることに-volume注意してください。そのvolumeため、一度だけチェックする必要がありvolume < MAXVALます。計算する前にそれを行うことができますtemp。これにより、エラーが(ごくわずかに)より効率的に検出されます。のように、piすでに定義されていることがわかります。M_PImath.h

トーンがあまり心地よくないとおっしゃいました。純粋な正弦波は、よく、純粋で、一般的に心地よい音であるため、これは何かが間違っている可能性があることを示しています。あなたが試みるかもしれない1つの簡単なことは、ゼロクロッシングで正確にトーンを開始および停止することです。そうしないと、トランジションでクリック音や歪みが聞こえます。または、「ランプ」関数を掛けてフェードインおよびフェードアウトすることもできます。この関数は、float短時間で1から0に減らすことで作成できます。

いくつかのC言語のヒント:

•に置き換えることができn = n + 1ます++n

•交換できます

 if (abs(temp) > MAXVAL) {
   return ERROR_CODE;
 }
 return temp;

return abs(temp) > MAXVAL ? ERROR_CODE : temp;

•を保持することを選択した場合はif、単一行の本文にも中括弧を使用することをお勧めします。いつか別の行を追加して中括弧を忘れる可能性があるためです。これは、実際のコードではなく、期待どおりにコードを読み取るため、見つけるのが特に難しいバグです。これで私を信じてください。:-)

于 2012-11-18T00:46:07.393 に答える