[7175ed4] | 1 | #! /usr/bin/env python |
---|
[89fd1e5] | 2 | |
---|
| 3 | import sys |
---|
| 4 | from aubio import pvoc, source |
---|
| 5 | from numpy import array, arange, zeros, shape, log10, vstack |
---|
[b1c2acc] | 6 | from pylab import imshow, show, cm, axis, ylabel, xlabel, xticks, yticks |
---|
[89fd1e5] | 7 | |
---|
[9f8e8a9] | 8 | def get_spectrogram(filename, samplerate = 0): |
---|
[b1c2acc] | 9 | win_s = 512 # fft window size |
---|
| 10 | hop_s = win_s / 2 # hop size |
---|
| 11 | fft_s = win_s / 2 + 1 # spectrum bins |
---|
| 12 | |
---|
| 13 | a = source(filename, samplerate, hop_s) # source file |
---|
[9f8e8a9] | 14 | if samplerate == 0: samplerate = a.samplerate |
---|
[89fd1e5] | 15 | pv = pvoc(win_s, hop_s) # phase vocoder |
---|
[b1c2acc] | 16 | specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram |
---|
| 17 | |
---|
| 18 | # analysis |
---|
[89fd1e5] | 19 | while True: |
---|
| 20 | samples, read = a() # read file |
---|
| 21 | specgram = vstack((specgram,pv(samples).norm)) # store new norm vector |
---|
| 22 | if read < a.hop_size: break |
---|
| 23 | |
---|
[b1c2acc] | 24 | # plotting |
---|
[be65de4] | 25 | imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=cm.gray_r) |
---|
[89fd1e5] | 26 | axis([0, len(specgram), 0, len(specgram[0])]) |
---|
[b1c2acc] | 27 | # show axes in Hz and seconds |
---|
[89fd1e5] | 28 | time_step = hop_s / float(samplerate) |
---|
| 29 | total_time = len(specgram) * time_step |
---|
[e8dd49f] | 30 | print "total time: %0.2fs" % total_time, |
---|
| 31 | print ", samplerate: %.2fkHz" % (samplerate / 1000.) |
---|
| 32 | n_xticks = 10 |
---|
| 33 | n_yticks = 10 |
---|
[4db10ad] | 34 | |
---|
| 35 | def get_rounded_ticks( top_pos, step, n_ticks ): |
---|
| 36 | top_label = top_pos * step |
---|
| 37 | # get the first label |
---|
| 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 ] |
---|
| 45 | # convert to string |
---|
| 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 |
---|
| 49 | |
---|
| 50 | # apply to the axis |
---|
| 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 ) ) |
---|
[e8dd49f] | 53 | ylabel('Frequency (kHz)') |
---|
| 54 | xlabel('Time (s)') |
---|
[89fd1e5] | 55 | |
---|
[b1c2acc] | 56 | if __name__ == '__main__': |
---|
| 57 | if len(sys.argv) < 2: |
---|
| 58 | print "Usage: %s <filename>" % sys.argv[0] |
---|
| 59 | else: |
---|
| 60 | for soundfile in sys.argv[1:]: |
---|
| 61 | get_spectrogram(soundfile) |
---|
| 62 | # display graph |
---|
| 63 | show() |
---|