@ -46,12 +46,17 @@ class StepMidiInput(MidiInput):
which means that as long as one of the chord notes would still be down the chord was still " on " .
That is not as robust and convenient as using the starting note , which is counter intuitive ,
therefore documented here .
Up until 2022 we used the midi in active toggle just on / off . So the template bypass .
But now we never switch midi processing off , we just reroute input vs . setting the pitch cursor
"""
def __init__ ( self ) :
#No super init in here! This is delayed until self.start
self . firstActiveNote = None #for chord entry.
self . _currentlyActiveNotes = set ( )
self . ready = False #Program start
self . inputitemTrueCursorpitchFalse = False #start with just
def start ( self ) :
""" Call this manually after the engine and an event loop have started.
@ -59,7 +64,8 @@ class StepMidiInput(MidiInput):
But it could be started from a simple command line interface as well . """
assert api . laborejoEngineStarted
super ( ) . __init__ ( session = api . session , portName = " in " )
self . midiProcessor . active = False #specific to Laborejo
self . midiProcessor . active = True #never off.
self . ready = True #Program start
#Connect the template midi input with Laborejo api calls.
#self.midiProcessor.notePrinter(True)
@ -71,35 +77,42 @@ class StepMidiInput(MidiInput):
@property
def midiInIsActive ( self ) :
"""
try :
return self . midiProcessor . active
except AttributeError : #during startupt
except AttributeError : #during startup
return False
"""
return self . inputitemTrueCursorpitchFalse
def _insertMusicItemFromMidi ( self , timeStamp , channel , midipitch , velocity ) :
if self . _currentlyActiveNotes : #Chord
api . left ( )
keysig = api . session . data . currentTrack ( ) . state . keySignature ( )
pitchToInsert = api . pitchmath . fromMidi ( midipitch , keysig )
api . addNoteToChord ( pitchToInsert )
api . right ( )
else : #Single note
baseDuration = api . session . data . cursor . prevailingBaseDuration
keysig = api . session . data . currentTrack ( ) . state . keySignature ( )
pitchToInsert = api . pitchmath . fromMidi ( midipitch , keysig )
api . insertChord ( baseDuration , pitchToInsert )
self . _currentlyActiveNotes . add ( midipitch )
keysig = api . session . data . currentTrack ( ) . state . keySignature ( )
pitchToInsert = api . pitchmath . fromMidi ( midipitch , keysig )
if self . inputitemTrueCursorpitchFalse :
if self . _currentlyActiveNotes : #Chord
api . left ( )
api . addNoteToChord ( pitchToInsert )
api . right ( )
else : #Single note
baseDuration = api . session . data . cursor . prevailingBaseDuration
api . insertChord ( baseDuration , pitchToInsert )
else :
api . session . data . cursor . cursorWasMovedAfterChoosingPitchViaMidi = False
api . toPitch ( pitchToInsert )
self . _currentlyActiveNotes . add ( midipitch ) #This needs to be at the end of the function for chord-detection to work
def _pop ( self , timeStamp , channel , midipitch , velocity ) :
self . _currentlyActiveNotes . remove ( midipitch )
def setMidiInputActive ( self , state : bool ) :
self . midiProcessor . active = state
#self.midiProcessor.active = state
self . inputitemTrueCursorpitchFalse = state
api . callbacks . _prevailingBaseDurationChanged ( api . session . data . cursor . prevailingBaseDuration )
def toggleMidiIn ( self ) :
self . setMidiInputActive ( not self . midiInIsActive )
#self.setMidiInputActive(not self.midiInIsActive)
self . setMidiInputActive ( not self . inputitemTrueCursorpitchFalse )
def _setMidiThru ( self , cursorExport ) :
""" We don ' t need to react to deleted tracks because that does reset the cursor.