// Example of a one button standard looper. Second loop length will be the length of all other loops // Second loop length will be a multiple of first loop length // // Author: LoopToGo // // Arguments or user arguments : // 1 : (optional) gFirstTrack, track number to start the looping, default is 1 // 2 : (optional) gNbBars, number of bars For the first recording, default is 10 // // Warning when using with midi events, make sure "Use MIDI events as arg" is uncheck! loadScript Looptogo\aliases.txt // To use aliases instead of shortcut commands ///////////////////////////////////////////////////////// ///////////// For debugging // Note see LoopToGo\libs\debugUtilities.ltgl For details on how to use debugging loadScript LoopToGo\libs\debugUtilities.ltgl // Uncomment the following line to remove all debug prints. When uncommented, there is no impact on perfromance //alias debug doNothing // Set tag Info, Info2 and Info3 to 1 to print or 0 to not print debugTag Info 0 debugTag Info2 0 debugTag Info3 0 //alias debug print alias print debug Info [ $scriptLineNumber ] alias print2 debug Info2 [ $scriptLineNumber ] alias print3 debug Info3 [ $scriptLineNumber ] // Uses { and } to increment and decrement debug message alias { debugIncreaseIndentation alias } debugDecreaseIndentation print " " // new line! print "Start of script: " ///////////// End of debugging ///////////////////////////////////////////////////////// // Do not call this script when there is no track! if $nbTracks < 1 setUserArgs // reset the users args just in case! endScriptDynamic endIf // Refrain from calling this script twice in a short time (debounce of midi events below) variable deltaTime $sysTime - $gLastExecutionTime globalVariable gLastExecutionTime $sysTime //print2 $deltaTime $sysTime $gLastExecutionTime ///////////////////////////////////////////////////////// ///////////// Script configuration alias aDefaultFirstTrack 1 // The first track used for looping alias aDefaultNbBars 10 // Lenght of first record loop if not specified by $arg1 or $userArg1 alias aGridLineColor #224422 // Color for the grid lines alias aBeforeLoopEnd 0.02 // Increase to make the extend before the end of the loop! Must not be greater than 0.02!!! ///////////// End of configuration ///////////////////////////////////////////////////////// alias true 1 alias false 0 alias UnLockedState 0 alias LockedState 3 alias OverdubMode 6 alias RepeatRecord 2 // Looper States alias LooperStoppedAndEmpty 0 alias LooperStopped 1 alias LooperRecord 2 alias LooperPlay 3 alias LooperOverdubFirst 4 alias LooperOverdubSecond 5 // Track monitoring mode alias InLoopsOrWhileTrackSelected 3 // Debouncing : midi buttons can sen multiple events in a short period of time if $deltaTime < 200 print3 "Debouncing: " $deltaTime endScriptDynamic endIf // Code For pausing or resetting the looper with a double click. if $deltaTime < 500 print "Double click: " $deltaTime $gLooperState $isRecording if $gLooperState = LooperStopped loadScript LoopToGo\LooperEmulations\resetSong.ltgs // The user ask For stop twice to reset the looper endScriptDynamic endIf if $isRecording pause endScriptDynamic endIf endIf print deltaTime : $deltaTime print2 gLooperState Before : $gLooperState callFunction fctComputeLooperState // The looper state must be compute in case the user used Ctr-Z (undo) or Ctr-Y (Redo) print2 gLooperState : $gLooperState gFirstRecordLoopLength: $gFirstRecordLoopLength gSecondRecordLoopLength : $gSecondRecordLoopLength // If we are not starting from scratch, just make sure we have a jam marker print2 nbMarkers: $nbMarkers $gFirstRecordLoopLength $gSecondRecordLoopLength $gFirstRecordLoopID $gSecondRecordLoopID if $nbMarkers < 1 if $gSecondRecordLoopID print2 startJamMode $gSecondRecordLoopID startJamMode $gSecondRecordLoopID else print2 startJamMode $gFirstRecordLoopID startJamMode $gFirstRecordLoopID endIf endIf callFunction looperStateManager // Choose action depending on the actual looper state function looperStateManager { if $gLooperState = LooperStoppedAndEmpty globalVariable gNbBars aDefaultNbBars globalVariable gFirstTrack aDefaultFirstTrack if $nbUserArgs globalVariable gFirstTrack $userArg1 if $nbUserArgs > 1 globalVariable gNbBars $userArg2 endIf setUserArgs // Make sure user args a resetted else if $nbArgs globalVariable gFirstTrack $arg1 if $nbArgs > 1 globalVariable gNbBars $arg2 endIf endIf endIf callFunction fctInitAndStartRecording exitFunction endIf setUserArgs // reset the users args just in case! if $gLooperState = LooperRecord callFunction fctStopFirstRecording exitFunction endIf if $gLooperState = LooperPlay callFunction fctNewOverdubFirst exitFunction endIf if $gLooperState = LooperOverdubFirst callFunction fctStopExtendingSecondOverdub exitFunction endIf if $gLooperState = LooperOverdubSecond callFunction fctStopOverdubSecond exitFunction endIf if $isRecording callFunction fctStopOverdubSecond exitFunction endIf setBar $gFirstRecordLoopStart record // Start recording } endFunction // First initialization of variables and start of recording function fctInitAndStartRecording { print "fctInitAndStartRecording: " globalVariable gFirstTime true globalVariable gFirstRecordLoopID 0 globalVariable gInRecordLoop true globalVariable gLooperState LooperRecord globalVariable gFirstRecordLoopStart $songBar globalVariable gSecondRecordLoopLength 0 globalVariable gSecondRecordLoopID 0 selectTrack $gFirstTrack callFunction setTracksMonitoringMode // First record loop addRecordLoop $selectedTrack FirstLoop $gFirstRecordLoopStart $gFirstRecordLoopStart + $gNbBars setGridLinesVisibility 0 removeAllCustomGridLines addCustomGridLine $gFirstRecordLoopStart 3 aGridLineColor addCustomGridLine $gFirstRecordLoopStart + $gNbBars 3 aGridLineColor globalVariable gFirstRecordLoopID $lastCreatedRecordLoopID globalVariable gFirstLoopTrack $selectedTrack record // Start recording startJamMode $lastCreatedRecordLoopID } endFunction // Creation of the first overdubing loop function fctNewOverdubFirst { print "fctNewOverdubFirst: " setLoopLockState $lastCreatedRecordLoopID LockedState if $gSecondRecordLoopLength = 0 addRecordLoop $selectedTrack "Overdub" $gFirstRecordLoopStart $gFirstRecordLoopStart + $gFirstRecordLoopLength startJamMode setLoopJamState $lastCreatedRecordLoopID RepeatRecord getLoopEnd loopEnd $lastCreatedRecordLoopID globalVariable gSecondRecordLoopLength $gFirstRecordLoopLength // First time, will be the same length as the first record loop! globalVariable gSecondRecordLoopID $lastCreatedRecordLoopID variable arguments $lastCreatedRecordLoopID & " " & $gFirstRecordLoopLength print gFirstRecordLoopLength : $gFirstRecordLoopLength gSecondRecordLoopLength : $gSecondRecordLoopLength [ $arguments ] addFunctionMarker $gFirstRecordLoopEnd - aBeforeLoopEnd "Overdub" fctExtendLoopRange $arguments globalVariable gLooperFunctionMarkerID $lastCreatedMarkerID setMarkerColor $gLooperFunctionMarkerID #775544 print2 : gLooperFunctionMarkerID: $gLooperFunctionMarkerID else addRecordLoop $selectedTrack "Overdub" $gFirstRecordLoopStart $gFirstRecordLoopStart + $gSecondRecordLoopLength setLoopJamState $lastCreatedRecordLoopID OverdubMode // We only select the last record loop to be able to use the E shortcut (erase) unselectAllLoops selectLoop $lastCreatedRecordLoopID endIf } endFunction // Creation of the second overdubing loop and other subsequent overdub loops function fctNewOverdubSecond { print3 "fctNewOverdubSecond: " $gLooperState LooperOverdubFirst LooperOverdubSecond //globalVariable gLooperState LooperOverdubFirst if $nbMarkers > 1 // First time in the second overDub.Since there is a marker that extend the looght length we, continue overbubing but we stop the loop extent! print3 "fctNewOverdubSecond: nbMarkers > 1 " else // We don't use script markers, it means that it is not the first time we use a second overdub, we change to play!!! callFunction fctStopOverdubSecond endIf } endFunction // First stop of recording function fctStopFirstRecording { print "fctStopFirstRecording: " // We must compute the next start of the record loop which must be the start of the first record loop plus a integer number of the first record loop length globalVariable gFirstRecordLoopEnd $songBar globalVariable gFirstRecordLoopLength $gFirstRecordLoopEnd - $gFirstRecordLoopStart print $lastCreatedRecordLoopID $gFirstRecordLoopStart $gFirstRecordLoopEnd setLoopStartAndEnd $lastCreatedRecordLoopID $gFirstRecordLoopStart $gFirstRecordLoopEnd removeCustomGridLine $gFirstRecordLoopStart + $gNbBars addCustomGridLine $gFirstRecordLoopEnd 3 aGridLineColor setLoopLockState $lastCreatedRecordLoopID LockedState jumpTo $gFirstRecordLoopStart // More accurate than setBar!!! waitDelta .01 // Wait for the jump! startJamMode $lastCreatedRecordLoopID } endFunction // Stopping the extension of loop by deleting the Function marker responsible For extension function fctStopExtendingSecondOverdub { print "fctStopExtendingSecondOverdub: nbMarkers" $nbMarkers deleteAllMarkers 2049 // delete Function marker // Make sure we are overdubbing setLoopJamState $lastCreatedRecordLoopID OverdubMode } endFunction // Stop second overdubbing and subsequent function fctStopOverdubSecond { print "fctStopOverdubSecond: " setLoopLockState $lastCreatedRecordLoopID LockedState } endFunction // Determine the looper state based on recording state and loops state function fctComputeLooperState { print fctComputeLooperState Before : $gLooperState $gSecondRecordLoopID $gSecondRecordLoopLength variable previousLooperState $gLooperState globalVariable gLooperState LooperPlay ifNot $isRecording if $nbLoops = 0 globalVariable gLooperState LooperStoppedAndEmpty exitFunction endIf globalVariable gLooperState LooperStopped exitFunction endIf for loop 1 $nbLoops // We check all the loops in case the user deleted a loop or did Ctr-Z! variable loopID loopID & $loop getLoopNextJamState loopJamMode $$loopID getLoopLockState loopLockState $$loopID getLoopType loopType $$loopID if $loopType = Record print2 $gLooperState $loopJamMode $loopLockState $nbMarkers if $loopLockState = UnLockedState if $loopJamMode = OverdubMode if $previousLooperState = LooperOverdubFirst globalVariable gLooperState LooperOverdubSecond exitFunction //Found, no need to continue searching! endIf if $previousLooperState = LooperOverdubSecond globalVariable gLooperState LooperOverdubSecond exitFunction //Found, no need to continue searching! endIf if $nbMarkers < 2 // No Function markers, we are in last overdub mode globalVariable gLooperState LooperOverdubSecond exitFunction //Found, no need to continue searching! endIf globalVariable gLooperState LooperOverdubFirst exitFunction //Found, no need to continue searching! endIf ifNot $gFirstRecordLoopID = $lastCreatedRecordLoopID globalVariable gLooperState LooperOverdubFirst exitFunction //Found, no need to continue searching! endIf globalVariable gLooperState LooperRecord exitFunction //Found, no need to continue searching! endIf endIf endFor } endFunction // Set all tracks Play Record and Pause monitoring mode to "In loops or when track is selected" function setTracksMonitoringMode { print "setTracksMonitoringMode: " for track 1 $nbTracks setChainRecordPlayMonitorMode $track InLoopsOrWhileTrackSelected endFor } endFunction ////////////////////////////////////////////////////////// alias print print // We must reset the print aliases because it refers to a functions in the debug library which will noy be accessible from the function // This Function is designed to be called by a FunctionMarker // It does have access to the global variables but not to the othe local variables in this file!!!! function fctExtendLoopRange // recordLoopID incrementWidth ifNot $nbArgs = 2 print fctExtendLoopRange requires 2 arguments [ $nbArgs : recordLoopID "=" $arg1 incrementWidth "=" $arg2 ] exitFunction endIf getLoopJamState loopJamMode $arg1 // The first time, the loop will be in record mode, we just set it in overdub mud // The second time, the loop will be in overdub, we move the marker and extend the loop! if $loopJamMode = OverdubMode variable newEnd $gFirstRecordLoopStart + $gSecondRecordLoopLength + $arg2 addPlayLoop $gFirstLoopTrack $gFirstRecordLoopID $gFirstRecordLoopStart + $gSecondRecordLoopLength $newEnd //Always on track1 setLoopStartAndEnd $arg1 $gFirstRecordLoopStart $newEnd getLoopEnd playLoopEnd $lastCreatedPlayLoopID // Move script markers just before the end setMarkerBar $gLooperFunctionMarkerID $newEnd - aBeforeLoopEnd globalVariable gSecondRecordLoopLength $newEnd - $gFirstRecordLoopStart addCustomGridLine $newEnd 3 aGridLineColor endIf setLoopJamState $arg1 OverdubMode setMarkerName $gLooperFunctionMarkerID "Extend" setMarkerColor $gLooperFunctionMarkerID #335577 endFunction