0
$\begingroup$

I am trying to write code to detect musical notes within a signal. I have been reading up on different methods for extracting frequency information out of a signal to determine which notes were played at a given time and I came across the "constant Q transform" which seems to be very well suited for this application. The main thing that appealed to me with the constant Q transform is that it is supposed to be able to achieve higher resolution for low frequencies than a normal FFT.

I just finished implementing a basic constant Q transform in C++ after reading through this paper and I ran into one major problem.

My code can be found here: https://godbolt.org/z/43b8vohs3

The problem primarily arises from this part of the paper:

enter image description here

If I am understanding what it says here correctly, this means in order to detect a frequency of 27.5Hz (A0, the lowest note on an 88 key piano) in a signal sampled at 44100Hz, The constant Q transform would require the input to have a minimum buffer size of N[k] = (S/f)Q = 44100/27.5*34 = 54523. That is over one full second of audio which is WAY too large to be practical considering notes can be played much faster than that.

I feel like I must be missing something critical here because requiring a buffer size that large would make this algorithm effectively useless for detecting notes in most pieces of music. How can the constant Q transform be used to detect low frequencies like this without increasing the buffer size to a completely unrealistic size?

Ideally I would like to keep the buffer size small enough to work on 100ms of audio or less (around 4096) or even smaller as long as it is possible to achieve a high enough resolution for the output to be useful.

$\endgroup$
2
  • $\begingroup$ The paper Sliding With A Constant Q by Bradford et. at. addresses the issue of your concern. $\endgroup$
    – AHT
    Commented Apr 28 at 22:25
  • $\begingroup$ Thank you! I will read it over :) $\endgroup$
    – tjwrona
    Commented Apr 28 at 22:52

1 Answer 1

1
$\begingroup$

It sounds like you are asking why the human ear can distinguish piano low notes quickly, yet this algorithm needs more than one second to do the same. The answer becomes apparent if you run a piano low note test clip through a band pass filter and the listen to it. For example, this filtering simulates listening to a piano over old telephone equipment:

sox.exe piano.wav out.wav sinc -n 32767 300-3000

With this filtering the sound lacks quality, but the notes are easily understood by a human. The filtered 27.5 Hz A0 is missing the first 10 harmonics. This shows that human hearing easily tolerates missing low harmonics and recognizes the tone based on the remaining harmonics.

For software to recognize low notes from musical instruments quickly, it must do it the same way the human ear does: don't rely on low harmonics. Instead, recognize the familiar pattern in the remaining harmonics.

Note: The term partial may be more suitable than harmonic when talking about string instruments such as piano due to the inharmonicity present in string instruments.

$\endgroup$
1
  • $\begingroup$ Thank you! That is very helpful. I am specifically going to be trying to detect notes for electric guitar and bass so I will have to do some analysis to find the pattern in the harmonics $\endgroup$
    – tjwrona
    Commented Apr 29 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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