python/demos/demo_pitch.py: add plotting
authorPaul Brossier <piem@piem.org>
Mon, 2 Dec 2013 17:14:33 +0000 (12:14 -0500)
committerPaul Brossier <piem@piem.org>
Mon, 2 Dec 2013 17:14:33 +0000 (12:14 -0500)
python/demos/demo_pitch.py

index 3a817ca..86f95c6 100755 (executable)
@@ -1,10 +1,7 @@
 #! /usr/bin/env python
 
 import sys
-from aubio import source, pitch
-
-win_s = 1024 # fft size
-hop_s = win_s # hop size
+from aubio import source, pitch, freqtomidi
 
 if len(sys.argv) < 2:
     print "Usage: %s <filename> [samplerate]" % sys.argv[0]
@@ -12,26 +9,93 @@ if len(sys.argv) < 2:
 
 filename = sys.argv[1]
 
-samplerate = 0
+downsample = 1
+samplerate = 44100 / downsample
 if len( sys.argv ) > 2: samplerate = int(sys.argv[2])
 
+win_s = 4096 / downsample # fft size
+hop_s = 512  / downsample # hop size
+
 s = source(filename, samplerate, hop_s)
 samplerate = s.samplerate
 
-pitch_o = pitch("default", win_s, hop_s, samplerate)
-pitch_o.set_unit("midi")
+tolerance = 0.8
 
-pitches = []
+pitch_o = pitch("yin", win_s, hop_s, samplerate)
+pitch_o.set_unit("freq")
+pitch_o.set_tolerance(tolerance)
 
+pitches = []
+confidences = []
 
 # total number of frames read
 total_frames = 0
 while True:
     samples, read = s()
     pitch = pitch_o(samples)[0]
-    print "%f %f" % (total_frames / float(samplerate), pitch)
-    #pitches += [pitches]
+    #pitch = int(round(pitch))
+    confidence = pitch_o.get_confidence()
+    #if confidence < 0.8: pitch = 0.
+    print "%f %f %f" % (total_frames / float(samplerate), pitch, confidence)
+    pitches += [pitch]
+    confidences += [confidence]
     total_frames += read
     if read < hop_s: break
 
+if 0: sys.exit(0)
+
 #print pitches
+from numpy import array, ma
+import matplotlib.pyplot as plt
+from demo_waveform_plot import get_waveform_plot, set_xlabels_sample2time
+
+skip = 1
+
+pitches = array(pitches[skip:])
+confidences = array(confidences[skip:])
+times = [t * hop_s for t in range(len(pitches))]
+
+fig = plt.figure()
+ax1 = fig.add_subplot(311)
+ax1 = get_waveform_plot(filename, samplerate = samplerate, block_size = hop_s, ax = ax1)
+ax1.set_xticklabels([])
+
+def array_from_text_file(filename, dtype = 'float'):
+    import os.path
+    from numpy import array
+    filename = os.path.join(os.path.dirname(__file__), filename)
+    return array([line.split() for line in open(filename).readlines()],
+        dtype = dtype)
+
+ax2 = fig.add_subplot(312, sharex = ax1)
+import sys, os.path
+ground_truth = os.path.splitext(filename)[0] + '.f0.Corrected'
+if os.path.isfile(ground_truth):
+    ground_truth = array_from_text_file(ground_truth)
+    true_freqs = ground_truth[:,2]
+    true_freqs = ma.masked_where(true_freqs < 2, true_freqs)
+    true_times = float(samplerate) * ground_truth[:,0]
+    ax2.plot(true_times, true_freqs, 'r')
+    ax2.axis( ymin = 0.9 * true_freqs.min(), ymax = 1.1 * true_freqs.max() )
+# plot raw pitches
+ax2.plot(times, pitches, '--g')
+# plot cleaned up pitches
+cleaned_pitches = pitches
+#cleaned_pitches = ma.masked_where(cleaned_pitches < 0, cleaned_pitches)
+#cleaned_pitches = ma.masked_where(cleaned_pitches > 120, cleaned_pitches)
+cleaned_pitches = ma.masked_where(confidences < tolerance, cleaned_pitches)
+ax2.plot(times, cleaned_pitches, '.-')
+#ax2.axis( ymin = 0.9 * cleaned_pitches.min(), ymax = 1.1 * cleaned_pitches.max() )
+#ax2.axis( ymin = 55, ymax = 70 )
+ax2.set_xticklabels([])
+
+# plot confidence
+ax3 = fig.add_subplot(313, sharex = ax1)
+# plot the confidence
+ax3.plot(times, confidences)
+# draw a line at tolerance
+ax3.plot(times, [tolerance]*len(confidences))
+ax3.axis( xmin = times[0], xmax = times[-1])
+plt.show()
+set_xlabels_sample2time(ax3, times[-1], samplerate)
+#plt.savefig(os.path.basename(filename) + '.png', dpi=200)