2012-04-14 88 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