Forum Replies Created
-
AuthorPosts
-
I didn’t use radio buttons but used classical uiImageButtons (2 images – On and Off states) that are all in the same RadioGroup property number (+ Component is member of a group).
Name your buttons as for example Bank1 to Bank16.
When you will toggle one ON, the others are toggled OFF immediately.
This is when you are acting on the panel.Then in Lua, if you need to set one of them ON (for example after recieving and reading a patch dump), I set first all of them to OFF then the desired one to ON by using (I have 2 radiogroups, one for Banks and one for Presets – Moog Sub37):
-- Illuminate corresponding Bank and Preset buttons for i=0,16 do btnBank = panel:getModulatorByName("btnBank"..i) btnBank:setValue(0,false) btnPreset = panel:getModulatorByName("btnPreset"..i) btnPreset:setValue(0,false) end btnBank = panel:getModulatorByName("btnBank"..PresetBank) btnBank:setValue(1,false) btnPreset = panel:getModulatorByName("btnPreset"..PresetNumber) btnPreset:setValue(1,false)
To read them, you can have one unique OnChange method for all. The same method will be called but has the changed modulator as argument “mod”. You set a Lua variable iSelectedBank by using
if value == 1 then sName= L(mod:getName()) iSelectedBank = tonumber(string.sub(sName,1,2)) end
As 2 modulators will change their value (one going to 1, the other to 0), you need to test for the one going to 1).
Please try and let us know… π
Got you! Tried it just now and it works fine (I set the timer to 150ms to be safe)!
One learns every day πThx dasfaker. Saw the same procedure in Carl’s P08 panel.
Can you explain a bit more (it is about the same as I did but I used a loop doing the 2 first lines above (starting timer)?
So, the main method starts the timer only once.
Then the timer is looping by itself 128 times??? No need for any classical loop (sorry I’m a classical programmer)?For my Pro2, a bank is 116622 and there is no problem sending that with MidiOX. Anyway I can also send the 99 programs one by one.
Anyway, tried to do this without success (only the 3 programs got sent).
Also tried with a timer but it didn’t help.
Can you please explain the principle?where to have the loop? in the BankSend button method?
where to prepare memory block with the program? in the BankSend button method?
Where to put the timer? within the loop?
If starting a timer, shall I stop it for each program or stop it at the end?
In the timer, I put
mbProgram = MemoryBlock()
mbProgram = mbUser1:getRange(iCounter*1178,1178)
msgBank = CtrlrMidiMessage(mbProgram)
panel:sendMidiMessageNow(msgBank)Thx to point me to some example. I already tried different things without any success.
Hi Atom, work and personal life are more important. Take your time and we are definitively already all grateful for what you have done so far.
Cheers from Belgium…DominiqueThx. I’ll try that.
For the moment, I did something similar by requesting a Global parameters dump of 55 bytes but using your method will be better as I can test that any time.
I was indeed looking for something more robust as one can have different cases:
- synth not switched on when Ctrlr is started
- synth switched on after ctrlr is started
- synth switched off while panel is still open
The list of devices is a source of info but the best way to secure good communication would be to test your universal sysex exchange before each program/bank communication with the synth (I will not do this at param level).
May 2, 2016 at 8:16 am in reply to: Is it possible to prevent running the OnModulatorValueChange method? #69123Good!
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.It is working now. Thanks dasfaker, you put me on the way π
Explanation: stateData is saving strings so you need to convert objects like memoryblock to a string but on restore also do the opposite.
I saw this because when using toHexString on Save stateData it didn’t work and by using what(LoadedProgramData) I saw it was a string…So:
- For memoryblock save, use
stateData:setProperty (βLoadedProgramDataβ, LoadedProgramData:toHexString(1), nil)
- For memoryblock restore, use
LoadedProgramData = MemoryBlock() LoadedProgramData:loadFromHexString(stateData:getProperty("LoadedProgramData"))
I’ll add this in the Step by Step guide 2.0 as it is needed by panel makers…
Welcome Markus. Maybe you will find what you need in my Step by Step Guide on p15 and 16…
Can someone help me with stateData and Memoryblock save/restore?
I don’t succeed to get a memoryblock cakked LoadedProgramData to be saved and restored (always empty)…Is there a special way to save and restore a memoryblock in stateDate?
In a method used to load a program I have
LoadedProgramData = utils.unpackDsiData(Pro2PackedProgramData:getRange(6,1171))
and it works fine; all modulatros are well initialized using the appropriate getByte methods as
modOsc1Sync:setValue(LoadedProgramData:getByte(52), true)I have a SaveStateData method in “Called when Ctrlr state is saved”
SaveStateData = function(--[[ ValueTree --]]stateData) -- Variables to be saved stateData:setProperty ("LastBank", LastBank, nil) stateData:setProperty ("LastProgram", LastProgram, nil) stateData:setProperty ("LoadedProgramData", LoadedProgramData, nil) stateData:setProperty ("CurrentOsc1Wave", iCurrentOsc1Wave, nil) stateData:setProperty ("CurrentOsc2Wave", iCurrentOsc2Wave, nil) stateData:setProperty ("CurrentOsc3Wave", iCurrentOsc3Wave, nil) stateData:setProperty ("CurrentOsc4Wave", iCurrentOsc4Wave, nil) stateData:setProperty ("Disk1FullPath", sDisk1FullPath, nil) stateData:setProperty ("Disk1FileName", sDisk1FileName, nil) end
I have a ReadStateData in “Called when Ctrlr is loaded”
ReadStateData = function(--[[ ValueTree --]] stateData) -- Variables to be read LastBank = stateData:getProperty("LastBank") LastProgram = stateData:getProperty("LastProgram") iCurrentOsc1Wave = stateData:getProperty("CurrentOsc1Wave") iCurrentOsc2Wave = stateData:getProperty("CurrentOsc2Wave") iCurrentOsc3Wave = stateData:getProperty("CurrentOsc3Wave") iCurrentOsc4Wave = stateData:getProperty("CurrentOsc4Wave") sDisk1FullPath = stateData:getProperty("Disk1FullPath") sDisk1FileName = stateData:getProperty("Disk1FileName") LoadedProgramData = MemoryBlock() LoadedProgramData = stateData:getProperty("LoadedProgramData") end
LoadedProgramData:getSize() is giving an error “Attempt to call method ‘?’ a (nil value)” so LoadedProgramdata is probably not a memory block or is nil…
Hi Poss, can you open another post with this question so we can continue the discussion there?
Quick answer: can be easily fixed by adding a number of loops (each loop adds 2 segments) between Release level (at 0 on your graph but not always 0) and the Sustain level then back to Release level.Hi,
how is the progress bar component working? Can someone provide an example?
Didn’t see any related function in Ctrlr source code…
If no answer in a while, I’ll just use the classical way with 2 rectangles on each other and changing the length of the top one based on % completion…Thx!
Thank you but actually I have also used them but adapted them further to be fully flexible in size (height/width) instead of having to modify the code and to handle a variable number of segments π
Plan was to re-create a panel just containing them with some explanations but I didn’t find the time yet.I did this for the SUB37 panel but also now on my Pro2 panel (and there are 5 of them).
This will of course be added in the Guide 2.0
Attachments:
You must be logged in to view attached files.Google is our friend π
The following codepackage.config:sub(1,1)
gives the separator in path names.
So it returns \ for Windows and / for Mac and Unix.
Another way can be to test the existance of key directories as I thought above (/Applications for MAC OS, /home (after trying MAC OS) for GNU/Linux and finally C:/Windows and C:/WINNT).OR another workaround, can we test for the existence of some unique file or folder?
On Windows, we should have some “Windows” folder On a Mac you have… (I don’t know, never used a Mac – my apologizes the Mac users π )After another look at this issue, it seems that on OSX, the fonts imported have to be used in bold style to be displayed correctly, while on Windows they have to be normal.
On Win: font:setSizeAndStyle(14, 0, 1, 0)
On OSX: font:setSizeAndStyle(14, 1, 1, 0)Is there a way to deal with this?
Is there a way to check that we are on Windows or on OSX? If we can test this then we can adjust the font accordingly.
Anyway thx for this topic, I have already a couple of guys who want to test my panel on OSX and myself I’m using Win…While waiting to get an answer to my questions in the previous post, I made a test panel for stateData and it works indeed exactly as dasfaker mentioned:
- keeping the panel open and closing Ctrlr saves the stateData
- closing the panel and re-opening it doesn’t save the stateData
Feel free to try with attached panel. You can edit 2 labels, 1 push button and one rotary button. You can also reset the stateData values to see that they are indeed changing.
One way to force the user to close Ctrlr is to hide the panel menu…
Does anyone have some other suggestion?Attachments:
You must be logged in to view attached files.Thx for your kind words, Poss!
Yep, I’ll add a lot of Lua stuff into the 2.x version of the guide and in my panel I put a lot of comments as well.
I know what to write, etc… Just a matter of priority and time.
I think I’ll work on it during summer vacations or earlier if my Pro2 panel gets correct enough to be published (I’m now working on initial setup with stateData, Save and on the librarian)Thx.
Q1: For other data than modulators, I will create the 2 methods you indicate (and descrive very well above). As closing the panel don’t save stateData, is it somewhere an OnPanelClose method to force the saving of the stateData?
I was planning to use methods for Reading/Writing .ini file containing different settings but I’ll try this way instead. Seems easier BUT I want to be sure to have the last values of my variables saved so they can be restored at next panel open.Q2: For all modulators data, is there a way to prevent restoring the modulators state (or better, to be able to control the restore or not restore of modulators state)?
The difference of behaviour you mention above (quit Ctrlr or just close panel) is maybe in relation with my issue that all my OnChange methods are triggered (see http://ctrlr.org/forums/topic/order-of-events-when-loading-a-panel/)
Related question: I see 2 method types in Ctrlr when adding a method. luaCtrlrRestoreState and luaPanelRestoreState (same for Save).
What are the difference between them and which one should be used where?
There is the setting in Preferences and there is the setting at Panel level which seems to be the same.The panel tree is not flushed to disk with every save, itβs only updated in memory, if you want to flush it to disk you do save ctrlr state (this is the equivalent of saving your project when host ctrlr as a VST). This is done for performance reasons.
Hi Atom and dasfaker,
can we be more precise here?
Let’s imagine we have a user of a panel and the developer has foreseen a way to store some key values (last used sound and bank for example) in statedata.
What should the programmer do (what to write and where) to secure that this data is saved when the user close the panel or quit Ctrlr and what should the programmer do to secure that this is loaded into variables and that the variables containing the key values can be used at panel opening.
I think that with that precision, the statedata read/write will be better understood.
Thx to both! -
AuthorPosts