Sampled Instrument Player with static and monolithic design. All instruments are built-in.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

79 lines
3.6 KiB

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from meta import ly2Track, initCbox, start, connectPhysicalKeyboards
def processMidiIn(eventLoop):
"""cbox event: ("event address", None, [firstByte, pitch, velocit])
Cbox event come in pairs
first is the normal midi-event + channel
channel = first & 0x0F
mode = first & 0xF0
Of course it doesn't need to be pitch and velocity.
But this is easier to document than "data2, data3"
Either call cbox.call_on_idle or cbox.get_new_events.
Both will clean the event queue but only the latter will give us
the results as python data.
"""
eventList = cbox.get_new_events()
lenList = len(eventList)
if lenList >= 2 and lenList % 2 == 0:
for (address, uninterestingStuff, event) in eventList: #we are only interested in the event, which is a list again.
#print (address, "event:", event, "playback:", cbox.Transport.status().playing)
if address in ("/io/midi/event_time_samples", "/io/midi/event_time_ppqn", ):
assert len(event) == 1
#We are very strict at the moment. A timestamp is only allowed if there wasn't another timestamp waiting. It is strict because only simple_event with len==3 eat up the timestamp. Any other event will trigger an error.
if processMidiIn.lastTimestamp:
raise NotImplementedError("the previous event didn't eat up the timestamp")
else:
if address == "/io/midi/event_time_ppqn":
assert cbox.Transport.status().playing == 1
during_recording = True
else:
assert not cbox.Transport.status().playing == 1
during_recording = False
processMidiIn.lastTimestamp = event[0]
elif address == "/io/midi/simple_event" and len(event) == 3: #we can only unpack the event after knowing its length.
assert processMidiIn.lastTimestamp # Midi events are always preceded by timestamps
first, second, third = event
channel = first & 0x0F
mode = first & 0xF0 #0x90 note on, 0x80 note off and so on.
if mode == 0x90: #Note On. 144 in decimal
midipitch = second
velocity = third
if during_recording:
print("ON: {}, Channel: {}, Pitch: {}, Velocity: {}".format(processMidiIn.lastTimestamp, channel, midipitch, velocity))
#else:
# print("ON Time-Samples: {}, Channel: {}, Pitch: {}, Velocity: {}".format(processMidiIn.lastTimestamp, channel, midipitch, velocity))
elif mode == 0x80: #Note Off. 128 in decimal
midipitch = second
velocity = third
if during_recording:
print("OFF: {}, Channel: {}, Pitch: {}, Velocity: {}".format(processMidiIn.lastTimestamp, channel, midipitch, velocity))
#elif mode == 0xB0: #CC
# ccNumber = second
# ccValue = third
#else:
#discard the events
processMidiIn.lastTimestamp = None
else:
raise NotImplementedError("Address type {} unknown".format(address))
eventLoop.call_later(0.1, processMidiIn, eventLoop)
processMidiIn.lastTimestamp = None
scene, cbox, eventLoop = initCbox("test01", internalEventProcessor=False)
#ly2Track(trackName="doWeNeedThis", lyString="c8")
eventLoop.call_later(0.1, processMidiIn, eventLoop) #100ms
connectPhysicalKeyboards()
start()