Suppose I have a recording of a live concert of a known band. We can assume that the concert was played using instruments that were in tune, in standard tuning. This was in the 1990s, so the concert was recorded to an analog cassette tape (or a DAT master) then distributed to collectors via tape trading. This means that by the time a recording has reached me, it has undergone a few generations of copying from one tape deck to another (dubbing on a double-deck player was typically frowned upon) and there is no guarantee that both tape decks ran at precisely the same speed when copying - quite the contrary was often the case - and the error could accumulate with each generation. This means that the tape in my hands is almost certainly off pitch by a certain degree. Now that I've converted the tape to a digital file I want to repair the error.
My typical method for doing this is to find a song I know how to play, pick up a tuned instrument and play along, tweaking the playback speed until the song matches my instrument. When I find the correct speed change ratio I apply it to the audio file and save the result.
This is great for fixing one or two recordings, not so much when I have a hundred of them.
I think it's theoretically possible for an algorithm to analyze a recording and tell whether it's off pitch, assuming standard tuning. Suppose my recording is sharp by 0.2 semitones the algorithm should be able to suggest a correction of -1.2/-0.2/+0.8/+1.8 (obviously it can't guess which direction is correct, nor how far we are from the original pitch). Googling for pitch correction software invariably leads me to auto-correct plugins for vocal tracks, which is really not what I'm looking for.
Using my fairly strong C++ but very limited understanding of the mathematics of digital signal processing, I tried to write a program that parses the output of sox song.wav -n stat -freq
(which performs a DFT on the audio and outputs the results), finding the dominant frequencies and checking whether they match the frequencies for standard notes or deviate from them by a fixed ratio, but I was unable to extract meaningful results - perhaps because the output from sox
is rather coarse. So here I am asking whether a tool exists that already implements such an algorithm, or any tips on doing this myself (would I need to perform the DFT using some software library or is the data from sox
sufficient? etc), or whether this is a far more complex problem than I imagine, not solvable using simple heuristics.