2012-04-14 86 views
2

我尝试使用Processing从麦克风获取频率。我已经混合了文档中的两个示例,但“最高”并非真正以Hz为单位(a是440 Hz)。 你知道如何拥有比这更好的东西吗?在Minim处理中获取频率

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

你需要做一些转换,这取决于你想要得到什么:

频谱并不代表个体的频率,但实际上代表集中于特定频率的频段。每个频带的中心频率通常表示为时域信号采样率的一小部分,等于频带指数除以频带总数。频带的总数通常等于时域信号的长度,但是仅向指数小于一半长度的频带提供接入,因为它们对应于低于奈奎斯特频率的频率。换句话说,给定一个长度为N的信号,频谱中会有N/2个频段。

作为一个例子,如果构造的FFT 1024一个timeSize和和 44100赫兹的采样率,则频谱将包含 频率低于22010赫兹,这是奈奎斯特频率值( 样品半率)。如果您询问5号频带的值,则这个 对应于以5/1024 * 44100 = 0.0048828125 * 44100 = 215Hz为中心的频带。该频带的宽度等于2/1024,表示为频谱总带宽的一部分。频谱的总带宽等于奈奎斯特频率,在这种情况下为22100,因此带宽等于约为50Hz的 。你不需要记住所有这些关系,尽管知道它们是很好的。 getFreq 允许您以Hz为频率查询频谱,并且方法 getBandWidth将返回频谱中每个频段的带宽(以Hz为单位)。

from Minim Manual, FFT section

+0

这有点抽象......当我在乐器上弹奏单个音符时,我想以Hz为单位获得价值......我不知道为什么手册中没有简单的例子。 如果您知道我可以在哪里改进我的代码,那么共享它将会很愉快。 – 2012-04-15 08:37:31

+2

这解释了您感兴趣的位 - 赫兹转换:**如果您要求5号频段的值,则这将对应于以5/1024 * 44100 = 0.0048828125 * 44100 = 215 Hz为中心的频段。 *在你的代码中,你使用getBand(),其中,文档指出:**返回所请求频段的振幅**你可能想尝试getFreq(float freq)(例如fft.getFreq(440)) **获得频谱**中所需频率(Hz)的幅度。 – 2012-04-15 08:51:15

+0

我想我明白为什么我有点麻烦,使用int来获得最高的返回不精确值(我在再次尝试并在未来发布我的代码时)。感谢您的回答 ! – 2012-04-15 10:24:51