1 | #! /usr/bin/env python |
---|
2 | |
---|
3 | import sys, os.path |
---|
4 | import numpy as np |
---|
5 | import aubio |
---|
6 | |
---|
7 | if __name__ == '__main__': |
---|
8 | |
---|
9 | if len(sys.argv) < 2: |
---|
10 | print ("usage: %s <inputfile>" % sys.argv[0]) |
---|
11 | sys.exit(1) |
---|
12 | input_filename = sys.argv[1] |
---|
13 | |
---|
14 | win_size = 8192 #2048 #1024 |
---|
15 | hop_size = win_size // 2 |
---|
16 | samplerate = 44100 |
---|
17 | bins_per_octave = 72 # 24 # 6, 12, 24, 36, 48, 72... |
---|
18 | |
---|
19 | a_source = aubio.source(input_filename, samplerate, hop_size) |
---|
20 | a_pvoc = aubio.pvoc(win_size, hop_size) |
---|
21 | a_constantq = aubio.constantq(win_size, samplerate, bins_per_octave) |
---|
22 | |
---|
23 | numbins = a_constantq.get_numbins() |
---|
24 | |
---|
25 | print ('created constant-q with %d win_size, %d numbins, %d Hz' % |
---|
26 | (win_size, numbins, samplerate)) |
---|
27 | |
---|
28 | read = hop_size |
---|
29 | |
---|
30 | cqts = np.ndarray((0,numbins)).astype(aubio.float_type) |
---|
31 | |
---|
32 | while read: |
---|
33 | samples, read = a_source() |
---|
34 | fftgrain = a_pvoc(samples) |
---|
35 | cqt = a_constantq(fftgrain) |
---|
36 | cqts = np.vstack([cqts, cqt]) |
---|
37 | |
---|
38 | print ('finished computing constant-q over %d frames of %d bins' % cqts.shape) |
---|
39 | try: |
---|
40 | import matplotlib.pyplot as plt |
---|
41 | import matplotlib.ticker as ticker |
---|
42 | plt.rc('font', size=8) |
---|
43 | plt.rc('axes', titlesize=8) |
---|
44 | |
---|
45 | fig, ax = plt.subplots(1) |
---|
46 | ax.imshow(cqts.T, aspect='auto', origin='bottom', cmap=plt.cm.gray_r) |
---|
47 | ax.axis([0, len(cqts), 0, len(cqts[0])]) |
---|
48 | |
---|
49 | time_step = hop_size / float(samplerate) |
---|
50 | freq_start = 19.0 # TODO get actual low_freq |
---|
51 | freq_step = 12./bins_per_octave |
---|
52 | freq_end = freq_start + len(cqts[0]) * freq_step |
---|
53 | #print ('plotting', end=" ") |
---|
54 | #print ('x from 0 to %.2f (sec),' % (time_step * len(cqts)), end=" ") |
---|
55 | #print ('y from %.2f to %.2f (midi note)' % (freq_start, freq_end)) |
---|
56 | |
---|
57 | ax.fmt_xdata = lambda x: "%.1f" % (x * time_step) |
---|
58 | x_formatter = ticker.FuncFormatter(lambda x, pos: ax.fmt_xdata(x) ) |
---|
59 | ax.xaxis.set_major_formatter(x_formatter) |
---|
60 | if 0: |
---|
61 | total_duration = time_step * len(cqts) |
---|
62 | if total_duration >= 60: rate = 10. |
---|
63 | elif total_duration >= 10: rate = 5. |
---|
64 | elif total_duration >= 3: rate = 1. |
---|
65 | elif total_duration >= 1: rate = .2 |
---|
66 | elif total_duration < 1: rate = .1 |
---|
67 | #ax.xaxis.set_major_locator(ticker.FixedLocator(np.arange(0, len(cqts), rate/time_step))) |
---|
68 | ax.xaxis.set_major_locator(ticker.MultipleLocator(base=rate/time_step)) |
---|
69 | else: |
---|
70 | ax.xaxis.set_major_locator(ticker.AutoLocator()) |
---|
71 | #ax.xaxis.set_major_locator(ticker.MaxNLocator(nbins=10, symmetric=True)) |
---|
72 | #ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True, steps=[1])) |
---|
73 | #ax.xaxis.set_major_locator(ticker.MultipleLocator(base=1./time_step)) |
---|
74 | |
---|
75 | ax.set_xlabel ('Time (s)') |
---|
76 | |
---|
77 | ax.fmt_ydata = lambda y: "%.1f" % (y * freq_step + freq_start) |
---|
78 | y_formatter = ticker.FuncFormatter(lambda y, pos: ax.fmt_ydata(y)) |
---|
79 | ax.yaxis.set_major_formatter(y_formatter) |
---|
80 | ax.yaxis.set_major_locator(ticker.MultipleLocator(base=bins_per_octave)) |
---|
81 | ax.set_ylabel ('Frequency (midi)') |
---|
82 | |
---|
83 | ax.set_title('Constant-Q tranform of %s' % os.path.basename(input_filename)) |
---|
84 | |
---|
85 | plt.show() |
---|
86 | except ImportError: |
---|
87 | print ('install matplotlib to plot results') |
---|