04-data-control.py - Multicore midi synthesizer. ============================================================================================================================================ Need at least 4 cores to be really effective. Usage: python3 -i 04-data-control.py .. code-block:: python import sys, time, multiprocessing from random import uniform from pyo import * VOICES_PER_CORE = 4 if sys.platform.startswith("linux"): audio = "jack" elif sys.platform.startswith("darwin"): audio = "portaudio" else: print("Multicore examples don't run under Windows... Sorry!") exit() class Proc(multiprocessing.Process): def __init__(self, pipe): super(Proc, self).__init__() self.daemon = True self.pipe = pipe def run(self): self.server = Server(audio=audio) self.server.deactivateMidi() self.server.boot().start() self.mid = Notein(poly=VOICES_PER_CORE, scale=1, first=0, last=127) self.amp = MidiAdsr(self.mid["velocity"], 0.005, 0.1, 0.7, 0.5, mul=0.01) self.pit = self.mid["pitch"] * [uniform(0.99, 1.01) for i in range(40)] self.rc1 = RCOsc(self.pit, sharp=0.8, mul=self.amp).mix(1) self.rc2 = RCOsc(self.pit * 0.99, sharp=0.8, mul=self.amp).mix(1) self.mix = Mix([self.rc1, self.rc2], voices=2) self.rev = STRev(Denorm(self.mix), [0.1, 0.9], 2, bal=0.30).out() while True: if self.pipe.poll(): data = self.pipe.recv() self.server.addMidiEvent(*data) time.sleep(0.001) self.server.stop() if __name__ == "__main__": main1, child1 = multiprocessing.Pipe() main2, child2 = multiprocessing.Pipe() main3, child3 = multiprocessing.Pipe() main4, child4 = multiprocessing.Pipe() mains = [main1, main2, main3, main4] p1, p2, p3, p4 = Proc(child1), Proc(child2), Proc(child3), Proc(child4) p1.start() p2.start() p3.start() p4.start() playing = {0: [], 1: [], 2: [], 3: []} currentcore = 0 def callback(status, data1, data2): global currentcore if status == 0x80 or status == 0x90 and data2 == 0: for i in range(4): if data1 in playing[i]: playing[i].remove(data1) mains[i].send([status, data1, data2]) break elif status == 0x90: for i in range(4): currentcore = (currentcore + 1) % 4 if len(playing[currentcore]) < VOICES_PER_CORE: playing[currentcore].append(data1) mains[currentcore].send([status, data1, data2]) break s = Server() s.setMidiInputDevice(99) # Open all devices. s.boot().start() raw = RawMidi(callback)