Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Librosa pitch tracking - STFT

I am using this algorithm to detect the pitch of this audio file. As you can hear, it is an E2 note played on a guitar with a bit of noise in the background.

I generated this spectrogram using STFT:spectrogram

And I am using the algorithm linked above like this:

y, sr = librosa.load(filename, sr=40000)
pitches, magnitudes = librosa.core.piptrack(y=y, sr=sr, fmin=75, fmax=1600)

np.set_printoptions(threshold=np.nan)
print pitches[np.nonzero(pitches)]

As a result, I am getting pretty much every possible frequency between my fmin and fmax. What do I have to do with the output of the piptrack method to discover the fundamental frequency of a time frame?

UPDATE

I am still not sure what those 2D array represents, though. Let's say I want to find out how strong is 82Hz in frame 5. I could do that using the STFT function which simply returns a 2D matrix (which was used to plot the spectrogram).

However, piptrack does something additional which could be useful and I don't really understand what. pitches[f, t] contains instantaneous frequency at bin f, time t. Does that mean that, if I want to find the maximum frequency at time frame t, I have to:

  1. Go to the magnitudes[][t] array, find the bin with the maximum magnitude.
  2. Assign the bin to a variable f.
  3. Find pitches[b][t] to find the frequency that belongs to that bin?
like image 1000
pavlos163 Avatar asked May 09 '17 19:05

pavlos163


People also ask

What does Librosa load do?

load. Load an audio file as a floating point time series. Audio will be automatically resampled to the given rate (default sr=22050 ).

What is N_fft in Librosa?

The default value, n_fft=2048 samples, corresponds to a physical duration of 93 milliseconds at a sample rate of 22050 Hz, i.e. the default sample rate in librosa. This value is well adapted for music signals.

What is the value of pitch and magnitude in LibROSA?

Both ``pitches`` and ``magnitudes`` take value 0 at binsof non-maximal magnitude. Notes-----This function caches at level 30. One of ``S`` or ``y`` must be provided. If ``S`` is not given, it is computed from ``y`` usingthe default parameters of `librosa.stft`.

How do you track pitch in FFT?

Typical pitch tracking techniques include searching the results of a FFT for magnitudes in certain bins that correspond to the expected frequencies of harmonics.

What is the maximum possible sample rate for LibROSA?

The recommended maximum is ``librosa.note_to_hz('C7')`` (~2093 Hz)though higher values may be feasible.sr : number > 0 [scalar]sampling rate of ``y`` in Hertz.frame_length : int > 0 [scalar]length of the frames in samples.

What is the minimum and maximum frequency range supported by LibROSA?

Multi-channel is supported.fmin : number > 0 [scalar]minimum frequency in Hertz. The recommended minimum is ``librosa.note_to_hz('C2')`` (~65 Hz)though lower values may be feasible.fmax : number > 0 [scalar]maximum frequency in Hertz.


2 Answers

Pitch detection is a tricky topic and is often counter-intuitive. I'm not wild about the way the source code is documented for this particular function -- it almost seems like the developer is confusing a 'harmonic' with a 'pitch'.

When a single note (a 'pitch') is made on a guitar or piano, what we hear is not just one frequency of sound vibration, but a composite of multiple sound vibrations occurring at different mathematically related frequencies, called harmonics. Typical pitch tracking techniques include searching the results of a FFT for magnitudes in certain bins that correspond to the expected frequencies of harmonics. For instance, if we press the Middle C key on the piano, the individual frequencies of the composite's harmonics will start at 261.6 Hz as the fundamental frequency, 523 Hz would be the 2nd Harmonic, 785 Hz would be the 3rd Harmonic, 1046 Hz would be the 4th Harmonic, etc. The later harmonics are integer multiples of the fundamental frequency, 261.6 Hz ( ex: 2 x 261.6 = 523, 3 x 261.6 = 785, 4 x 261.6 = 1046 ). However, the frequencies where harmonics are located are logarithmically spaced, but the FFT uses a linear spacing. Often the vertical spacing for FFTs are not resolved enough at the lower frequencies.

For that reason when I wrote a pitch detecting application (PitchScope Player), I chose to create a logarithmically spaced DFT, rather than a FFT, so I could focus on the precise frequencies of interest for music ( see the attached diagram of my custom DFT from 3 seconds of a guitar solo ). If you are serious about pursuing pitch detection, you should consider doing more reading into the topic, looking at other sample code (mine is linked below), and consider writing your own functions to measure frequency.

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

https://github.com/CreativeDetectors/PitchScope_Player

enter image description here

like image 162
James Paul Millard Avatar answered Oct 06 '22 01:10

James Paul Millard


Turns out the way to pick the pitch at a certain frame t is simple:

def detect_pitch(y, sr, t):
  index = magnitudes[:, t].argmax()
  pitch = pitches[index, t]

  return pitch

First getting the bin of the strongest frequency by looking at the magnitudes array, and then finding the pitch at pitches[index, t].

like image 26
pavlos163 Avatar answered Oct 05 '22 23:10

pavlos163