Created
June 8, 2022 07:38
-
-
Save frostburn/814aa3ca09a4eac12075d423dd87c835 to your computer and use it in GitHub Desktop.
Turning drawings from SOB into audio
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from numpy import arange, linspace, where, maximum, sqrt, floor, clip, concatenate | |
from matplotlib.pyplot import plot, legend, show | |
import scipy.io.wavfile | |
# --- Helpers --- | |
def sqrt0(x): | |
return sqrt(maximum(0, x)) | |
def triangle(x): | |
x = x - floor(x) | |
return 1 - 4*abs(x - 0.5) | |
def fold(x): | |
return triangle(0.25*x + 0.25) | |
# --- SOB drawings --- | |
def cups(x, separation=1): | |
x = x - floor(x) | |
return where(x < 0.5, | |
separation - sqrt0(1 - (4*x-1)**2), | |
sqrt0(1 - (4*x-3)**2) - separation | |
) | |
def clipped_triangle(x, overdrive=2): | |
return clip(triangle(x + 0.25) * overdrive, -1, 1) | |
def folded_triangle(x, overdrive=2): | |
return fold(triangle(x + 0.25) * overdrive) | |
# --- Plot waveforms --- | |
phase = linspace(0, 2, 1000) | |
plot(phase, cups(phase), label="cups") | |
legend() | |
show() | |
plot(phase, clipped_triangle(phase), label="flat peak") | |
legend() | |
show() | |
plot(phase, folded_triangle(phase), label="double peak") | |
legend() | |
show() | |
# --- Render audio --- | |
SAMPLE_RATE = 44100 | |
t = arange(SAMPLE_RATE) / SAMPLE_RATE | |
def chord(waveform): | |
return 0.4 * (waveform(220 * t) + waveform(275 * t) + waveform(330 * t) + waveform(385 * t)) | |
data = 0.49 * concatenate([ | |
cups(220 * t), | |
clipped_triangle(220 * t), | |
folded_triangle(220 * t), | |
0*t, | |
chord(cups), | |
chord(clipped_triangle), | |
chord(folded_triangle) | |
]) | |
scipy.io.wavfile.write("/tmp/sob.wav", SAMPLE_RATE, (data * 2**15).astype("int16")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment