[347d273] | 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') |
---|