2

処理を使用してマイクから周波数を取得しようとしています。ドキュメントの 2 つの例をミックスしましたが、「最高」は実際には Hz ではありません (a は 440 Hz)。これよりも優れたものを手に入れる方法を知っていますか?

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioInput in;
FFT fft;
int highest=0;

void setup()
{
  size(1024, 200, P2D);

  minim = new Minim(this);
  minim.debugOn();

  in = minim.getLineIn(Minim.MONO, 4096, 44100);
  fft = new FFT(in.left.size(), 44100);
}

void draw()
{


  background(0);
  stroke(255);

  fft.forward(in.left);
  highest=0;
  for (int n = 0; n < fft.specSize(); n++) {
    // draw the line for frequency band n, scaling it by 4 so we can see it a bit better
    line(n/4, height, n/4, height - fft.getBand(n)*4);

    //find frequency with highest amplitude
    if (fft.getBand(n)>fft.getBand(highest))
      highest=n;
  }
  println(highest);

  //println(fft.getFreq(110));
  // draw the waveforms
  for (int i = 0; i < in.bufferSize() - 1; i++)
  {
    line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
    line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
  }
}


void stop()
{
  // always close Minim audio classes when you are done with them
  in.close();
  minim.stop();

  super.stop();
}
4

1 に答える 1

3

取得したいものに応じて、少し変換を行う必要があります。

スペクトルは個々の周波数を表すのではなく、実際には特定の周波数を中心とした周波数帯域を表します。各帯域の中心周波数は、通常、時間領域信号のサンプリング レートの分数として表され、帯域の総数で割った周波数帯域のインデックスに等しくなります。通常、周波数帯域の総数は時間領域信号の長さと同じですが、ナイキスト周波数よりも低い周波数に対応するため、長さの半分未満のインデックスを持つ周波数帯域にのみアクセスが提供されます。つまり、長さ N の信号が与えられた場合、スペクトルには N/2 の周波数帯域が存在します。

たとえば、timeSize が 1024 で、sampleRate が 44100 Hz の FFT を作成すると、スペクトルには、ナイキスト周波数 (サンプル レートの半分) である 22010 Hz 未満の周波数の値が含まれます。帯域番号 5 の値を求めると、これは 5/1024 * 44100 = 0.0048828125 * 44100 = 215 Hz を中心とする周波数帯域に対応します。その周波数帯域の幅は 2/1024 に等しく、スペクトルの全帯域幅の割合として表されます。スペクトルの総帯域幅はナイキスト周波数 (この場合は 22100) に等しいため、帯域幅は約 50 Hz に等しくなります。これらの関係をすべて覚えておく必要はありませんが、知っておくとよいでしょう。

Minim マニュアルの FFT セクションから。

于 2012-04-15T08:21:41.070 に答える