# How to determine guitar tones played as early as possible?

I want to detect chords on a guitar as early as possible, but my approach with a sliding window and a filter bank seems to introduce too much lag.

Would required observation time decrease by using a model where there are only a finite number of tones possible and only a finite number of simultaneous tones? (I.e. the different strings of the guitar).

I would suppose that for the system to not be underdetermined the number of samples would have to be at least as many as the number of guitar strings, and the time window would have to be at least on the same time scale as the tone with the shortest period. Or maybe the number of samples would have to be at least the same as the dimension of the model space (something like ~6 * 20)? And probably the amplitude resolution of the microphone together with the slowest frequency would set a constraint too?

I think that's the way to go. If you do a Fourier transform, you have to do a trade-off that's a variation on the Schroedinger uncertainty principle: The shorter you take your time window if you look at a non-periodic signal, the less well defined your frequency spectrum is.

But you can also think of it the following way: You probably want to know frequencies down to, say, 100 Hz. That means that just one period of that signal is going to take 10 ms, and you probably want to observe several periods to really say for sure that that frequency is there and you're not just moving through a transition in the pressure-as-a-function-of-time period. So you have to expect that if that's where your frequency region of interest starts, you won't be able to go substantially shorter than time windows of around 100 ms. I don't know whether that's a time lag of the kind you're concerned about, but there isn't going to be a way to make a determination on tones and chords much faster than that.

• I will try with 1ms and increase from there, perhaps I could use midi files as validation set while developing to find sweet spot. I think I only need a fraction of a period, I just need to make sure the quantisation of the sine would be guaranteed to change in the time window for the volume of interest. – Emil Nov 21 at 7:01
• No, you cannot disambiguate between different frequencies if you only look at a time interval that is less than one period of the lowest frequency. – Wolfgang Bangerth Nov 22 at 2:22
• You miss the point. Plot the function $\sin(x)$ on the interval $[0,0.1]$. Then plot the function $\frac 12 \sin(x) + \frac 14 \sin(2x)$. They clearly have different frequency content, but on an interval substantially smaller than one period, they are indistinguiable. – Wolfgang Bangerth Nov 22 at 17:42
• @Emil In the time window $[0,0.1]$, the amplitude is exactly the same. The point I'm trying to make is this: If you look at a short enough time window, a lot of functions will look the same. You can't expect to figure out whether something is function 1 or function 2, because they look the same in the window at hand. Just to make the point, if you don't like the example I gave, compare $\sin(x)$ and $\frac 13 \sin(x) + \frac \sin(2x)$. Now you have two sine functions of equal amplitude that on that time interval add up to what's indistinguishable from $\sin(x)$. – Wolfgang Bangerth Nov 23 at 4:24
• @Emil The formula didn't come out right. It was supposed to be $\frac 13 \sin(x) + \frac 13 \sin(2x)$. Plot it! – Wolfgang Bangerth Nov 23 at 16:57

I'll add a few other thoughts. First of all, I assume you do not exactly need the fastest way to determine guitar tones ("as early as possible"), but just one that works well with a reasonably short lag.

So what you need is some numerical method that inputs samples of your guitar tone and outputs the dominant frequency (while neglecting other higher harmonics). There are several methods to do so among them the Fourier transform, Wavelet transforms, and harmonic inversion. Of these, the Fourier transform is the basic method with which I'd start to play around.

So you plug your string, record it, and apply a Fourier transformation. First, as mentioned in the answer by @WolfgangBangerth, you need some kind of temporal window (ranging back a fixed duration from "now") for your FT. This is because as you change the tune, you want to get a new result, and not a superposition of the previous tune and the new one. More general, you probably want to apply a specific window function (like "Hamming" and so on) because this makes the signal periodically and thus removes artifacts in the frequency range (at the cost of broadening the peaks).

When you got the results from the FT, you have to spot for the position of the dominant tune, i.e. the largest peak, which must be done automatically. For this, one can possibly apply further methods such as interpolation, averaging over frequencies, etc.

The previous approach cooresponds to a single tone. When you want to determine chords, you can basically do the same process several times. However, I would assume that the problem then becomes quite harder, as you have to separate harmonics from "real" plugged tones and also neglect irrelevant artifacts.

• This is what I do today, I get too much lag. I want something that works 99% of the time and is as early as possible. So your assumption of what I want is wrong. With that said I probably need better audio drivers, the default ones that comes with the OS does not seem to be realtime. – Emil Nov 22 at 7:54
• Ok, so then you probably should get specific on your applied model, and the problems with it (because, for example, there's no mention of Fourier transform) and probably also your morivation and your goals. I don't think you need better audio driverd, because these also won't beat the uncertainty pricnciple. You'll need at least a full wavelength of the targeted frequency. Right thereafter, you can start searching for your peaks in frequency space, track them as they get sharper and thus develop confidence of the result. This works faster for higher frequencies. – davidhigh Nov 22 at 10:32
• The latency is noticably different between audio drivers, I have only gotten low latency with one program in ubuntu studio and one program in windows. I experimented with a wavelet filter bank and fourier transform. My wavelet implementation was super buggy so it should be forgotten but the FFT needed a too big window to give fast enough feedback...Also, FFT gives "too many" frequencies. I do not have use for most of them. – Emil Nov 22 at 14:46
• @Emil: ok, but these are two different areas. We're talking here about the stage where you have your audio signal in temporal space available. For the other topic how to get that, you're probably not in the correct forum here. Ok, regarding the FFT: what window functions did you use? Because this can be ised to damp irrelevant frequencies. And what is too long here? After which time did you have the single plugged A-string with 110 Hz determined? – davidhigh Nov 22 at 15:36
• I would probably want to be able to detect a 1/128th note before it is finished, or something like that. The frequency range would probably be something like 10 Hz-1400 Hz. I am not even sure an entire period is finished at that rate, it might just be the "attack" of the note over and over. – Emil Nov 22 at 20:31