Auriotouch, получить музыкальную ноту с частотой FFT - PullRequest
4 голосов
/ 16 марта 2011

Я разрабатываю своего рода гитарный тюнер.

У меня есть функция, которая дает мне БПФ и значения FFt для каждой частоты.

Как мне получитьмузыкальная нота оттуда?Нужно ли выбирать самый высокий пик?

 for(y=0; y<maxY; y++){


    CGFloat yFract = (CGFloat)y / (CGFloat)(maxY - 1);          

    CGFloat fftIdx = yFract * ((CGFloat)fftLength);
    double fftIdx_i,fftIdx_f;
    fftIdx_f = modf(fftIdx, &fftIdx_i);

    SInt8 fft_l, fft_r;
    CGFloat fft_l_fl, fft_r_fl;
    CGFloat interpVal;

    fft_l = (fftData[(int)fftIdx_i] & 0xFF000000) >> 24;
    fft_r = (fftData[(int)fftIdx_i + 1] & 0xFF000000) >> 24;


    fft_l_fl = (CGFloat)(fft_l + 80) / 64.;
    fft_r_fl = (CGFloat)(fft_r + 80) / 64.;
    interpVal = fft_l_fl * (1. - fftIdx_f) + fft_r_fl * fftIdx_f;
    interpVal = CLAMP(0., interpVal, 1.);


    drawBuffers[0][y] = (interpVal * 120);
    //NSLog(@"The magnitude for %f Hz is %f.", (yFract * hwSampleRate * .5), (interpVal * 120));

}

Большое спасибо, если вы можете помочь.

Julien.

1 Ответ

3 голосов
/ 16 марта 2011

Это нетривиальная проблема по нескольким причинам:

  • Пик может не соответствовать основной гармонике (может даже отсутствовать).
  • Основная гармоникавероятно, не приземлится точно в центре бункера FFT, поэтому его энергия будет распределена по нескольким бинам.Вам необходимо выполнить интерполяцию для оценки фактической частоты.
  • Если вы не выполните какое-либо управление окнами, вы получите эффекты "спектральной утечки", которые размазывают ваш спектр повсюду, затрудняя распознаваниедетали.

Я ценю, что это на самом деле не отвечает на ваш вопрос, но следует подчеркнуть тот факт, что на самом деле это довольно сложно сделать хорошо.

...