Pitch detection with computeSpectrum() return FFT values

前端 未结 4 474
借酒劲吻你
借酒劲吻你 2020-12-30 15:19
  • I\'m developing using Actionscript 3.0 for Flash Player 10.3
  • I\'m using computeSpectrum() on a loaded .mp3
  • Running *Event.ENTER_FRAM
4条回答
  •  生来不讨喜
    2020-12-30 16:04

    Sounds like you already understand how to get an FFT spectrum, right?

    spectrum http://flic.kr/p/7notw6

    But if you're looking for the fundamental (green dot), you can't just use the highest peak. It's not necessarily the fundamental. In my example, the actual fundamental is 100 Hz, but the highest peak is 300 Hz.

    There are a lot of different ways you could find the true fundamental, and each works better in different contexts. One thread on comp.dsp mentions "FFT, cepstrum, auto/cross-correlation, AMDF/ASDF".

    For a simple example, each of the red dots is 100 Hz away from its neighbor, so if you used a peak-finding algorithm and then averaged together the distance between each harmonic and the next, you'd find the fundamental, but this would fail if any of the peaks were missed, or extra peaks included, or if the signal was symmetrical and only contained odd harmonics (1f, 3f, 5f). You'd need to find the mode and then throw away outliers and then average. This is probably an error-prone method.

    You could also do an autocorrelation of the original waveform. Conceptually, this means sliding a copy of the waveform past itself, and finding the delay at which it best lines up with itself (which will be one complete cycle). In normal implementation, we use the FFT, though, to speed it up. Autocorrelation is basically

    • IFFT(FFT(signal)⋅FFT(signal)*)

    where * means complex conjugate, or time reversal. In Python, for instance:

    correlation = fftconvolve(sig, sig[::-1], mode='full')
    

    and the source for fftconvolve() is relatively simple: https://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L133

提交回复
热议问题