How to detect and act on only the final value of a widget knob twist

Thanks to all who assisted above!

I have arrived at a scriptlet that works well for me.

Here it is:

/*
    Scriptlet:  PC Knob Final Value 01a   (Sends PCs)
    
    Written to pair with a knob widget, an Incr widget, and a Decr widget
    
    This code always sends the final value for the connected knob, but not all the values in-between as the knob is turned.
    
    This can be very helpful if gear downstream doesn't respond all-so-well to a blast of multiple program change messages (PCs).
    
    Note: Results are timer-based.  if you twist the connected widget knob slowly, then some intermediate values will go out at
    intervals of SnapShot_Time_ms.  SnapShot_Time_ms is a Parameter, so you can control it also via widge if you like, or else 
    just accept the value compiled from the code here.
    
    Use Case #1:   Sending PCs to BIAS FX plugin to select guitar patch presets
    
    01a (Progster, 20240916)    Initial version    
    
*/

var
   
	ProgramChangeNumber ("Program"): Subrange Parameter 0 .. 127 = 0
	Decr : Parameter 0..1 = 0   
    Incr : Parameter 0..1 = 0 
    
    //  specify a nominal 500ms ramp  - we will wait for it's completion for-to-send the PC    
    SnapShot_Time_ms : Parameter 0..2000 = 500   
	
	Last_PC_Sent : Integer = 0
	
	PC_Ever_Sent : Boolean = False
	Waiting_For_Ramp : Boolean = False
	
	MyRamp  : Ramp
	
	Ramp_Start_Time: Double
	Ramp_End_Time: Double
	Ramp_Elapsed_Time : Double


function SendPchange( PC : Int )

    if ( PC <> Last_PC_Sent ) then                  // never send the same PC twice in a row
        //Print( "Called SendPchange: " + PC )
        SendNow( MakeProgramChangeMessage(PC) )     // PC message on Ch 1
	    Last_PC_Sent = ProgramChangeNumber    
        Print( "Last_PC_Sent: " + Last_PC_Sent )
    end
	
end


On GeneratorEndCycle(timeX : integer) from MyRamp

    Ramp_End_Time = TimeSinceStartup()
    Ramp_Elapsed_Time = Ramp_End_Time - Ramp_Start_Time
    //Print( "Ramp Finished: " + TimeSinceStartup() + "   Ramp Elapsed time: " + Ramp_Elapsed_Time )
    
    // Send Out PC message
    SendPchange( ProgramChangeNumber )      //  ProgramChangeNumber is always most current one as provided by the connected knob widget 
        
    //  reset to "neutral" state
    Waiting_For_Ramp = False
    
End


//  ParameterValueChanged callbacks

On ParameterValueChanged matching ProgramChangeNumber    
	
    //  If in the "neutral" state, start a new Ramp to wait for
    if ( !Waiting_For_Ramp ) then
        Ramp_Start_Time = TimeSinceStartup()
        TriggerOneShotRamp(MyRamp, SnapShot_Time_ms, 10)         
        //Print( "Ramp Started: " + Ramp_Start_Time + "   SnapShot_Time_ms: " + SnapShot_Time_ms )
        Waiting_For_Ramp = True
    end	
	
End

//  Act on change of connected widget used for Increment of preset
On ParameterValueChanged matching Incr
    ProgramChangeNumber = Last_PC_Sent
    //Print( "ParameterValueChanged matching Incr " + Incr )
    if (Incr == 1) and (Last_PC_Sent < 127) then
        //Print( " Incr button" )
        ProgramChangeNumber = ProgramChangeNumber + 1
		SendPchange( ProgramChangeNumber )
		Last_PC_Sent = ProgramChangeNumber
	end
End

//  Act on change of connected widget used for Decrement of preset
On ParameterValueChanged matching Decr
    ProgramChangeNumber = Last_PC_Sent
	//Print( "ParameterValueChanged matching Decr " + Decr )
    if (Decr == 1) and (Last_PC_Sent > 0) then
        //Print( " Decr button" )
		ProgramChangeNumber = ProgramChangeNumber - 1
		SendPchange( ProgramChangeNumber )
		Last_PC_Sent = ProgramChangeNumber
	end
End   

And here is a short video demo of it in action:

4 Likes