9

Hi I'm a noob in audio related coding and I'm working in a pitch tracking DLL that I will use to try to create a sort of open-source version of the video-game Rocksmith as a learning experience.

So far I have managed to get the FFT to work so I can detect pitch frequency (Hz) then by using an algorithm and the table below I can manage to determine the octave (2th to 6th) and the note (C to B) for played note.

The next step is to detect the string so I can determine the fret.

enter image description here

I've been thinking about it and in theory I can work with this, I will know when the user is playing the right note but the game could be "Hack" because by just using the Hz the game is not able to detect if a note is played in the right string. For example 5th string + 1th fret = C4 261.63Hz is equals to 6th string + 5th fret = C4 261.63Hz.

The chances of having an user playing a note in the wrong string and getting it right is low, but I think it would be really good to know the string so I can provide to the users some error feedback when they play the wrong string (Like you should go a string up or down).

Do you know what can I do to detect the string? Thanks in advance :)

[edit]

The guitar and strings that we are using affect the timbre so analyzing the timbre seems to not be a easy way of detecting strings:

"Variations in timbre on your guitar are produced by an enormous number of factors from pickup design and position, the natural resonances and damping in your guitar due to the wood used (that's a different sort of timber!) and its construction and shape, the gauge and age of your strings, your playing technique, where you fret and pluck the string, and so on."

Remo H. Jansen
  • 23,172
  • 11
  • 70
  • 93
  • 4
    I'm not sure this is possible since, if properly tuned, both strings will make the same note. I don't know if the difference in timbre can be detected by computers at this point. – NWard Sep 09 '13 at 08:53
  • 2
    Agree with NWard - the same note will have a different (slightly mellower) timbre when played on a lower string, but I doubt you'd have much luck detecting this - it possibly could be slightly easier on a single, known instrument. I assume you're not interested in making a custom pickup? :) – Нет войне Sep 09 '13 at 09:20
  • I will use this only for electric guitar with standard tuning. From a quick research looks like timbre detection is a too complex task... I will probably have to create an algorithm that do it's best to identify user errors comparing the played note with the notes nearby the expected note. – Remo H. Jansen Sep 09 '13 at 12:43

3 Answers3

3

This might be a little bit late because the post is one years old. But here's a solution, which I found out after long research for pitch detecting a guitar.

THIS IS WHY FFT DOESN'T WORK :

You cannot use FFT since the result gives you a linear array, and the sound is calculated logarithmically (exponential distance between notes). Plus, FFT gives you an array of bins in which your frequency COULD BE, it doesnt give you the precise result.

THIS IS WHAT I SUGGEST :

Use dywapitchtrack. it's a library that uses a wavelet algorythm, which works directly on your wave instead of calculating large bins like FFT.

description: The dywapitchtrack is based on a custom-tailored algorithm which is of very high quality: both very accurate (precision < 0.05 semitones), very low latency (< 23 ms) and very low error rate. It has been thoroughly tested on human voice. It can best be described as a dynamic wavelet algorithm (dywa):

DOWNLOAD : https://github.com/inniyah/sndpeek/tree/master/src/dywapitchtrack

USE(C++): put the .c and .h where you need it and import it in your project

include the header file

//Create a dywapitchtracker Object
dywapitchtracker pitchtracker;

//Initialise the object with this function
dywapitch_inittracking(&pitchtracker);

When your buffer is full (buffer needs to be at 44100 resolution and power of 2 of length, mine is 2048):

//use this function with your buffer
double thePitch = dywapitch_computepitch(&pitchtracker, yourBuffer, 0, 2048);

And voilà, thePitch contains precisely what you need. (feel free to ask question if something is unclear)

Andrew_STOP_RU_WAR_IN_UA
  • 9,318
  • 5
  • 65
  • 101
s.1.618
  • 41
  • 3
  • I have a question. The `dywapitchtracker` library is a jewel, but it seems to not free memory once it is uninitialised. Any idea why? – cassi.lup Dec 03 '14 at 13:46
2

An simple FFT peak estimator is not a good guitar pitch detector/estimator, due to many potentially strong overtones. There exist more robust pitch estimation algorithms (search stackoverflow and DSP.stackexchange). But if you require the players to pre-characterize each string on their individual instruments, both open and fretted, before starting the game, an FFT fingerprint of those characterizations might be able to differentiate the same note played on different strings on some guitars. The thicker strings will give off slightly different ratios of energy in some of the higher overtones, as well as different amounts of slight inharmonicity.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • 1
    There are FFT-based f0 estimation algorithms that work well (e.g. Maher and Beauchamp's "two-way mismatch procedure" JASA 04 1994). You might want to correct your answer to say "simple peak picking on an FFT is not a good pitch detector". – Ross Bencina Sep 10 '13 at 14:03
  • 1
    Done. An FFT can be used as a trivial first step of a more robust composite estimation method (cepstral, etc.) – hotpaw2 Sep 10 '13 at 18:58
0

The other answers seem to suggest a simple pitch detection method. However, it is something you will have to research.

Specifically, compare the overtones of 5th string 1st fret to sixth string 5th fret. that is, only look at 261.63*2, 261.63*3, *4, etc. Also, try looking at 261.63*0.5. Compare the amplitudes of the two signals at these freqs. There might be a pattern that could be detected.

JackCColeman
  • 3,777
  • 1
  • 15
  • 21