def interaction_loop(): """Interaction loop for the box, reads serial, makes predictions, outputs servo and sound.""" global last_received_midi # Start Lever Processing userloc = read_lever() if userloc is not None: if args.verbose: print("Input:", userloc) # Send MIDI to synth. midi_loc = int(userloc * 127) midi_ctl_event = (10, 1, 0, 0, (0, 0), (0, 0), (0, 0), (0, 0, 0, 0, 0, midi_loc)) alsaseq.output(midi_ctl_event) # print("MIDIOUT:", midi_ctl_event) if args.mirror: last_received_midi = midi_loc # Read incoming midi. while(alsaseq.inputpending() > 0): midi_event = alsaseq.input() if midi_event[0] == SND_SEQ_EVENT_CONTROLLER: # just take the controller value last_received_midi = midi_event[7][5] # do something with it if args.verbose: print("Servo:", last_received_midi) # print("MIDI:", midi_event) if args.servo: # Only send to servo if args suggest it. # Only act on most recent message. command_servo(last_received_midi)
def main(): se = ServoEvent() parser = MusicParser() alsaseq.client('RoboWhistle PassThrough', 1, 1, False) # Set up a new ALSA channel alsaseq.connectfrom( 1, 129, 0) # Midi file input needs to be sent in to channel 129 # Backup ALSA channel to run on port 128. Can use either a virtual synth (e.g. Timidity or a physical MIDI keyboard) alsaseq.connectto(1, 128, 0) srv = ServoEvent() srv.ResetServoEvent() #To enter FreePlay mode provide any argument when running the program; if left blank AutoPlay will proceed automaticlly if len(sys.argv) is 2: print "Entering FreePlay Mode" play = FreePlay() play.ManualPlay() else: print str(len(sys.argv)) while 1: if alsaseq.inputpending(): # ALSA queue event = alsaseq.input() # Pop event from top of the queue eventPitch = event[7][ 1] # Pitch of the note that needs to be played parsedNote = parser.AnalyseSingleNote(eventPitch % 12) if parsedNote is None: alsaseq.output( event ) # Event is unplayable by the whistle, forward it to the synthesiser else: se.PlayNoteEvent(parsedNote) # Pass item for playing
def start(self): while True: if alsaseq.inputpending(): (etype, # enum snd_seq_event_type flags, tag, queue, timestamp, source, destination, data) = alsaseq.input() sec, msec = timestamp sclient, sport = source dclient, dport = destination event = self.events[etype] if etype in self.events else etype if event in ['controller', 'pgmchange', 'chanpress', 'pitchbend']: channel, _, _, _, *params = data else: channel, *params = data print('{} event, channel {}, params {}, timestamp {}' .format(event, channel, params, timestamp)) if event in self.binds: self.binds[event](*params[:2])
def play(self): while self.is_running: # check for quit in pygame for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.interrupt = not self.interrupt print("toggle interrupt") if event.key == pygame.K_ESCAPE: self.is_running = False if event.key == pygame.K_RIGHT: self.update_step() if event.key == pygame.K_LEFT: self.update_step(direction="backward") elif event.type == pygame.QUIT: self.is_running = False if alsaseq.inputpending(): event = alsaseq.input() if event[ 0] == 6: # note on event (zumindest bei kleinem midikeyboard) self.reaction_note_on(event) elif event[0] == 7: self.reaction_note_off(event)
def receive(self, debug=False): running = True if debug: print("run receiver") while running: # Read the queue try: msg = self.in_q.get_nowait() except Empty: pass else: ctrl, idx, value = msg if ctrl == "exit": self.running = False # Event types: # https://www.alsa-project.org/alsa-doc/alsa-lib/seq__event_8h_source.html evt = parse_event(*alsaseq.input(), debug=debug) if evt["channel"] == CTRL_CHANNEL: # Main controller event if evt["control"]: control = evt["control"]["control"] value = evt["control"]["value"] if debug: print("control", evt) if 13 <= control <= 20: self.publish(("cc1", control - 13, value)) if 29 <= control <= 36: self.publish(("cc2", control - 29, value)) if 49 <= control <= 56: self.publish(("cc3", control - 49, value)) if 77 <= control <= 84: self.publish(("cc4", control - 77, value)) elif evt["note"]: note = evt["note"]["note"] if debug: print(evt) if note == PAGE_UP: self.publish(("pagechange", 0, 1)) if note == PAGE_DN: self.publish(("pagechange", 0, -1)) if note == SCALE_UP: self.publish(("scalechange", 0, 1)) if note == SCALE_DN: self.publish(("scalechange", 0, -1)) if note == SPEED_UP: self.publish(("speedchange", 0, 10)) if note == SPEED_DN: self.publish(("speedchange", 0, -10)) if note == EXIT: self.publish(("exit", 0, 0)) running = False self.publish(("message", None, str(evt))) elif evt["note"]: # Root note change from another controller if debug: print("note", evt) note = data[1] self.publish(("root", 0, evt["note"]["note"]))
def MIDIgen(self): # Try to run using a platform-specific backend if platform.system() == "Linux" and alsa_ok: alsaseq.client("Audionodes", 1, 1, False) while True: if alsaseq.inputpending(): inputData = alsaseq.input() if inputData[0] in (6, 7): # Key f = 440 * (2**((inputData[-1][1] - 48) / 12)) yield { "type": "key", "frequency": f, "velocity": inputData[-1][2], "note": inputData[-1][1] } elif inputData[0] in (10, ): # Sustain yield { "type": "sustain", "velocity": inputData[-1][-1] } time.sleep(0.01) # If such is not available, fall back to PyGame else: pygame.init() midi.init() inputdata = midi.Input(midi.get_default_input_id()) def toDict(event): velocity = event[0][0][2] # Sustain if event[0][0][0] == 176 and event[0][0][1] == 64: return {"velocity": velocity, "type": "sustain"} elif event[0][0][0] == 144: note = event[0][0][1] f = 440 * (2**((note - 48) / 12)) return { "type": "key", "velocity": velocity, "note": note, "frequency": f } while 1: if inputdata.poll(): event = inputdata.read(1) if toDict(event) != None: print(toDict(event)) yield toDict(event) time.sleep(0.01)
def midi_read(self): while alsaseq.inputpending(): event = alsaseq.input() chan = event[7][0] if event[0]==alsaseq.SND_SEQ_EVENT_CONTROLLER and chan==self.midi_chan and self.active_screen=='control': ctrl = event[7][4] val = event[7][5] print ("MIDI CTRL " + str(ctrl) + ", CH" + str(chan) + " => " + str(val)) if ctrl in self.screens['control'].zcontroller_map.keys(): self.screens['control'].zcontroller_map[ctrl].set_value(val,True) if self.polling: top.after(40, self.midi_read)
def midi_read(self): try: while alsaseq.inputpending(): event = alsaseq.input() chan = event[7][0] if event[0]==alsaseq.SND_SEQ_EVENT_CONTROLLER and chan==self.zyngine.get_midi_chan() and self.active_screen=='control': ctrl = event[7][4] val = event[7][5] #print ("MIDI CTRL " + str(ctrl) + ", CH" + str(chan) + " => " + str(val)) if ctrl in self.screens['control'].zcontroller_map.keys(): self.screens['control'].zcontroller_map[ctrl].set_value(val,True) except Exception as err: print("ERROR: zynthian_gui.midi_read() => %s" % err) if self.polling: top.after(40, self.midi_read)
def run(self): import select alsaseq.client(appinfo.name, self.num_inports, self.num_outports, True) self.start_time = datetime.now() alsaseq.start() log.debug("ALSA sequencer started") alsafd = alsaseq.fd() while not self.join_req: fds_ready = select.select([alsafd], [], [], 0.1) if alsaseq.inputpending(): raw_event = alsaseq.input() new_event = self.create_event(raw_event) self.dispatch_event(new_event)
def run(clientName, inPorts, outPorts, controller): curScreen = controller alsaseq.client(clientName, inPorts, outPorts, True) initd = False while True: if not alsaseq.inputpending(): time.sleep(0.001) continue val = alsaseq.input() mtype = val[0] if mtype == _MIDI_CONNECT: __devi = val[7][0] __devo = val[7][2] initd = True elif not initd: continue elif mtype == _MIDI_CC: but = val[7][4] vel = val[7][5] r,c = __b2idx(but) if c == 9: but = PLAY if vel == 0: curScreen.onButtonUp(but, 9 - r, c) else: curScreen.onButtonDown(but, vel, 9 - r, c) elif mtype == _MIDI_ON: but = val[7][1] vel = val[7][2] r,c = __b2idx(but) if vel == 0: curScreen.onButtonUp(but, 9 - r, c) else: curScreen.onButtonDown(GRID, vel, 9 - r, c) elif mtype == _MIDI_OFF: but = val[7][1] vel = val[7][2] r,c = __b2idx(but) curScreen.onButtonUp(GRID, 9 - r, c) elif mtype == _MIDI_MAFTER: vel = val[7][5] curScreen.onMonoAftertouch(vel) elif mtype == _MIDI_PAFTER: but = val[7][1] vel = val[7][2] r,c = __b2idx(but) curScreen.onPolyAftertouch(9 - r, c, vel)
def run(self): import select alsaseq.client(appinfo.name, self.num_inports, self.num_outports, True) self.start_time = datetime.now() alsaseq.start() log.debug("ALSA sequencer started") alsafd = alsaseq.fd() while not self.join_req: fds_ready = select.select([alsafd], [], [], 0.1) if alsaseq.inputpending(): raw_event = alsaseq.input() new_event = self.create_event(raw_event) self.dispatch_event(new_event) alsaseq.stop() alsaseq.close()
def run(self): print ("starting alsa listener") while not sync.terminate.isSet(): if alsaseq.inputpending(): now = time.time() event = alsaseq.input() evtype = event[0] pitch = event[7][1] if evtype == alsaseq.SND_SEQ_EVENT_NOTEON: sync.putEvent(now) else: time.sleep(0.001) continue else: time.sleep(0.001) continue print ("stopping alsa listener")
def run(self): print "starting alsa listener" while not sync.terminate.isSet(): if alsaseq.inputpending(): event = alsaseq.input() evtype = event[0] pitch = event[7][1] if evtype == alsaseq.SND_SEQ_EVENT_NOTEON: cmd = (PSH_NOTE, pitch) elif evtype == alsaseq.SND_SEQ_EVENT_NOTEOFF: cmd = (POP_NOTE, pitch) elif evtype == alsaseq.SND_SEQ_EVENT_START: cmd = (TRP_START, None) elif evtype == alsaseq.SND_SEQ_EVENT_STOP: cmd = (TRP_STOP, None) elif evtype == alsaseq.SND_SEQ_EVENT_CLOCK: cmd = (TRP_TICK, None) else: continue sync.putCommand(cmd) else: time.sleep(0.005) continue print "stopping alsa listener"
def retrieveinput(): "Retrieve received events." global incoming, waitingforsplit, split p = select.poll() p.register(fd, select.POLLIN) while vivo: p.poll(5000) while alsaseq.inputpending(): entrante = alsaseq.input() nota = entrante[7][1] type = entrante[0] if type in rechazados: continue # discard obnoxious Clavinova events elif type == alsaseq.SND_SEQ_EVENT_ECHO: drums(ritmos[nritmo], tempo, compases) continue ev = alsamidi.modifyevent(entrante, ch=1) if waitingforsplit: split = nota waitingforsplit = 0 print(nota) continue # discard note if not split: alsaseq.output(entrante) alsaseq.output(ev) incoming.append(ev) incoming.append(entrante) elif nota > split: alsaseq.output(entrante) incoming.append(entrante) else: alsaseq.output(ev) incoming.append(ev) print(len(incoming), "incoming") print("Ending retrieveinput()")
def retrieveinput(): 'Retrieve received events.' global incoming, waitingforsplit, split p = select.poll() p.register(fd, select.POLLIN) while vivo: p.poll(5000) while alsaseq.inputpending(): entrante = alsaseq.input() nota = entrante[7][1] type = entrante[0] if type in rechazados: continue # discard obnoxious Clavinova events elif type == alsaseq.SND_SEQ_EVENT_ECHO: drums(ritmos[nritmo], tempo, compases) continue ev = alsamidi.modifyevent(entrante, ch=1) if waitingforsplit: split = nota waitingforsplit = 0 print(nota) continue # discard note if not split: alsaseq.output(entrante) alsaseq.output(ev) incoming.append(ev) incoming.append(entrante) elif nota > split: alsaseq.output(entrante) incoming.append(entrante) else: alsaseq.output(ev) incoming.append(ev) print(len(incoming), 'incoming') print('Ending retrieveinput()')
def Read(self, num_events): if back_end == 'pypm': pkt = self.mDevIn.Read(num_events) m_time = pkt[0][1] b0 = pkt[0][0][0] b1 = pkt[0][0][1] b2 = pkt[0][0][2] b3 = pkt[0][0][3] return (m_time, b0, b1, b2, b3) elif back_end == 'alsaseq': pkt = alsaseq.input() mtype = pkt[0] flags = pkt[1] tag = pkt[2] queue = pkt[3] #m_time = pkt[4] todo... m_time = 0 src = pkt[5] dest = pkt[6] mdata = pkt[7] if mtype == alsaseq.SND_SEQ_EVENT_SENSING: #42: # tick? get about 3 per second return None b0 = mdata[0] # 0, ch? mtype=6 b1 = mdata[1] # note b2 = mdata[2] # velocity b3 = mdata[3] # 0 print(pkt) # need to debug,understand, print it. if mtype == alsaseq.SND_SEQ_EVENT_NOTEON: #6: if len(mdata) != 5: print('noteon unexpected len:%d' % (len(mdata))) print('ch:%d noteon:%d vel:%d' % (b0, b1, b2)) return (m_time, b0 | 0x80, b1, b2, b3) if mtype == alsaseq.SND_SEQ_EVENT_NOTEOFF: #7: if len(mdata) != 5: print('noteoff unexpected len:%d' % (len(mdata))) print('ch:%d noteoff:%d vel:%d' % (b0, b1, b2)) return (m_time, b0 | 0x90, b1, b2, b3) elif mtype == alsaseq.SND_SEQ_EVENT_CONTROLLER: #10: if len(mdata) != 6: print('cc unexpected len:%d' % (len(mdata))) b4 = mdata[4] # cc number b5 = mdata[5] # value print('ch:%d cc:%d val:%d' % (b0, b4, b5)) return (m_time, b0 | 0xb0, b4, b5, b3) elif mtype == alsaseq.SND_SEQ_EVENT_PITCHBEND: # 13: if len(mdata) != 6: print('cc unexpected len:%d' % (len(mdata))) b4 = mdata[4] # cc number b5 = mdata[5] # value here, see on pitch wheel -8192 to 8192 print('ch:%d cc-ext?pitch? cc:%d val:%d' % (b0, b4, b5)) return (m_time, b0 | 0xe0, b4, b5, b3) else: print('unhandled alsaseq pkt type:%d' % (mtype)) print(pkt) return None elif back_end == 'rtmidi': if not self.rtmidi_pkt: return None self.rtmidi_pkt_read_flag = True print('rtmidi pkt:') print(self.rtmidi_pkt) buf = self.rtmidi_pkt[0] mtime = self.rtmidi_pkt[1] ret_pkt = [mtime,] for b in buf: ret_pkt.append(b) ret_pkt.append(0) return ret_pkt elif back_end == 'mididings': print('mididings Read not implemented') return None
def JUNK_OLD_Read(self): # read the alsa event ev = alsaseq.input() (mtype, flags, tag, queue, m_time, src, dest, mdata) = ev if mtype == alsaseq.SND_SEQ_EVENT_SENSING: #42: # tick? get about 3 per second return None # ignore for now, filter these out quitely. b0 = mdata[0] # 0, ch? mtype=6 b1 = mdata[1] # note b2 = mdata[2] # velocity b3 = mdata[3] # 0 if self.verbose & 4: print(mtype, flags, tag, queue, m_time, src, dest, mdata) # need to debug,understand, print it. # there is just a NOTE ev, why? would I see this ever? if mtype == alsaseq.SND_SEQ_EVENT_NOTEON: #6: if len(mdata) != 5: print('noteon unexpected len:%d' % (len(mdata))) if self.verbose & 2: print('ch:%d noteon:%d vel:%d' % (b0, b1, b2)) return (ev, b0 | 0x80, b1, b2, b3) elif mtype == alsaseq.SND_SEQ_EVENT_NOTEOFF: #7: if len(mdata) != 5: print('noteoff unexpected len:%d' % (len(mdata))) if self.verbose & 2: print('ch:%d noteoff:%d vel:%d' % (b0, b1, b2)) return (ev, b0 | 0x90, b1, b2, b3) elif mtype == alsaseq.SND_SEQ_EVENT_CONTROLLER: #10: if len(mdata) != 6: print('cc unexpected len:%d' % (len(mdata))) b4 = mdata[4] # cc number b5 = mdata[5] # value if self.verbose & 2: print('ch:%d cc:%d val:%d' % (b0, b4, b5)) return (ev, b0 | 0xb0, b4, b5, b3) elif mtype == alsaseq.SND_SEQ_EVENT_PGMCHANGE: #?: if len(mdata) != 4: print('cc unexpected len:%d' % (len(mdata))) b4 = mdata[4] # prog number if self.verbose & 2: print('ch:%d prog:%d' % (b0, b4)) return (ev, b0 | 0xc0, b4, 0, 0) elif mtype == alsaseq.SND_SEQ_EVENT_PITCHBEND: # 13: if len(mdata) != 6: print('cc unexpected len:%d' % (len(mdata))) b4 = mdata[4] # cc number b5 = mdata[5] # value here, see on pitch wheel -8192 to 8192 if self.verbose & 2: print('ch:%d cc-ext?pitch? cc:%d val:%d' % (b0, b4, b5)) return (ev, b0 | 0xe0, b4, b5, b3) else: if self.verbose & 2: print('Unhandled alsaseq pkt type:%d' % (mtype)) if self.verbose & 4: print(mtype, flags, tag, queue, m_time, src, dest, mdata) if self.verbose & 2: print(' mtype:%x flags:%x tag:%x queue:%x m_time:%s src:%s dest:%s mdata:%s' % \ (mtype, flags, tag, queue, str(m_time), str(src), str(dest), str(mdata))) return None
events = [] EV_KEYDOWN = 6 EV_KEYUP = 7 s = serial.Serial("/dev/ttyUSB0", 115200) ch = 1 def sendmsg(chan,note,vel): print "msg going",chan,note onoff = 0x40 if note >= 0 else 0 note = abs(note) s.write(chr(0x80 | chan | onoff)) s.write(chr(0x60 | (note >> 4))) s.write(chr(0x50 | (note & 0xf))) s.write(chr(0x20 | (vel >> 4))) s.write(chr(0x10 | (vel & 0xf))) while 1: if alsaseq.inputpending(): ch = int(open("ch.txt", "r").read()) event = alsaseq.input() evtype = event[0] if evtype == EV_KEYDOWN: sendmsg(ch, event[7][1], event[7][2]) elif evtype == EV_KEYUP: sendmsg(ch, -event[7][1], event[7][2]) else: print event
# amidioffset.py - Tom Clayton # Connect input and out put to alsa midi streams and this program will # shift midi notes received by x notes. x is set with a command line # argument. x can be negative to shift down. import alsaseq import sys if len(sys.argv) > 1: offset = int(sys.argv[1]) else: print("Enter offset as command line argument.") sys.exit() alsaseq.client('Midi Offset', 1, 1, False) # alsaseq event: # (type, flags, tag, queue, time stamp, source, destination, data) # data = (channel, note, velocity, ??, ??) while True: if alsaseq.inputpending(): event = list(alsaseq.input()) if (event[0] == 6 or event[0] == 7): data = list(event[7]) data[1] += offset event[7] = tuple(data) alsaseq.output(event)
]) """ for h in s.getAllHitsSecs(): alsaseq.output(noteOn(h[0], 127, h[1] )); totalTime = s.totalSecsLength() print totalTime time.sleep(totalTime) exit() bpm = 240 spb = 60.0/bpm blen = .01 for i in range(0,10): print i; alsaseq.output(noteOn(i*spb)); alsaseq.output(noteOff((i+blen) * spb)); time.sleep(5) exit() while 1: if alsaseq.inputpending(): ev = alsaseq.input() print ev alsaseq.output( ev )
#!/usr/bin/env python3 # amiditimer.py - Tom Clayton # Connect input and output to alsa midi streams and this program will # send a message out and time how long it takes for it to return. import alsaseq import sys alsaseq.client('Midi Timer', 1, 1, True) # alsaseq event: # (type, flags, tag, queue, time stamp, source, destination, data) # data = (channel, note, velocity, start, duration) out_event = (6, 1, 0, 1, (0, 0), (0, 0), (0, 0), (0, 60, 127, 0, 0)) input("Midi Timer, connect then hit enter to start.") alsaseq.output(out_event) alsaseq.start() while True: if alsaseq.inputpending(): event = alsaseq.input() if event[0] == 6: print(event[4][1] / 1000000, " ms") break