1 | #! /usr/bin/env python |
---|
2 | |
---|
3 | import numpy as np |
---|
4 | from aubio import pitch |
---|
5 | import pylab as plt |
---|
6 | |
---|
7 | buf_size = 2048 * 1 |
---|
8 | hop_size = buf_size // 4 |
---|
9 | |
---|
10 | samplerate = 44100 |
---|
11 | minfreq = 40 |
---|
12 | maxfreq = 6000 |
---|
13 | |
---|
14 | def sinewave(freq, duration, samplerate = samplerate): |
---|
15 | """ generate a sinewave """ |
---|
16 | length = hop_size |
---|
17 | while length < duration * samplerate: |
---|
18 | length += hop_size |
---|
19 | return np.sin( 2. * np.pi * np.arange(length) * freq / samplerate ).astype("float32") |
---|
20 | |
---|
21 | def get_stats_for_pitch_method(method, freqs, samplerate = samplerate): |
---|
22 | """ for a given pitch method and a list of frequency, generate a sinewave |
---|
23 | and get mean deviation """ |
---|
24 | means = np.zeros(len(freqs)) |
---|
25 | medians = np.zeros(len(freqs)) |
---|
26 | for freq, fn in zip(freqs, range(len(freqs))): |
---|
27 | s = sinewave(freq, .50).reshape(-1, hop_size) |
---|
28 | #s = (sinewave(freq, .50) + .0*sinewave(freq/2., .50)).reshape(-1, hop_size) |
---|
29 | p = pitch(method, buf_size, hop_size, samplerate = samplerate) |
---|
30 | candidates = np.zeros(len(s)) |
---|
31 | #samples = np.zeros(buf_size) |
---|
32 | for frame, i in zip(s, range(len(s))): |
---|
33 | candidates[i] = p(frame)[0] |
---|
34 | # skip first few candidates |
---|
35 | candidates = candidates[4:] |
---|
36 | means[fn] = np.mean(candidates[candidates != 0] - freq) |
---|
37 | medians[fn] = np.median(candidates[candidates != 0] - freq) |
---|
38 | print (freq, means[fn], medians[fn]) |
---|
39 | return means, medians |
---|
40 | |
---|
41 | if __name__ == '__main__': |
---|
42 | freqs = np.arange(minfreq, maxfreq, 1.) |
---|
43 | modes = ["yin", "yinfft"] |
---|
44 | for mode in modes: |
---|
45 | means, medians = get_stats_for_pitch_method(mode, freqs) |
---|
46 | plt.figure() |
---|
47 | plt.plot(freqs, means, 'g-') |
---|
48 | plt.plot(freqs, medians, 'r--') |
---|
49 | #plt.savefig(mode + '_deviations_test.png', dpi=300) |
---|
50 | plt.show() |
---|