4 from aubio import pvoc, source
5 from numpy import array, arange, zeros, shape, log10, vstack
6 from pylab import imshow, show, cm, axis, ylabel, xlabel, xticks, yticks
8 def get_spectrogram(filename, samplerate = 0):
9 win_s = 512 # fft window size
10 hop_s = win_s / 2 # hop size
11 fft_s = win_s / 2 + 1 # spectrum bins
13 a = source(filename, samplerate, hop_s) # source file
14 if samplerate == 0: samplerate = a.samplerate
15 pv = pvoc(win_s, hop_s) # phase vocoder
16 specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram
20 samples, read = a() # read file
21 specgram = vstack((specgram,pv(samples).norm)) # store new norm vector
22 if read < a.hop_size: break
25 imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=cm.gray_r)
26 axis([0, len(specgram), 0, len(specgram[0])])
27 # show axes in Hz and seconds
28 time_step = hop_s / float(samplerate)
29 total_time = len(specgram) * time_step
30 print "total time: %0.2fs" % total_time,
31 print ", samplerate: %.2fkHz" % (samplerate / 1000.)
35 def get_rounded_ticks( top_pos, step, n_ticks ):
36 top_label = top_pos * step
38 ticks_first_label = top_pos * step / n_ticks
39 # round to the closest .1
40 ticks_first_label = round ( ticks_first_label * 10. ) / 10.
41 # compute all labels from the first rounded one
42 ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ]
43 # get the corresponding positions
44 ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ]
46 ticks_labels = [ "%.1f" % x for x in ticks_labels ]
47 # return position, label tuple to use with x/yticks
48 return ticks_positions, ticks_labels
51 xticks( *get_rounded_ticks ( len(specgram), time_step, n_xticks ) )
52 yticks( *get_rounded_ticks ( len(specgram[0]), (samplerate / 2. / 1000.) / len(specgram[0]), n_yticks ) )
53 ylabel('Frequency (kHz)')
56 if __name__ == '__main__':
58 print "Usage: %s <filename>" % sys.argv[0]
60 for soundfile in sys.argv[1:]:
61 get_spectrogram(soundfile)