From 1e7a8f938c0259f0555b3b21d75333cee052e52b Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Fri, 8 Mar 2013 20:26:24 -0500 Subject: [PATCH] demos/demo_sink_create_woodblock.py: table lookup to improve synthesis --- python/demos/demo_sink_create_woodblock.py | 65 +++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/python/demos/demo_sink_create_woodblock.py b/python/demos/demo_sink_create_woodblock.py index 9fd86ae1..398c41e0 100755 --- a/python/demos/demo_sink_create_woodblock.py +++ b/python/demos/demo_sink_create_woodblock.py @@ -1,38 +1,53 @@ #! /usr/bin/env python import sys -from math import sin, pi +from math import pi, e from aubio import sink -from numpy import array +from numpy import arange, resize, sin, exp, zeros -if len(sys.argv) != 2: - print 'usage: %s ' % sys.argv[0] +if len(sys.argv) < 2: + print 'usage: %s [samplerate]' % sys.argv[0] sys.exit(1) -samplerate = 44100 # in Hz +samplerate = 44100 # samplerate in Hz +if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) + pitch = 2200 # in Hz blocksize = 256 # in samples duration = 0.02 # in seconds twopi = pi * 2. -duration = int ( 44100 * duration ) # convert to samples -attack = 3 - -period = int ( float(samplerate) / pitch ) -sinetone = [ 0.7 * sin(twopi * i/ period) for i in range(period) ] -sinetone *= int ( duration / period ) -sinetone = array(sinetone, dtype = 'float32') - -from math import exp, e -for i in range(len(sinetone)): - sinetone[i] *= exp( - e * float(i) / len(sinetone)) -for i in range(attack): - sinetone[i] *= exp( e * (float(i) / attack - 1 ) ) - -my_sink = sink(sys.argv[1], 44100) - -i = 0 -while i + blocksize < duration: - my_sink(sinetone[i:i+blocksize], blocksize) - i += blocksize +duration = int ( samplerate * duration ) # convert to samples +attack = int (samplerate * .001 ) +decay = .5 + +period = float(samplerate) / pitch +# create a sine lookup table +tablelen = 1000 +sinetable = arange(tablelen + 1, dtype = 'float32') +sinetable = 0.7 * sin(twopi * sinetable/tablelen) +sinetone = zeros((duration,), dtype = 'float32') + +# compute sinetone at floating point period +for i in range(duration): + x = int((i % period) / float(period) * tablelen) + sinetone[i] = (sinetable[x] + sinetable[x+1]) / 2 + +# apply some envelope +float_ramp = arange(duration, dtype = 'float32') +sinetone *= exp( - e * float_ramp / duration / decay) +sinetone[:attack] *= exp( e * ( float_ramp[:attack] / attack - 1 ) ) + +if 0: + import matplotlib.pyplot as plt + plt.plot(sinetone) + plt.show() + +my_sink = sink(sys.argv[1], samplerate) + +total_frames = 0 +while total_frames + blocksize < duration: + my_sink(sinetone[total_frames:total_frames+blocksize], blocksize) + total_frames += blocksize +my_sink(sinetone[total_frames:duration], duration - total_frames) -- 2.26.2