0
$\begingroup$

I'm trying to make a program that catch and audio signal of a bass and show the notes that have been played. My program:

  • Gets the sound and put it in a double data type array. (48 000Hz, 16bits) (1 frame in array per sample)
  • Splits the array into many arrays, with 4~5 arrays in a second approx.
  • Applies FFT algorithm to every array and left the same number of array's that have been created in the last step with frequency domain instead of time domain.
  • Obtains the highest number of each array. That's the note that I have played with the bass.

This works and get the frequency when I don't split the array, for most of the times, but when I split it doesn't work even for the half of the results, maybe I have to use another way for get several notes instead of splitting. But the results are good too, so I think the problem is that I have to apply some filters.

The first one has to be a filter for the range of the bass (41 - 784), assuming that I'm not playing anything that time if it's out of that range.

Many times, if I play 41Hz (E1), the program interpret that I'm playing 82Hz (E2), or even a higher harmonic, and I don't know what to do with that. I could turn into 0Hz every note that has been played after the same note or one of its harmonics, but then how could I play the same note several times.

  • Some advice for deal with this problems?
  • Should I split the original array into more/less array's for get more accuracy?
  • Which filters should I apply on my frequency or time domain array for get all the notes that have been played, with the right frequency and avoiding their harmonics?
$\endgroup$
2
$\begingroup$

A good stringed instrument music pitch detection/estimation algorithm will do the opposite, e.g. it will not ignore overtones. Instead it will pay attention to the harmonics, specifically the harmonic train and its spacing, as this is a stronger indication of human perceived pitch than spectral content at the fundamental frequency (which could be nearly or completely missing, depending on the microphone and channel characteristics).

If you want to work in the frequency domain, than look into cepstrum/cepstral analysis and/or the Harmonic Product Spectrum algorithm, which can estimate pitch from spectral periodicity. Or you can instead work in the time domain using weighted/interpolated autocorrelation, ASDF, AMDF, etc. type algorithms for pitch estimation.

If you slice your time windows too small, then there will be very few full cycles at he fundamental pitch frequency, which causes FFT frequency estimation to have very poor resolution. A parametric estimator within and across windows may work better than a bare FFT.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Several questions: If you are calculating frequency from harmonics, how could i stipulate what octave has been played? I've been looking for cepstral analysis. PD: I don't use a microphone, I'm using a bass-usb cable connected to my computer, and the sound is nice. It has some noise, but i think that it's pretty clean. $\endgroup$ – Meliodas Mar 24 at 9:18
  • $\begingroup$ I've been looking for cepstral analysis. ¿Would i get a time domain function, and with an amplitude that is my fundamental frequency? Because that's what i have understood. (FFT -> log -> (FFT)^(-1) ). What do you refer about "A parametric estimator within and across windows"? $\endgroup$ – Meliodas Mar 24 at 9:32
  • $\begingroup$ really agree with hot about this. $\endgroup$ – robert bristow-johnson Apr 22 at 21:31
1
$\begingroup$

What kind of windowing/overlap scheme do you use?

Did you look into cepstral processing, seeing as your bass should produce a harmonic series?

Perhaps dynamic programming to pick a sensible «time-pitch-contour»?

Fundamental pitch tracking is a long standing challenge. There should be many hints in the litterature.

| improve this answer | |
$\endgroup$
  • $\begingroup$ I´m not using any windowing on the sound, i just split the array into N arrays, where N is Math.ceil((FullArray.length)/7.500) because 1 second is a value between 50.000 frames and 30.000 frames. Anyway i don't know if I'm following you with the windowing/overlap. $\endgroup$ – Meliodas Mar 24 at 9:02
  • $\begingroup$ If you split a sampled signal into N equally sized windows, that can be described as rectangular, non-overlapped (critically sampled) windowing. See e.g. this reference: dsp.stackexchange.com/questions/19311/… $\endgroup$ – Knut Inge Mar 24 at 9:06
  • $\begingroup$ Then should i apply a window function and overlap the results? Windows are like you say then, and non-overlapped. $\endgroup$ – Meliodas Mar 24 at 9:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.