Home Forums General Programming Is it possible to prevent running the OnModulatorValueChange method?

This topic contains 8 replies, has 4 voices, and was last updated by Puppeteer Puppeteer 1 week, 5 days ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #68792
    goodweather
    goodweather
    Participant

    Hi,
    I’d like to know if it is possible and how to prevent the OnModulatorValueChange method to be run.
    Is it with the force bool in setValue(value, force)? Setting the force bool to false I mean.
    Or shall I use setModulatorValue(value, vst, midi, ui) where according to the documentation only the midi bool is working and where I don’t see a way to prevent the change method to be run?

    I have the issue because I have a toggle button On/Off that affects a Slider with 32 positions but that Slider can itself affects the On/Off button if it is set on position 0. The user can thus use both.
    I have also other cases where this could be useful.

    Thx!

    #68794

    dasfaker
    Participant

    You can set a variable at the beginning of the OnModulatorValueChange script.

    if locked == 0 then
        -- execute your code here
    end

    Then set this variable to 1 whenever you want to change this modulator value without triggering OnModulatorValueChange code.

    #68795
    goodweather
    goodweather
    Participant

    Thx! Simple…
    I’ll use that if nobody (Atom…) comes with a Ctrlr built-in way of doing this

    #68830
    Possemo
    Possemo
    Participant

    I had the same prob. When getting a patch from the synth, all OnModulatorValueChange scripts would execute (which I did not want to happen). As OnModulatorValueChange executes AFTER the MidiMessageReceived-script I found no way to prevent this. My solution: MidiMessageReceived changes all sliders-scripts to “OnMouseDrag”. You can set it back manually to ValueChange with a button.

    #68835
    goodweather
    goodweather
    Participant

    Hi Possemo! That one I solved since some time…
    I’m not using MidiMessage Received at the moment.
    What I’m doing:

    • at the beginning of the LoadProgram method, I’m setting a flag bLoadingProgram to true
    • in each OnMOdValueChange methods, I’m testing for that flag as I’m also testing for the classical isPanelReady
      -- No action while loading a program or if the panel is in bootstrap or program states
      if bLoadingProgram or not isPanelReady() then
      	return
      end
    • at the end of the LoadProgram method, I’m starting a timer like:
      -- Starting a timer to reset bLoadingProgram to false after that all modulators have processed their OnChange function
      	timer:setCallback (1, timerCallback)
      	timer:startTimer(1, 200)
      
    • And I have a timer method like
      function timerCallback(timerId)
      
      --Osc1Shape_OnChange(modOsc1ShapeNoise, LoadedProgramData:getByte(12))
      bLoadingProgram = false
      timer:stopTimer(timerId)
      
      txtCurrentValue:getComponent():setPropertyString ("uiLabelText", "LOADED")
      
      end
    • Here, I solved it with just another boolean (as dasfaker proposed and what was also my option without any Ctrlr alternative).
      I’m now also using the source argument of the OnChange method (if =2 then it is coming from the synth).

    #68841
    Possemo
    Possemo
    Participant

    Thank you goodweather. I have no experience with timers, looks like a much nicer way than mine.

    #69117
    Possemo
    Possemo
    Participant

    I finally tried it out. This is awesome, it’s working perfectly.

    I don’t understand this line:
    txtCurrentValue:getComponent():setPropertyString (“uiLabelText”, “LOADED”)

    I see that it will fill an uiLabelText with the text “LOADED” but what is txtCurrentValue? You dont’t need to hurry to answer, this is just cosmetic 🙂

    Thanks again!

    #69123
    goodweather
    goodweather
    Participant

    Good!
    txtCurrentValue is indeed a uiLabel that is displaying the current value of the currently modified parameter or other information as “LOADED” or “READY”. You can see it on attached picture (I also change the txtInformation to show the manual extract and lblCurrentValue to show the value boundaries.

    About timers, you can put multiple timers within the same timerCallback method. Just use timerid to make the difference between them. This is useful to perform different “post timer” processing as in following code:

    --
    --	All timer related functions
    --
    function timerCallback(timerId)
    
    	-- Loading program timer
    	if timerId==1 then	
    		bLoadingProgram = false
    		timer:stopTimer(timerId)
    		txtCurrentValue:getComponent():setPropertyString ("uiLabelText", "LOADED")
    
    	-- Loading panel timer
    	elseif timerId==2 then
    		bPanelLoaded = true
    		timer:stopTimer(timerId)
    		panel:getComponent("Pro2Tabs"):setProperty ("uiTabsCurrentTab", 0, false)
    		lblParameter:getComponent():setPropertyString ("uiLabelText", "Welcome - DSI Pro2 Ctrlr panel v0.14")
    		sWelcome = "Due to sysex format, this panel is foresseen to be used with a DSI Pro2 OS 1.1.0. It may however work with more recent versions of the OS as well."
    		sWelcome = sWelcome.."\nA bug in 1.1.0 prevents setting global parameters to their maximum value via Midi. This has been corrected in OS 1.2.0.2"
    		sWelcome = sWelcome.."\nVariables read from stateData... Panel loaded and modulators assigned..."
    		sWelcome = sWelcome.."\nClick on any button label to get information or just change any parameter..."
    		txtInformation:getComponent():setPropertyString ("uiLabelText", sWelcome)
    		txtCurrentValue:getComponent():setPropertyString ("uiLabelText", "READY")
    
    	-- Loading receiving program timer
    	elseif timerId==3 then	
    		timer:stopTimer(timerId)
    	end
    
    end
    Attachments:
    You must be logged in to view attached files.
    #73481
    Puppeteer
    Puppeteer
    Participant

    I’m including this for info on another possible way to address this, though it’s a major restructure for most panels.

    In the panel I’m working on, I’m limited to doing sysex dumps to modify the synth’s edit buffer. I need to restrict bandwidth or I’ll crash the synth.

    I ended up setting up a button to put the panel in “control mode”, which just starts a timer.

    Inside the timer loop I maintain a memoryblock, and the previous copy of the memoryblock (tables also work) with all the values of the sysex dump. Each time the callback is triggered, I scan all of the ctrlr modulators, comparing them to the value in the previous memoryblock. If the memoryblock has changed, I send out MIDI, and update the previous memoryblock, with the new one (ie I have 2 variables called midiBuffer and lastMididBuffer).

    In the onChange method for each ctrlr modulator I update a flag called bufferChanged which I can use to see if something has changed, from within the timer loop. I change this back to false on each scan of the modulators, or I can switch it off if I need to do something such as load a patch into ctrlr, or manage sysex dumps.

    Also I make sure that dumps can’t be requested while in the control mode, so you can do whatever you want with the modulators while not in control mode and nothing will be sent to the synth.

    Importantly I scan the control mode button. If it gets turned off, it stops the timer.

    It’s a very different way of controlling stuff, but affords a lot of control over panel changes and bandwidth.

    Also, thankyou so much Goodweather for the method for tracking multiple timers. It’s a very elegant method for keeping track of multiple timers and I wouldn’t be able to have my panel working without a similar approach.

    • This reply was modified 1 week, 5 days ago by Puppeteer Puppeteer.

    The Puppeteer
    http://godlike.com.au

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.

Comments are closed.