Skip to content

Instantly share code, notes, and snippets.

@RemyPorter
Last active January 4, 2023 18:25
Show Gist options
  • Save RemyPorter/a2607f2714225f0951926b2e5a3873d4 to your computer and use it in GitHub Desktop.
Save RemyPorter/a2607f2714225f0951926b2e5a3873d4 to your computer and use it in GitHub Desktop.
This is a simple synthesizer based on NumPy, which allows you to create surprisingly complex sounds with surprisingly simple code. Uses the Python library `sounddevice` for playback, so you'll need to `pip install sounddevice`
import time
import spatial as sp
import sounddevice as sd
def play(sound, sample_rate=sp.SAMPLE_RATE):
"""Helper to play serially"""
sd.play(sound)
time.sleep(len(sound) / sample_rate)
space = sp.space(3)
play(sp.sin(space, 440)) #concert A sin wave for three seconds
play(sp.sin(space, 440) * (sp.sin(space, 1.) / 2. + 0.5)) #beating w/ a sin wave
play(sp.sigmoid(sp.sin(space,60), sp.sin(space,60)+220)*0.5) #buzzing by modulating frequency
play(sp.sigmoid(sp.sin(space,60), sp.sin(space,60)+220)*(sp.sin(space, 2.) / 2. + 0.5)*0.5) #buzzing by modulating frequency, with a beat
import numpy as np
SAMPLE_RATE=44100
def smoothstep(edge0, edge1, x):
"""broadcastable hermite interpolation, e.g. a sigmoid function"""
t = np.clip((x - edge0) / (edge1 - edge0), 0.0, 1.0)
return t * t * (3.0 - 2.0 * t)
def space(duration, sample_rate=SAMPLE_RATE):
"""Create a samplespace of `duration` seconds"""
return np.mgrid[0:int(sample_rate*duration)] / sample_rate
def sin(space, freq,shift=0):
"""given an arbitrary space, modulate it using a sin wave of `freq` frequency, shifted by `shift` distance"""
return np.sin(2*np.pi*space*freq+shift)
def sigmoid(space, freq, shift=0):
"""given an arbitrary space, modulate it using a sigmoid wave of `freq` frequency, shifted by `shift` distance"""
return smoothstep(0, 1., sin(space, freq, shift)) + smoothstep(-1., 0., sin(space, freq, shift))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment