Python code for generating audio files algorithmically
Posted: Tue May 23, 2017 9:21 pm
Something I was working on recently, some Python code to generate audio files for use with the 2B.
At the moment is has amplitude modulation but not frequency modulation yet. An example script is attached at the end of the script.
I will probably put this on github soon enough.
ssynth.py
To use it (example):
example.py
Soon I'll post the Python API I wrote a few years ago. I need to clean up the code a little first though.
At the moment is has amplitude modulation but not frequency modulation yet. An example script is attached at the end of the script.
I will probably put this on github soon enough.
ssynth.py
Code: Select all
from scipy.io.wavfile import write
from numpy import linspace, sin, pi, int16
import seaborn as sns; sns.set()
import numpy as np
from scipy import signal
def tone(freq, len, amp=1, rate=44100):
t = linspace(0, len, len*rate)
data = sin(2*pi*freq*t) * amp
return data
def square(freq, len, duty=0.5, amp=1, rate=44100):
t = linspace(0, len, len*rate)
sq = signal.square(2*pi*t*freq, duty=duty)
return sq * amp
def sawtooth(freq, len, width=1., amp=1, rate=44100):
t = linspace(0, len, len*rate)
saw = signal.sawtooth(2*pi*t*freq, width)
return saw * amp
def pause(len, rate=44100):
t = linspace(0, 0, len*rate)
return t
def extract_snip(tone, start, end, rate=44100):
nsamples = len(tone)
length = float(nsamples)/rate
start_sample = start * rate
end_sample = end * rate
return tone[start_sample:end_sample]
def modulate(tone, mod):
assert len(tone) == len(mod)
return tone * mod
def modulate_gaussian(tone, c, rate=44100):
nsamples = len(tone)
length = float(nsamples)/rate
t = linspace(-length/2, length/2, nsamples)
#tshift = -nsamples/2
g = np.exp(-(t)**2/(2*c**2))
return modulate(tone, g)
def modulate_fadein(tone, in_by=0.25, rate=44100):
nsamples = len(tone)
length = float(nsamples)/rate
in_by_sample = int(in_by * rate)
t = linspace(0, 1, in_by_sample)
nfollowing = int(nsamples - in_by_sample)
following = linspace(1, 1, nfollowing)
t = np.append( [t], [following] )
return modulate(tone, t)
def modulate_fadeout(tone, start_fade=0.75, rate=44100):
nsamples = len(tone)
length = float(nsamples)/rate
fade_at_sample = start_fade * rate
nfade = int(nsamples - fade_at_sample)
fade = linspace(1, 0, nfade)
t = linspace(1, 1, fade_at_sample)
t = np.append( [t], [fade] )
return modulate(tone, t)
def modulate_parabola(tone, rate=44100):
nsamples = len(tone)
length = float(nsamples)/rate
t = linspace(0, length, nsamples)
length = length/2
p = length**2 - (t - length)**2
p /= np.max(p)
return modulate(tone, p)
def write_waveform(data, fn, bitrate=44100):
write(fn, bitrate, data.astype(int16))
def plot_waveform(data, fn='waveform.png'):
sns.plt.plot(data)
sns.plt.savefig(fn)
sns.plt.close()
example.py
Code: Select all
import numpy as np
from ssynth import *
# presets
rumble_low = square(15, len=6, amp=10000)
rumble = square(40, len=6, amp=10000)
rumble_mid = square(100, len=6, amp=10000)
rumble_high = square(150, len=5, amp=10000)
spike = tone(2000, len=4, amp=15000)
rampup = modulate_fadein(sawtooth(100, len=30, amp=12500), in_by=27)
pulse_high = modulate_parabola(tone(1500, len=2, amp=20000))
pulse_low = modulate_parabola(tone(200, len=2, amp=12500))
p0 = pause(0.25)
p1 = pause(1)
p2 = pause(2)
p3 = pause(3)
stream = np.zeros(1)
stream = np.append(stream, rumble)
stream = np.append(stream, p1)
stream = np.append(stream, rumble_low)
stream = np.append(stream, p0)
stream = np.append(stream, rumble_mid)
stream = np.append(stream, spike)
stream = np.append(stream, rumble_mid)
stream = np.append(stream, spike)
stream = np.append(stream, rumble_mid)
stream = np.append(stream, spike)
stream = np.append(stream, p1)
stream = np.append(stream, pulse_high)
stream = np.append(stream, pulse_low)
stream = np.append(stream, p1)
stream = np.append(stream, rampup)
stream = np.append(stream, p1)
stream = np.append(stream, rampup)
write_waveform(stream, 'audio.wav')