Skip to content

Instantly share code, notes, and snippets.

@gldnspud gldnspud/foo.py
Created Oct 14, 2016

Embed
What would you like to do?
from collections import deque
import sys
import time
import threading
import mido
import numpy as np
from orbitant import backend as midi
from orbitant.transport import START, STOP, CLOCK
import sounddevice as sd
import sunvox as sv
import sunvox.buffered
SIZE = 512
FREQ = 44100
SUNVOX_FILE = 'ticks.sunvox'
def main():
clock_p = sv.buffered.BufferedProcess(size=SIZE, freq=FREQ)
player_p = sv.buffered.BufferedProcess(size=SIZE, freq=FREQ)
clock_slot = sv.Slot(process=clock_p)
player_slot = sv.Slot(process=player_p)
buf_len_seconds = SIZE / FREQ
tick_events = deque()
seq_tick_events = deque()
ports = [
midi.open_output('studiomux @ Cadence', virtual=False),
midi.open_output('USB2.0-MIDI Port 2', virtual=False),
]
def callback(outdata, frames, t, status):
clock_buf = clock_p.fill_buffer()
player_buf = player_p.fill_buffer()
outdata[:] = np.tile(player_buf, outdata.shape[1] // 2)
ticks, = (clock_buf.transpose()[0] != 0).nonzero()
if ticks.any():
last = None
for tick in ticks:
if last is None or tick - last > 1:
wait = buf_len_seconds * (tick / SIZE)
until = time.time() + wait
tick_events.append(until)
last = tick
def clock():
print('clock started')
ticks = -1
while True:
if tick_events:
e = tick_events.popleft()
while time.time() < e:
time.sleep(0)
for port in ports:
port.send(CLOCK)
seq_tick_events.append(e)
ticks += 1
if ticks % 24 == 0:
sys.stdout.write('\n')
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(0)
def sequencer():
print('sequencer started')
ticks = -1
while True:
if seq_tick_events:
seq_tick_events.popleft()
ticks += 1
if ticks % 24 == 0:
player_slot.send_event(0, sv.NOTECMD.C4, 32, 3, 0, 0)
sys.stdout.write('C')
else:
sys.stdout.write(' ')
if ticks % 96 == 0:
player_slot.send_event(1, sv.NOTECMD.G3, 48, 3, 0, 0)
sys.stdout.write('G')
else:
sys.stdout.write(' ')
if ticks % 32 == 0:
sys.stdout.write('E')
player_slot.send_event(2, sv.NOTECMD.E4, 64, 3, 0, 0)
else:
sys.stdout.write(' ')
if ticks % 12 == 0:
sys.stdout.write('F')
player_slot.send_event(3, sv.NOTECMD.F4, 64, 3, 0, 0)
else:
sys.stdout.write(' ')
sys.stdout.flush()
time.sleep(0)
clock_thread = threading.Thread(None, clock, 'clock', daemon=True)
clock_thread.start()
sequencer_thread = threading.Thread(None, sequencer, 'sequencer', daemon=True)
sequencer_thread.start()
clock_slot.load(SUNVOX_FILE)
player_slot.load(SUNVOX_FILE)
clock_slot.play_from_beginning()
for port in ports:
port.send(mido.Message('songpos', pos=0))
port.send(START)
with sd.OutputStream(FREQ, SIZE, callback=callback):
input()
for port in ports:
port.send(STOP)
clock_p.kill()
player_p.kill()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.