source: python/demos/demo_spectrogram.py @ 4120fbc

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since 4120fbc was 4120fbc, checked in by Paul Brossier <piem@piem.org>, 3 years ago

python/demos: python3 and double precision compatibility

  • Property mode set to 100755
File size: 3.1 KB
Line 
1#! /usr/bin/env python
2
3import sys, os.path
4from aubio import pvoc, source, float_type
5from numpy import zeros, log10, vstack
6import matplotlib.pyplot as plt
7
8def 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
12
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=float_type)     # numpy array to store spectrogram
17
18    # analysis
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
24    # plotting
25    fig = plt.imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=plt.cm.gray_r)
26    ax = fig.axes
27    ax.axis([0, len(specgram), 0, len(specgram[0])])
28    # show axes in Hz and seconds
29    time_step = hop_s / float(samplerate)
30    total_time = len(specgram) * time_step
31    outstr = "total time: %0.2fs" % total_time
32    print(outstr + ", samplerate: %.2fkHz" % (samplerate / 1000.))
33    n_xticks = 10
34    n_yticks = 10
35
36    def get_rounded_ticks( top_pos, step, n_ticks ):
37        top_label = top_pos * step
38        # get the first label
39        ticks_first_label = top_pos * step / n_ticks
40        # round to the closest .1
41        ticks_first_label = round ( ticks_first_label * 10. ) / 10.
42        # compute all labels from the first rounded one
43        ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ]
44        # get the corresponding positions
45        ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ]
46        # convert to string
47        ticks_labels = [  "%.1f" % x for x in ticks_labels ]
48        # return position, label tuple to use with x/yticks
49        return ticks_positions, ticks_labels
50 
51    # apply to the axis
52    x_ticks, x_labels = get_rounded_ticks ( len(specgram), time_step, n_xticks )
53    y_ticks, y_labels = get_rounded_ticks ( len(specgram[0]), (samplerate / 1000. / 2.) / len(specgram[0]), n_yticks )
54    ax.set_xticks( x_ticks )
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(filename))
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
65
66if __name__ == '__main__':
67    if len(sys.argv) < 2:
68        print("Usage: %s <filename>" % sys.argv[0])
69    else:
70        for soundfile in sys.argv[1:]:
71            fig = get_spectrogram(soundfile)
72            # display graph
73            plt.show()
74            #outimage = os.path.basename(soundfile) + '.png'
75            #print ("writing: " + outimage)
76            #plt.savefig(outimage)
77            plt.close()
Note: See TracBrowser for help on using the repository browser.