@ -54,16 +54,16 @@ class ClientCallbacks(Callbacks): #inherits from the templates api callbacks
ppqn = cbox . Transport . status ( ) . pos_ppqn * session . data . subdivisions
status = playbackStatus ( )
for func in self . setPlaybackTicks :
func ( ppqn , status )
func ( ppqn , status )
def _loopChanged ( self , measurenumber , loopStart , loopEnd ) :
export = measurenumber
for func in self . loopChanged :
func ( export )
func ( export )
def _timeSignatureChanged ( self ) :
nr = session . data . howManyUnits
typ = session . data . whatTypeOfUnit
typ = session . data . whatTypeOfUnit
for func in self . timeSignatureChanged :
func ( nr , typ )
@ -79,26 +79,26 @@ class ClientCallbacks(Callbacks): #inherits from the templates api callbacks
You don ' t need to redraw anything if you don ' t want to . One recommendation is to
draw every n step a little more important ( bigger , different color ) .
where n = subdivions
We also place JACK BBT via tempoMap here because we need it every time the time sig
We also place JACK BBT via tempoMap here because we need it every time the time sig
changes ( which calls _subdivisionsChanged ) and if subdivisions change .
"""
typ = baseDurationToTraditionalNumber [ session . data . whatTypeOfUnit ]
typ = baseDurationToTraditionalNumber [ session . data . whatTypeOfUnit ]
nr = session . data . howManyUnits
tradNr = int ( nr / session . data . subdivisions )
tradNr = int ( nr / session . data . subdivisions )
#JACK BBT for Timebase Master. No matter if we are master at the moment or not.
if tradNr == nr / session . data . subdivisions :
if tradNr == nr / session . data . subdivisions :
#Easier to read than the else case. Not possible with 9 Steps per Pattern in Groups of 2 because that is a 4.5/4 timesig.
session . data . tempoMap . setTimeSignature ( tradNr , typ )
session . data . tempoMap . setTimeSignature ( tradNr , typ )
else :
#Always possible, compared to first if case.
#Always possible, compared to first if case.
session . data . tempoMap . setTimeSignature ( nr , typ * session . data . subdivisions )
export = session . data . subdivisions
for func in self . subdivisionsChanged :
func ( export )
callbacks . _dataChanged ( )
def _scoreChanged ( self ) :
""" This includes the time signature as well, but is not send on a timesig change.
@ -120,7 +120,7 @@ class ClientCallbacks(Callbacks): #inherits from the templates api callbacks
and stepChanged . """
export = track . export ( )
for func in self . exportCacheChanged :
func ( export )
func ( export )
def _patternChanged ( self , track ) :
""" each track has only one pattern. We can identify the pattern by track and vice versa.
@ -163,7 +163,7 @@ class ClientCallbacks(Callbacks): #inherits from the templates api callbacks
def _trackMetaDataChanged ( self , track ) :
""" a low cost function that should not trigger anything costly to redraw
but some text and simple widgets . """
export = track . export ( )
export = track . export ( )
for func in self . trackMetaDataChanged :
func ( export )
callbacks . _dataChanged ( )
@ -182,7 +182,7 @@ from template.engine.api import callbacks
_templateStartEngine = startEngine
def updatePlayback ( ) :
#TODO: use template.sequencer.py internal updates instead
#TODO: use template.sequencer.py internal updates instead
cbox . Document . get_song ( ) . update_playback ( )
def startEngine ( nsmClient ) :
@ -193,6 +193,7 @@ def startEngine(nsmClient):
#Send initial Callbacks to create the first GUI state.
#The order of initial callbacks must not change to avoid GUI problems.
#For example it is important that the tracks get created first and only then the number of measures
logger . info ( " Sending initial callbacks to GUI " )
callbacks . _numberOfTracksChanged ( )
callbacks . _timeSignatureChanged ( )
callbacks . _numberOfMeasuresChanged ( )
@ -205,13 +206,14 @@ def startEngine(nsmClient):
session . data . buildAllTracks ( buildSongDuration = True ) #will set to max track length, we always have a song duration.
updatePlayback ( )
logger . info ( " Patroneo api startEngine complete " )
def _loopOff ( ) :
session . data . buildSongDuration ( ) #no parameter removes the loop
updatePlayback ( )
session . inLoopMode = None
callbacks . _loopChanged ( None , None , None )
callbacks . _loopChanged ( None , None , None )
def _loopNow ( ) :
now = cbox . Transport . status ( ) . pos_ppqn
@ -221,7 +223,7 @@ def _setLoop(loopMeasureAroundPpqn):
if loopMeasureAroundPpqn < 0 :
_loopOff ( )
return
loopStart , loopEnd = session . data . buildSongDuration ( loopMeasureAroundPpqn )
updatePlayback ( )
@ -267,19 +269,19 @@ def set_quarterNotesPerMinute(value):
elif value == " on " :
assert not session . data . tempoMap . isTransportMaster
#keep old bpm value. 120 bpm is default.
session . data . tempoMap . isTransportMaster = True #triggers rebuild
session . data . tempoMap . isTransportMaster = True #triggers rebuild
else :
assert value > 0
session . data . tempoMap . setQuarterNotesPerMinute ( value )
session . data . tempoMap . isTransportMaster = True #triggers rebuild
session . data . tempoMap . isTransportMaster = True #triggers rebuild
#Does not need track rebuilding
updatePlayback ( )
callbacks . _quarterNotesPerMinuteChanged ( )
callbacks . _quarterNotesPerMinuteChanged ( )
def set_whatTypeOfUnit ( ticks ) :
""" Denominator of Time Signature """
if session . data . whatTypeOfUnit == ticks : return
if session . data . whatTypeOfUnit == ticks : return
session . data . whatTypeOfUnit = ticks
session . data . buildAllTracks ( )
if session . inLoopMode :
@ -289,14 +291,14 @@ def set_whatTypeOfUnit(ticks):
def set_howManyUnits ( value ) :
""" Numerator of Time Signature """
if session . data . howManyUnits == value : return
if session . data . howManyUnits == value : return
session . data . howManyUnits = value
session . data . buildAllTracks ( )
if session . inLoopMode :
_loopNow ( )
updatePlayback ( )
callbacks . _timeSignatureChanged ( )
def set_subdivisions ( value ) :
if session . data . subdivisions == value : return
@ -456,18 +458,18 @@ def trackMergeCopyFrom(sourceTrackId, targetTrackId):
targetTrack . buildTrack ( )
updatePlayback ( )
callbacks . _trackStructureChanged ( targetTrack )
def trackPatternReplaceFrom ( sourceTrackId , targetTrackId ) :
if not sourceTrackId == targetTrackId :
sourceTrack = session . data . trackById ( sourceTrackId )
targetTrack = session . data . trackById ( targetTrackId )
copyPattern = sourceTrack . pattern . copy ( newParentTrack = targetTrack )
targetTrack . pattern = copyPattern
targetTrack . buildTrack ( )
updatePlayback ( )
callbacks . _patternChanged ( targetTrack )
callbacks . _patternChanged ( targetTrack )
def setSwitchScaleTranspose ( trackId , position , transpose ) :
""" Scale transposition is flipped. lower value means higher pitch """
@ -498,32 +500,32 @@ def insertSilence(howMany, beforeMeasureNumber):
updatePlayback ( )
def duplicateSwitchGroup ( startMeasureForGroup : int , endMeasureExclusive : int ) :
groupSize = endMeasureExclusive - startMeasureForGroup
insertSilence ( groupSize , endMeasureExclusive )
groupSize = endMeasureExclusive - startMeasureForGroup
insertSilence ( groupSize , endMeasureExclusive )
for track in session . data . tracks :
for switch in range ( startMeasureForGroup + groupSize , endMeasureExclusive + groupSize ) : #One group after the given one.
if switch - groupSize in track . structure :
track . structure . add ( switch )
track . structure . add ( switch )
if switch - groupSize in track . whichPatternsAreScaleTransposed :
track . whichPatternsAreScaleTransposed [ switch ] = track . whichPatternsAreScaleTransposed [ switch - groupSize ]
if switch - groupSize in track . whichPatternsAreHalftoneTransposed :
track . whichPatternsAreHalftoneTransposed [ switch ] = track . whichPatternsAreHalftoneTransposed [ switch - groupSize ]
track . whichPatternsAreHalftoneTransposed [ switch ] = track . whichPatternsAreHalftoneTransposed [ switch - groupSize ]
callbacks . _trackStructureChanged ( track )
session . data . buildAllTracks ( )
updatePlayback ( )
def clearSwitchGroupTranspositions ( startMeasureForGroup : int , endMeasureExclusive : int ) :
def clearSwitchGroupTranspositions ( startMeasureForGroup : int , endMeasureExclusive : int ) :
for track in session . data . tracks :
for switch in range ( startMeasureForGroup , endMeasureExclusive ) :
if switch in track . whichPatternsAreScaleTransposed :
del track . whichPatternsAreScaleTransposed [ switch ]
if switch in track . whichPatternsAreHalftoneTransposed :
del track . whichPatternsAreHalftoneTransposed [ switch ]
del track . whichPatternsAreHalftoneTransposed [ switch ]
callbacks . _trackStructureChanged ( track )
session . data . buildAllTracks ( )
updatePlayback ( )
updatePlayback ( )
def deleteSwitches ( howMany , fromMeasureNumber ) :
for track in session . data . tracks :
new_structure = set ( )
@ -650,35 +652,35 @@ def patternOffAllSteps(trackId):
track . buildTrack ( )
updatePlayback ( )
callbacks . _patternChanged ( track )
def patternInvertRow ( trackId , pitchindex ) :
""" Pitchindex is the row """
""" Pitchindex is the row """
track = session . data . trackById ( trackId )
track . pattern . invertRow ( pitchindex )
track . pattern . buildExportCache ( )
track . buildTrack ( )
updatePlayback ( )
callbacks . _patternChanged ( track )
callbacks . _patternChanged ( track )
def patternClearRow ( trackId , pitchindex ) :
""" Pitchindex is the row.
Index is the column """
Index is the column """
track = session . data . trackById ( trackId )
track . pattern . clearRow ( pitchindex )
track . pattern . buildExportCache ( )
track . buildTrack ( )
updatePlayback ( )
callbacks . _patternChanged ( track )
callbacks . _patternChanged ( track )
def patternRowRepeatFromStep ( trackId , pitchindex , index ) :
""" Pitchindex is the row.
Index is the column """
Index is the column """
track = session . data . trackById ( trackId )
track . pattern . repeatFromStep ( pitchindex , index )
track . pattern . buildExportCache ( )
track . buildTrack ( )
updatePlayback ( )
callbacks . _patternChanged ( track )
callbacks . _patternChanged ( track )
def patternRowChangeVelocity ( trackId , pitchindex , delta ) :
track = session . data . trackById ( trackId )