MSuperLooper: momentary widgets to show state of loops

So I’ve updated the posted code to include a position marker bar and a warning loop end Indicator
I tried a few ways around this; First using a timer to store increments, but the callback is asynchronous, so cannot be used.
I then tried using TimeSinceStartup () but again the async timer callback allowed it to drift when trying to reset the Increment
In the end I just used the Timer callback as an event handler and used the TimeSinceStartup to store a free running accumulator which I can store no of loops and loop inc.
I’ve left this running for a few hrs and it seems to stay locked to the Msuperlooper Loop
I only needed one master timer, but it would be fairly trivial to stick some in arrays and have one for each track. I’ve not trapped double overflow but I don’t need the loops to run that long in songs.
hope it helps someone.
the Two extra widgets are MSloopWarn and MSloopPosition.
Guess the same principle can be used for other time tracking Ideas.
Some of the code is included from a OSC Heartbeat I use to link to TouchOSC, please Ignore.


//------ loop timers --------
var loopSetStatus : Boolean = false
var lStart : Double = 0.0
var lTime : Double = 0.0
var lPer : Integer = 0

//-------- Timers ----------------
var myMessage :String

var myMidiMess : MidiMessage
var i:Double = 0
var FlipFlop :Double = 0
Var ClockGen : Ramp
Var LoopProgress : Ramp
Var iTmp :Integer = 0
var lastTstamp : double = 0
var cummTime : Double = 0

// var for loop position
var currTime : double = 0
var lastTime : Double = 0
var aLoops : Double
var nLoops :double
var lInc : Double
// reset position widgets
Function ClrTrkData(TrkNo:integer)
// clear position data
SetWidgetValue(MSloopWarn, 0) // reset warn led
SetWidgetValue(MSloopPosition, 0) // reset position
loopSetStatus = false
End

Initialization
ClrTrkData(0)
SetTimersRunning(false)
SetGeneratorOneShot(ClockGen,false)
SetGeneratorFrequency(ClockGen,1)
EnableGenerator(ClockGen, true)
SetGeneratorOneShot(LoopProgress,false)
SetGeneratorFrequency(LoopProgress,5) // ten per second
EnableGenerator(LoopProgress, true) // start loop timer
SetTimersRunning(true)

End

//-------------------- M SUPERLOOPER --------loop status ---------------------------------------

// Called on Looper reset all
On WidgetValueChanged(nVal : double) from MSloopReset
ClrTrkData(0)
cummTime = 0
End
// Called on track reset
On WidgetValueChanged(nVal : double) from MSloopTrkReset
ClrTrkData(0)
cummTime = 0
End

// ---- calc loop Time
On WidgetValueChanged(newValue : double) from MSloopRecord
var sTime: double = TimeSinceStartup()
var trk : double = 0
if loopSetStatus == false then // no loop defined yet
if newValue == 1 then lStart = sTime end
if newValue == 0 then
lTime = sTime - lStart
cummTime = 0
loopSetStatus = true // loop done
end
end // loopstatus
End
// ------------Process Loop Status -------------------
On GeneratorEndCycle(x:Integer) from LoopProgress
currTime = TimeSinceStartup()
if lastTime == 0 then lastTime = currTime end
cummTime = cummTime + (currTime - lastTime)
aLoops = (cummTime / lTime) // accumulated loops and inc time
nLoops = Floor(cummTime / lTime) // no of loops done
lInc = aLoops - nLoops // incremnent in current loop
//lPosn = lPosn + lInc
if loopSetStatus == true then
SetWidgetValue(MSloopPosition, lInc)
if lStart > 0 then
lPer = Floor(lInc * 100)// 0 to 100 for position of loop
if lPer < 10 then SetWidgetValue(MSloopWarn, 0) end // turn of warn if less than 10
if lPer > 90 then SetWidgetValue(MSloopWarn, 1) end // turn on warn if > 90% done
end
end
lastTime = currTime
End

1 Like