[87b0c03] | 1 | #! /usr/bin/env python |
---|
| 2 | |
---|
| 3 | import sys |
---|
[1e7a8f9] | 4 | from math import pi, e |
---|
[4120fbc] | 5 | from aubio import sink, float_type |
---|
[8fb567c] | 6 | from numpy import arange, sin, exp, zeros |
---|
[87b0c03] | 7 | |
---|
[1e7a8f9] | 8 | if len(sys.argv) < 2: |
---|
[4120fbc] | 9 | print('usage: %s <outputfile> [samplerate]' % sys.argv[0]) |
---|
[87b0c03] | 10 | sys.exit(1) |
---|
| 11 | |
---|
[1e7a8f9] | 12 | samplerate = 44100 # samplerate in Hz |
---|
| 13 | if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) |
---|
| 14 | |
---|
[87b0c03] | 15 | pitch = 2200 # in Hz |
---|
| 16 | blocksize = 256 # in samples |
---|
| 17 | duration = 0.02 # in seconds |
---|
| 18 | |
---|
| 19 | twopi = pi * 2. |
---|
| 20 | |
---|
[1e7a8f9] | 21 | duration = int ( samplerate * duration ) # convert to samples |
---|
| 22 | attack = int (samplerate * .001 ) |
---|
| 23 | decay = .5 |
---|
| 24 | |
---|
| 25 | period = float(samplerate) / pitch |
---|
| 26 | # create a sine lookup table |
---|
| 27 | tablelen = 1000 |
---|
[4120fbc] | 28 | sinetable = arange(tablelen + 1, dtype = float_type) |
---|
[1e7a8f9] | 29 | sinetable = 0.7 * sin(twopi * sinetable/tablelen) |
---|
[4120fbc] | 30 | sinetone = zeros((duration,), dtype = float_type) |
---|
[1e7a8f9] | 31 | |
---|
| 32 | # compute sinetone at floating point period |
---|
| 33 | for i in range(duration): |
---|
| 34 | x = int((i % period) / float(period) * tablelen) |
---|
[dedeffc] | 35 | idx = int(x) |
---|
| 36 | frac = x - idx |
---|
| 37 | a = sinetable[idx] |
---|
| 38 | b = sinetable[idx + 1] |
---|
| 39 | sinetone[i] = a + frac * (b -a) |
---|
[1e7a8f9] | 40 | |
---|
| 41 | # apply some envelope |
---|
[4120fbc] | 42 | float_ramp = arange(duration, dtype = float_type) |
---|
[1e7a8f9] | 43 | sinetone *= exp( - e * float_ramp / duration / decay) |
---|
| 44 | sinetone[:attack] *= exp( e * ( float_ramp[:attack] / attack - 1 ) ) |
---|
| 45 | |
---|
[dedeffc] | 46 | if 1: |
---|
[1e7a8f9] | 47 | import matplotlib.pyplot as plt |
---|
| 48 | plt.plot(sinetone) |
---|
| 49 | plt.show() |
---|
| 50 | |
---|
| 51 | my_sink = sink(sys.argv[1], samplerate) |
---|
| 52 | |
---|
| 53 | total_frames = 0 |
---|
| 54 | while total_frames + blocksize < duration: |
---|
| 55 | my_sink(sinetone[total_frames:total_frames+blocksize], blocksize) |
---|
| 56 | total_frames += blocksize |
---|
| 57 | my_sink(sinetone[total_frames:duration], duration - total_frames) |
---|