Skip to content
licnep edited this page Jun 23, 2011 · 5 revisions

The controllable parameters are stored as a struct called "ParameterStruct", defined in /Params/paramchangefunc.cpp The parameter struct has all the information needed to identify a parameter, such as a unique ID, the part number, effect number, adsynth voice number etc.

When a dial is created in the UI, it has to be assigned its parameterStruct. To do so, the dial passes itself to the function "whichParameterDoesThisDialControl" (defined in Params/midiController.cpp). The function scans every possible parameter, and tries to move the knob to find out which one is the parameter controlled by that knob. If the knob seem to change one of the midi-controllable parameters, it’s drawn as a midi-controllable knob.

How do i turn a regular dial into a midi controllable one?

Use FLUID to examine the UI where the knob is. For example, if it’s an adsynth parameter you should analyze the file: "UI/ADnoteUI.fl".

The callback is called whenever the dial is rotated. You can see that when you rotate this dial it changes the value of: "pars→GlobalPar.PPunchStrength". To learn more about this, let’s switch to the "ADnoteUI.cxx" (that is automatically generated from the .fl file). With the help of some search functions we can explore the code to understand it. I personally use, and suggest, netbeans, because it offers many useful functions to navigate the code:

Now we have to add it to "Params/midiController.cpp", in the "WhichParameterDoesThisDialControl" function. This funciton is huge. You can see it has many nested loops to check for all the different parameters, it is structured more or less like this:

for (all parts) {
   //check part global parameters HERE
   for (all kititems) {
     if (adnote activated) {
        //check adnote global parameters HERE
        (*)
        for (all adnote voices) {
            //check adnote voice specific parameters HERE
        }
     }
   }
   for (all effects) {
       //check effects parameters HERE
   }
}

In this case it’s an adnote global parameter, so we’ll have to put it at the (*) mark. The code we have to add is similar to the many other snippets we find there, we just have to change a couple of things.

We changed the value to check to Gpar→PPunchStrength, according to what we saw from the FL file. We chose to write "Punch Strength" as a label, and we chose "parID::PAddSynthPunchStrength" as unique parameter-identifying number. If you just want to test you can simply put a random, high number like 999 instead of "parID::PAddSynthPunchStrength". Otherwise you have to define a new ID number in MidiController.h, like this:

(We will probably switch to string identifiers later, so all this is no more needed.)

Now if you compile, and everything goes well, you should see that the knob is midi-controllable!!! :D

This procedure only works for some knobs, other require something a bit differnent. If you encounter any problem contact me at: lsnpreziosi8888888@gmail.com (without the 8s)

enabling save and restore:

Now yoshimi can convert the parameter pointer in memory to a numeric ID, and it can save it to a session file, but when it loads the session it doesn’t know, from the number ID, where the parameter is located in memory (memory addresses change on every execution). Let’s change that. All we need to do is add a line like this in "Params/ParamChangeFunc.cpp":

This is basically the reverse of what we did previosly.

WARNING: in many cases this won’t work without other tweaks. Just drop me an email, and i’ll be happy to help. lsnpreziosi9999999999@gmail.com (remove the 9s)

Clone this wiki locally