|
|
@ -244,11 +244,11 @@ class TempoBlock(GraphBlock): |
|
|
|
return oid |
|
|
|
|
|
|
|
class TempoTrack(GraphTrackCC): |
|
|
|
"""The Tempo Track is Laborejos own independent structure that sends data to |
|
|
|
"""The Tempo Track is Laborejos own independent structure that sends data to |
|
|
|
template.sequencer.TempoMap which handles the actual midi/cbox tempo map. |
|
|
|
|
|
|
|
There is only one TempoTrack instance in the main data strucutre. """ |
|
|
|
|
|
|
|
|
|
|
|
There is only one TempoTrack instance in the main data strucutre. """ |
|
|
|
|
|
|
|
def __init__(self, parentData): |
|
|
|
firstBlock = TempoBlock(parentGraphTrack = self) |
|
|
|
firstBlock.name = "Default Tempo" |
|
|
@ -302,7 +302,7 @@ class TempoTrack(GraphTrackCC): |
|
|
|
def splitTempoBlock(self, tempoBlockId, positionInTicksRelativeToBlock): |
|
|
|
"""The new block will be right of the original content. If the new block will be empty |
|
|
|
or has no real start value the last prevailing tempo will be used |
|
|
|
as the blocks start-point""" |
|
|
|
as the blocks start-point""" |
|
|
|
block = self.tempoBlockById(tempoBlockId) |
|
|
|
if not block.duration > positionInTicksRelativeToBlock: |
|
|
|
return False |
|
|
@ -426,15 +426,15 @@ class TempoTrack(GraphTrackCC): |
|
|
|
|
|
|
|
def _expandLastBlockToScoreDuration(self): |
|
|
|
""" |
|
|
|
The tempo tracks needs to be at least as long as the score. |
|
|
|
The tempo tracks needs to be at least as long as the score. |
|
|
|
We force it on every staticExport. |
|
|
|
|
|
|
|
|
|
|
|
This can lead to unexpected behaviour if the last block is content-linked and will resize |
|
|
|
automatically when the score-duration gets longer. All the other content links will resize |
|
|
|
as well. |
|
|
|
We therefore define it to "expected behaviour" and put a note in the users |
|
|
|
manual to prevent that confusion""" |
|
|
|
|
|
|
|
|
|
|
|
lastBlock = self.blocks[-1] |
|
|
|
plainScoreDuration = self.parentData.duration() |
|
|
|
duration = sum(block.duration for block in self.blocks) |
|
|
@ -570,9 +570,20 @@ class TempoTrack(GraphTrackCC): |
|
|
|
"graphType" : thisGraphItem.graphType, |
|
|
|
"lilypondParameters" : thisGraphItem.lilypondParameters, |
|
|
|
} |
|
|
|
if additionalData: #additional data is not for interpolated items |
|
|
|
exportDictItem.update(additionalData) |
|
|
|
|
|
|
|
#There was a problem with this in nuitka 0.6.10 with py 3.9. |
|
|
|
#The full dict was evaluating to False. |
|
|
|
#Working around this was trivial, but let's hope that was not just one example of countless problems. |
|
|
|
#if additionalData: #additional data is not for interpolated items |
|
|
|
# print ("found additional for", id(thisGraphItem), additionalData) |
|
|
|
# exportDictItem.update(additionalData) |
|
|
|
#else: |
|
|
|
# print ("found NO additional for", id(thisGraphItem), additionalData) |
|
|
|
# if "referenceTicks" in additionalData: |
|
|
|
# print ("refTicks in additional!", additionalData) |
|
|
|
exportDictItem.update(additionalData) #updating with an empty dict is ok as well. |
|
|
|
result.append(exportDictItem) |
|
|
|
|
|
|
|
typeString = "interpolated" #The next items in userItemAndInterpolatedItemsPositions are interpolated items. Reset once we leave the local forLoop. |
|
|
|
|
|
|
|
#Prepare data for the next block. |
|
|
@ -596,7 +607,7 @@ class TempoTrack(GraphTrackCC): |
|
|
|
virtualLast.update(additionalData) |
|
|
|
#Add this to the result AFTER we calculate the midi data. Otherwise it will result in conflicts. |
|
|
|
|
|
|
|
#send tempo information to cbox. |
|
|
|
#send tempo information to cbox. |
|
|
|
blocksAsDict = self.blocksAsDict() |
|
|
|
offsetForBlock = {} |
|
|
|
|
|
|
@ -605,7 +616,7 @@ class TempoTrack(GraphTrackCC): |
|
|
|
offsetForBlock[block] = offsetCounter |
|
|
|
offsetCounter += block.duration #after this block is over how many ticks have gone by? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sendToSequencerTempoMap = {} #{positionInTicks:(bpmAsFloat, timesigUpper, timesigLower)} |
|
|
|
for staticItem in result: #static item is a tempo change as exportDictItem from above. |
|
|
|
value = float(abs(staticItem["value"])) #exportItems have negative values. calfbox wants a float. |
|
|
@ -613,7 +624,7 @@ class TempoTrack(GraphTrackCC): |
|
|
|
absoluteBlockStartPosition = offsetForBlock[tempoBlock] |
|
|
|
pos = staticItem["positionInBlock"] + absoluteBlockStartPosition |
|
|
|
sendToSequencerTempoMap[pos] = (value, 4, 4) #TODO: faked 4/4 meter because we do not combine tempo and timesig, but midi and jack wants to combine it. |
|
|
|
|
|
|
|
|
|
|
|
self.parentData.tempoMap.setTempoMap(sendToSequencerTempoMap) |
|
|
|
|
|
|
|
result.append(virtualLast) |
|
|
@ -662,17 +673,17 @@ class TempoTrack(GraphTrackCC): |
|
|
|
@property |
|
|
|
def factor(self): |
|
|
|
return self.parentData.tempoMap.factor |
|
|
|
|
|
|
|
|
|
|
|
def setFactor(self, factor:float): |
|
|
|
self.parentData.tempoMap.setFactor(factor) |
|
|
|
|
|
|
|
def staticTrackRepresentation(self): |
|
|
|
result = {} |
|
|
|
result = {} |
|
|
|
mini, maxi = self.getMinimumAndMaximumValues() |
|
|
|
result["minimumAbsoluteTempoValue"] = mini |
|
|
|
result["maximumAbsoluteTempoValue"] = maxi |
|
|
|
return result |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
def lilypond(self): |
|
|
|
"""Based on the static export""" |
|
|
|