Showing the changes to python (1 of 1 file). Show all
Unified · Split
| @@ -1,63 +1,77 @@ | |||
| 1 | #! /usr/bin/env python | 1 | #! /usr/bin/env python |
| 2 | 2 | ||
| 3 | import sys | 3 | import sys, os.path |
| 4 | from aubio import pvoc, source | 4 | from aubio import pvoc, source |
| 5 | from numpy import array, arange, zeros, shape, log10, vstack | 5 | from numpy import array, arange, zeros, log10, vstack |
| 6 | from pylab import imshow, show, cm, axis, ylabel, xlabel, xticks, yticks | 6 | import matplotlib.pyplot as plt |
| 7 | 7 | ||
| 8 | def get_spectrogram(filename, samplerate = 0): | 8 | def get_spectrogram(filename, samplerate = 0): |
| 9 | win_s = 512 # fft window size | 9 | win_s = 512 # fft window size |
| 10 | hop_s = win_s / 2 # hop size | 10 | hop_s = win_s / 2 # hop size |
| 11 | fft_s = win_s / 2 + 1 # spectrum bins | 11 | fft_s = win_s / 2 + 1 # spectrum bins |
| 12 | 12 | ||
| 13 | a = source(filename, samplerate, hop_s) # source file | 13 | a = source(filename, samplerate, hop_s) # source file |
| 14 | if samplerate == 0: samplerate = a.samplerate | 14 | if samplerate == 0: samplerate = a.samplerate |
| 15 | pv = pvoc(win_s, hop_s) # phase vocoder | 15 | pv = pvoc(win_s, hop_s) # phase vocoder |
| 16 | specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram | 16 | specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram |
| 17 | 17 | ||
| 18 | # analysis | 18 | # analysis |
| 19 | while True: | 19 | while True: |
| 20 | samples, read = a() # read file | 20 | samples, read = a() # read file |
| 21 | specgram = vstack((specgram,pv(samples).norm)) # store new norm vector | 21 | specgram = vstack((specgram,pv(samples).norm)) # store new norm vector |
| 22 | if read < a.hop_size: break | 22 | if read < a.hop_size: break |
| 23 | 23 | ||
| 24 | # plotting | 24 | # plotting |
| 25 | imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=cm.gray_r) | 25 | fig = plt.imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=plt.cm.gray_r) |
| 26 | axis([0, len(specgram), 0, len(specgram[0])]) | 26 | ax = fig.axes |
| 27 | # show axes in Hz and seconds | 27 | ax.axis([0, len(specgram), 0, len(specgram[0])]) |
| 28 | time_step = hop_s / float(samplerate) | 28 | # show axes in Hz and seconds |
| 29 | total_time = len(specgram) * time_step | 29 | time_step = hop_s / float(samplerate) |
| 30 | print "total time: %0.2fs" % total_time, | 30 | total_time = len(specgram) * time_step |
| 31 | print ", samplerate: %.2fkHz" % (samplerate / 1000.) | 31 | print "total time: %0.2fs" % total_time, |
| 32 | n_xticks = 10 | 32 | print ", samplerate: %.2fkHz" % (samplerate / 1000.) |
| 33 | n_yticks = 10 | 33 | n_xticks = 10 |
| 34 | n_yticks = 10 | ||
| 34 | 35 | ||
| 35 | def get_rounded_ticks( top_pos, step, n_ticks ): | 36 | def get_rounded_ticks( top_pos, step, n_ticks ): |
| 36 | top_label = top_pos * step | 37 | top_label = top_pos * step |
| 37 | # get the first label | 38 | # get the first label |
| 38 | ticks_first_label = top_pos * step / n_ticks | 39 | ticks_first_label = top_pos * step / n_ticks |
| 39 | # round to the closest .1 | 40 | # round to the closest .1 |
| 40 | ticks_first_label = round ( ticks_first_label * 10. ) / 10. | 41 | ticks_first_label = round ( ticks_first_label * 10. ) / 10. |
| 41 | # compute all labels from the first rounded one | 42 | # compute all labels from the first rounded one |
| 42 | ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ] | 43 | ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ] |
| 43 | # get the corresponding positions | 44 | # get the corresponding positions |
| 44 | ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ] | 45 | ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ] |
| 45 | # convert to string | 46 | # convert to string |
| 46 | ticks_labels = [ "%.1f" % x for x in ticks_labels ] | 47 | ticks_labels = [ "%.1f" % x for x in ticks_labels ] |
| 47 | # return position, label tuple to use with x/yticks | 48 | # return position, label tuple to use with x/yticks |
| 48 | return ticks_positions, ticks_labels | 49 | return ticks_positions, ticks_labels |
| 49 | 50 | ||
| 50 | # apply to the axis | 51 | # apply to the axis |
| 51 | xticks( *get_rounded_ticks ( len(specgram), time_step, n_xticks ) ) | 52 | x_ticks, x_labels = 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 | y_ticks, y_labels = get_rounded_ticks ( len(specgram[0]), (samplerate / 1000. / 2.) / len(specgram[0]), n_yticks ) |
| 53 | ylabel('Frequency (kHz)') | 54 | ax.set_xticks( x_ticks ) |
| 54 | xlabel('Time (s)') | 55 | ax.set_yticks ( y_ticks ) |
| 56 | ax.set_xticklabels( x_labels ) | ||
| 57 | ax.set_yticklabels ( y_labels ) | ||
| 58 | ax.set_ylabel('Frequency (kHz)') | ||
| 59 | ax.set_xlabel('Time (s)') | ||
| 60 | ax.set_title(os.path.basename(soundfile)) | ||
| 61 | for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + | ||
| 62 | ax.get_xticklabels() + ax.get_yticklabels()): | ||
| 63 | item.set_fontsize('x-small') | ||
| 64 | return fig | ||
| 55 | 65 | ||
| 56 | if __name__ == '__main__': | 66 | if __name__ == '__main__': |
| 57 | if len(sys.argv) < 2: | 67 | if len(sys.argv) < 2: |
| 58 | print "Usage: %s <filename>" % sys.argv[0] | 68 | print "Usage: %s <filename>" % sys.argv[0] |
| 59 | else: | 69 | else: |
| 60 | for soundfile in sys.argv[1:]: | 70 | for soundfile in sys.argv[1:]: |
| 61 | get_spectrogram(soundfile) | 71 | fig = get_spectrogram(soundfile) |
| 62 | # display graph | 72 | # display graph |
| 63 | show() | 73 | fig.show() |
| 74 | #outimage = os.path.basename(soundfile) + '.png' | ||
| 75 | #print ("writing: " + outimage) | ||
| 76 | #plt.savefig(outimage) | ||
| 77 | plt.close() | ||