Home › Forums › General › Programming › Getting Panel reflect Patch & Program Settings
- This topic has 7 replies, 3 voices, and was last updated 3 years, 1 month ago by
BAUS.
-
AuthorPosts
-
October 3, 2020 at 9:55 pm #120119
As some already know I am working on a Panel for the Ensoniq Mirage. It’s almost finished and at this moment it is a ‘one way’ editor, which is already very useful.
It would be great if I could understand how to get to the point to get the Panel to reflect the Patch and Program Settings. It’s working with requesting just 1 Parameter and that’s very cool to see.
Dnaldoog, Tedjuh and Goodweather already helped out. I checked out their JD-990 and Pro-2 Panels to see what they did. However I feel like an illiterate trying to read an encyclopedia. Yes…I have no clue.
So, to start off:
When I send a Patch request to the Mirage it returns a 148byte sysex string. It sends this nibbelized and I need to denibbelize it so that it creates a value for the Modulators… i.e 0F 01 needs to become 1F.
Dnaldoog gave me a denibbelize code for Lua but how/where do I implement this?
Updating a 25 year old Editor
October 4, 2020 at 11:08 am #120126Hi Baus,
First you would need to determine at the positions of the two 4bit bytes in the incoming MIDI message. Remember to count from
F0
as zero.These two bytes will be converted to a number, for example
0F 01
is converted to1F
which in decimal is31
as you know.Create a function that processes the 148 byte MIDI message. You can filter out other incoming midi strings:
receiveMidiFromDevice = function(--[[ CtrlrMidiMessage --]] midi) if midi:getSize()==148 then updateModulators(midi) - only run function if incoming MIDI = 148 end end
In that
updateModulators()
function, create a hash table of all the modulator names you want to assign values to:
The key refers to the modulator name and the value to the position of the leading byte in the MIDI message.local t={dial1=8,dial2=10,dial3=12}
In the function you pass :
local b1=m:getData():getByte(v) local b2=m:getData():getByte(v+1)
..as two arguments to the 4 bit denibbilize function:
† It is possible to use getRange(t.dial1,2) and pass one argument to a function but we won’t go there
That function will return the value which you then assign to the modulator.
function combine4n(a, b) -- convert two 4 bit nibbles to a single integer local m = bit.lshift(a, 4) return m + b end
In that
updateModulators()
function, loop through the table to assign values to the modulators:function updateModulators(m) local t={dial1=8,dial2=10,dial3=12} for k,v in pairs (t) do local b1=m:getData():getByte(v) local b2=m:getData():getByte(v+1) local value=combine4n(b2,b1) panel:getModulatorByName(k):getComponent():setValue(value,true) end end
*NOTE: it is possible that this may in turn cause the modulator to fire off a send MIDI message, but I haven’t addressed that issue here. Also the code
panel:getModulatorByName(k)
can be assigned to a lua variable on start as previously discussed in another post.See attached panel.
Regards,
JG
-
This reply was modified 3 years, 1 month ago by
dnaldoog. Reason: removed unnecessary variable
-
This reply was modified 3 years, 1 month ago by
dnaldoog. Reason: removed another unnecessary variable
Attachments:
You must be logged in to view attached files.October 4, 2020 at 4:47 pm #120132Woauww dnaldoog! This is support 🙂
@BAUS, please try the above.
I’m using another method (memoryblocks instead of tables) but don’t want to confuse you.
If needed, just ask 😉October 5, 2020 at 2:02 am #120139Thanks Goodweather,
A short reply was not possible!
I thought of explaining
MemoryBlock()
but that’s another complication as you said.A lot of this code is taken from a panel I am doing for the Zoom RFX 2000, which is turning out to be more difficult than I thought, but it actually uses MemoryBlock() everywhere. Everything is 4 bit nibbles msb,lsb in the Zoom RFX 2000 and every MIDI message is 83 bytes, so I condense that combine4n(b2,b1) into a MemoryBlock() single byte each time.
Regards,
October 6, 2020 at 11:49 pm #120157Alright…..this is very cool!
Thanks for the step-by-step explanation. That’s what I need. Although I don’t know yet what some things mean I now can see the bigger picture….I think.
You create a function that calls another function…or two or more.
I managed to get it to work. First on the Patch level….then I added the elseif for the size of the received Midi of the Program Dump from the Mirage and that one now also works.
Now that we have that working I am thinking about how to put it effectively in the Panel. I could add 32 buttons each sending a dump request for the correspondent Program…but I think this could be embedded in the Lua script as well.
Same thing for the Patch request…I could add 42 buttons for the Patch request but I think there could be a more effective way of doing this. The COMBO is what I tried. For Patch changes it works, I think because this sysex string uses lsb/msb but the Dump Requeat does not.
I will have a look at it again in the morning.
JG….Thanks so much for showing me how to read.
Goodweather….I am interested in your way of using the memoryblock method as well at a later time. As you mentioned it may only confuse me at this moment.Grateful for your help,
Robin.
-
This reply was modified 3 years, 1 month ago by
BAUS.
Updating a 25 year old Editor
October 7, 2020 at 11:39 am #120159Update on my last post:
I figured out how to do this much easier.
The request string for a Program is F0 00 00 23 01 06 01 F7….where 06 is the Parameter to request a dump and 01 the value.
When I put this in a COMBO it does not work. But…when I actually nibblize the value into two bytes then the COMBO does work, and that’s good.
EDIT: This works from selection 1 through 15. At 16 the Mirage does not return anything. Then at selection 17 it starts to return at 02 again.
-
This reply was modified 3 years, 1 month ago by
BAUS.
Updating a 25 year old Editor
October 7, 2020 at 9:04 pm #120164I think you should use another simpler method for requesting your programs. I will describe it here in a generic way and you need to adapt what I write to your specific sysex request program string.
The example is for the Korg Prologue that I just did.1. Create a uiImageSlider modulator with a nice button look as image.
Set Values 0-99 for example if the Mirage has 100 programs.
This is used to decide the program to load
2. Create a uiIMageButton modulator (2 images) and set Called when modulator value changes to a method “Receive_OnChange”
In that method you should have a code similar to this one:iProgram = modProgramSelector:getModulatorValue() local iMSB = math.modf(iProgram/128) local iLSB = iProgram - iMSB * 128 msg = string.format("F0 42 30 00 01 4B 1C %.2x %.2x F7", iLSB, iMSB) panel:sendMidiMessageNow(CtrlrMidiMessage(msg))
modprogram has been declared at panel opening as modProgramSelector = panel:getModulatorByName(“ProgramSelector”)
you can also do this in this method but it is less good3. Define a MidiMessageReceived method that will be used to receive and process incoming midi messages
if size = xxx then use dnaldoog’s method to store and update your modulatorsOctober 12, 2020 at 10:20 pm #120285Alright…..
Thanks goodweather!
Actually to request a Patch Dump I did not need to nibblize at all. Each Patch from 1 to 48 is just $01 to $30….so…at first I made 48 Buttons each with their own sysex string to request the wanted Patch.
Then I was looking through some other posts and I found something else, which I also implemented, and then I found that I could give each Value in a Combo it’s own sysex string. So….I ended up deleting the 48 buttons and now I have a Combo to select Patches which also immediately request the Patch Dump.
The space where the 48 buttons were now holds 12 LCD Displays to give an overview of the Program and it’s Patches and Keyranges.
This is great!
Thanks everyone!
RB
Updating a 25 year old Editor
-
This reply was modified 3 years, 1 month ago by
-
AuthorPosts
- The forum ‘Programming’ is closed to new topics and replies.