"tickindex":trackState.tickindex-duration,#we parse the tickindex after we stepped over the item.
"midiBytes":[],
"text":self.text,
"UIstring":"ch{}".format(self.value),#this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible.
"UIstring":f"{self.text}(ch{self.value})"ifself.textelsef"ch{self.value}",#this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible.
}
def_lilypond(self):
"""called by block.lilypond(), returns a string.
Don't create white-spaces yourself, this is done by the structures.
self.ccGraphTracks={}#cc number, graphTrackCC. Every CC is its own SequencerTrack that routes to this tracks jack midi out
self.ccChannels=tuple()#numbers from 0-15 which represent the midi channels all CCs are sent to. Only replaced by a new tuple by the user directly. From json this becomes a list, so don't test for type. If empty then CC uses the initial midi channel.
@ -986,8 +986,9 @@ class Track(object):
#TODO: However, it is even less elegant to put this call in all rhythm editing methods and functions. inserts, block duplicate, content links, augment, tuplets undo etc.
#Taken out an placed in tempo Export. #self.score.tempoTrack.expandLastBlockToScoreDuration() #we guarantee that the tempo track is always at least as long as the music tracks.
patternBlob=bytes()# Create a binary blob that contains the MIDI events
midiNotesBinaryCoxData=bytes()# Create a binary blob that contains the MIDI events
instrumentChangesBinaryCoxData=bytes()# same as above, but only for instrument changes.
originalPosition=self.state.position()
self.getPreliminaryData()
barlines=OrderedDict()#tick:metricalInstruction . We do not use selft.state.barlines, which is simply barlines for the live cursor. This is to send Barlines to a UI and also to generate the Metronome by associating a metricalInstruction with each barline.
patternBlob+=cbox.Pattern.serialize_event(0,0xB0+self.initialMidiChannel,0,self.initialMidiBankMsb)#position, status byte+channel, controller number, controller value
patternBlob+=cbox.Pattern.serialize_event(0,0xB0+self.initialMidiChannel,32,self.initialMidiBankLsb)#position, status byte+channel, controller number, controller value
instrumentChangesBinaryCoxData+=cbox.Pattern.serialize_event(0,0xB0+self.initialMidiChannel,0,self.initialMidiBankMsb)#position, status byte+channel, controller number, controller value
instrumentChangesBinaryCoxData+=cbox.Pattern.serialize_event(0,0xB0+self.initialMidiChannel,32,self.initialMidiBankLsb)#position, status byte+channel, controller number, controller value
localRight=self.right#performance
resultAppend=result.append#performance
@ -1024,11 +1025,15 @@ class Track(object):
expObj=previousItem.exportObject(self.state)#yes, it is correct that the state in the parameter is ahead by one position. Why is it that way? Because everything that matters, like new dynamics will only be parsed afterwards. The trackState is always correct except for the tickindex when exporting after parsing. Thats why exportObject sometimes substracts its own duration for finding its starting tick.
resultAppend(expObj)
dur=expObj["completeDuration"]
forblobinexpObj["midiBytes"]:#a list of
patternBlob+=blob
ifexpObj["type"]=="Chord"orexpObj["type"]=="Rest":#save for later when we create Beams. No other use.
_allExportedChordsAppend(expObj)
ifexpObj["type"]!="InstrumentChange":
forblobinexpObj["midiBytes"]:#a list of
midiNotesBinaryCoxData+=blob
ifexpObj["type"]=="Chord"orexpObj["type"]=="Rest":#save for later when we create Beams. No other use.
_allExportedChordsAppend(expObj)
else:
forblobinexpObj["midiBytes"]:#a list of
instrumentChangesBinaryCoxData+=blob
elifr==2:#block end. Again, this is already the previous state. right now we are in the next block already.
lastBlock=self.blocks[self.state.blockindex-1]#why -1? see comment above
dur=lastBlock.staticExportEndMarkerDuration()
@ -1155,9 +1160,14 @@ class Track(object):
metaData["duration"]=self.state.tickindex#tickindex is now at the end, so this is the end duration. This includes Blocks minimumDuration as well since it is included in left/right
metaData["beams"]=resultBeamGroups
t=(patternBlob,0,self.state.tickindex)
#Notes
t=(midiNotesBinaryCoxData,0,self.state.tickindex)
self.sequencerInterface.setTrack([t])#(bytes-blob, position, length) #tickindex is still on the last position, which means the second parameter is the length