Skip to content

Instantly share code, notes, and snippets.

@mortie
Last active February 23, 2021 22:58
Show Gist options
  • Select an option

  • Save mortie/53b35fb56a95f82639f927d300c69ad1 to your computer and use it in GitHub Desktop.

Select an option

Save mortie/53b35fb56a95f82639f927d300c69ad1 to your computer and use it in GitHub Desktop.
Horrible Music
#!/usr/bin/env python3
import simpleaudio as sa
import numpy as np
import sys
import wave
kick = wave.open("kick.wav")
class Mixer:
def __init__(self, wav, secs):
self.sampwidth = wav.getsampwidth()
self.samprate = wav.getframerate()
self.nframes = wav.getnframes()
self.position = 0
self.time = 0
self.progress = 0.2
self.writers = []
self.output = np.empty(secs * self.sampwidth * self.samprate, "float")
bs = wav.readframes(self.nframes)
self.data = np.empty(self.nframes, "float")
for i in range(0, self.nframes):
high = bs[i * 2]
low = bs[i * 2 + 1]
self.data[i] = (high << 8 | low)
def add(self):
self.writers.append(self.position)
def proceed(self, secs):
idx = int(self.position)
samps = secs * self.sampwidth * self.samprate
self.position += samps
self.time += secs
self.progress -= secs
if self.progress < 0:
sys.stderr.write(f" {self.time} -- {len(self.writers)} concurrent \r")
self.progress = 0.2
while idx <= self.position:
for start_pos in self.writers:
offset = int(idx - start_pos)
if offset >= self.nframes:
continue
samp = self.data[offset]
self.output[idx] += samp
idx += 1
for i, start_pos in enumerate(self.writers):
offset = int(idx - start_pos)
if offset > self.nframes:
if i == len(self.writers) - 1:
self.writers.pop()
else:
self.writers[i] = self.writers.pop()
def play(self):
return sa.play_buffer(np.array(self.output, "byte"), 1, self.sampwidth, self.samprate)
def save(self, name):
f = wave.open(name, "wb")
f.setnchannels(1)
f.setsampwidth(self.sampwidth)
f.setframerate(self.samprate)
f.writeframes(np.array(self.output, "byte"))
m = Mixer(kick, 102)
def playHz(hz, sec):
t = 0
while t < sec:
m.add()
m.proceed(1 / hz)
t += 1 / hz
for i in range(0, 2):
m.add()
m.proceed(1)
for i in range(0, 4):
m.add()
m.proceed(0.5)
for i in range(0, 8):
m.add()
m.proceed(0.25)
for i in range(0, 15):
m.add()
m.proceed(0.125)
print("\nramping")
hz = 8
while hz < 98:
m.add()
m.proceed(1 / hz)
hz += 4 / hz
playHz(98, 0.5)
# Frequencies from https://pages.mtu.edu/~suits/notefreqs.html
print("\ngo")
playHz(110, 0.5)
playHz(123.47, 0.5)
playHz(110, 0.5)
playHz(130.81, 0.5)
playHz(146.83, 0.5)
playHz(130.81, 0.5)
playHz(123.47, 1)
#
playHz(110, 0.5)
playHz(123.47, 0.5)
playHz(110, 0.5)
playHz(130.81, 0.5)
playHz(123.47, 2)
#
#
#
playHz(110, 0.5)
playHz(123.47, 0.5)
playHz(110, 0.5)
playHz(130.81, 0.5)
playHz(146.83, 0.5)
playHz(130.81, 0.5)
playHz(123.47, 1)
#
playHz(130.81, 1)
#
playHz(123.47, 1)
#
playHz(110, 2)
#
#
#
print("\nramping 2")
hz = 110
while hz < 392:
m.add()
m.proceed(1 / hz)
hz += 16 / hz
print("\nA's")
playHz(440, 2)
playHz(220, 2)
playHz(110, 2)
playHz(60, 2)
playHz(30, 2)
playHz(15, 2)
playHz(7.5, 2)
m.proceed(2)
print("\ndone")
m.save("music.wav")
m.play().wait_done()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment