stoermelder's Idea und Development Thread

I’ve been reasoning about some RPC for modules since I started to use rack but never got back to have a look at the source code. Today I sat down and implemented the basic functionality of my python midi codec with a patch, where I showcase how I script 2 modules … (Plateau and ADDR-Seq) by entering python commands in a Jupyter Notebook. On mac and linux the setup and code is a little bit easier, as you can create virtual ports by code, on windows I had to use loopMIDI which is easy enough to setup. So for this I created a loopback device called VCVScript.

The idea is: I created an automatic mapping with midi-cat, created a list of the same order with python compatible names.

plateau_controls = [
    "dry_level",
    "wet_level",
    "pre_delay",
    "input_low_cut",
    "input_high_cut",
    "size",
    "diffusion",
    "decay",
    "reverb_high_cut",
    "reverb_low_cut",
    "modulation_rate",
    "modulation_shape",
    "modulation_depth",
    "freeze",
    "clear",
    "freeze_toggle",
    "nr_17",
    "dry_cv_depth",
    "wet_cv_depth",
    "input_low_cut_cv",
    "input_high_cut_cv",
    "size_cv",
    "diffusion_cv",
    "decay_cv",
    "reverb_high_cut_cv",
    "reverb_low_cut_cv",
    "mod_speed_cv",
    "mod_shape_cv",
    "mod_depth_cv",
    "tuned_mode",
    "diffuse_input",
]
addr_seq_controls = [
    "stesp",
    "direction",
    "select_step",
    "step_1",
    "step_2",
    "step_3",
    "step_4",
    "step_5",
    "step_6",
    "step_7",
    "step_8",
]

Could also have been using the label function of midi_cat and reading the labels from the json.

Next step then saved this as preset and loaded the json in the python script, automatically generated midi cc’s and been writing it back. Then loading the preset in rack again. With this setup I have a proper mapping.

No the idea … I want to gey some mechanism, where I can address every module and its items. midi is always possible, but requires manual mapping all the time. My idea is more like how can we automate this.

One idea which I also posted in another thread is to have something like OSC … an publish subscribe like lightweight thing lik zeromq, or nanomsg nng. I also wouldn’t mind using mqtt for this and running a broker on my machine. But I’d rather prefere a highspeed low latency solution.

And now the question to @stoermelder or @Vortico

Is it possible to enumerate all existing modules in rack and get their parameter names? Like it already is done in midi-map or cat.

This way I would have a server module in rack that enumerates all the modules and I’d implement the client side in my python script (or other app like touch osc) where I then could address a module by its canonical name like

/plateau/<moduleId or instance number>/pre_delay

I had a reason remote code implemented with a sysex codec to be able to adress all modules in parallel within a script. But I don’t think we need that in rack, also it might would be nice. But for this solution I’d rather have some conventional setup, where I can discover the modules automatically (get a response from the module server with the available controller item names and then could autogenerate class in python. Then I get autocompletion and can easily script stuff like custom randomization, which I did in this example and assigned a midi send on the big button. The script receives the midi message and then executes the randomization over midi.

Please open a feature request on Rack for that (there will be an API for enumeration of all module in Rack v2).
It sounds like a really specialized request for your personal workflow. Will there anybody else using something like that?

My guess is: basically every workflow where you don’t map one small controller to an interface, but have a controller with a lot of controlls and want to control as many parameters as possible. Or put it simple: Less work setting up mappings: It basically this example with cvOSCcv from trowasoft but for every module you wan’t to control.

I could totally do it like this or with the manuall midi way and would have to have a lot of setup every time I create new patches, which is fine for me, but very tedious :slight_smile:

I also had a look at how midi-cat and mem are saving the stuff into the preset or song json. So it’s almost there.

This is how midi-cat json looks like:

 {
      "id": 91,
      "plugin": "Stoermelder-P1",
      "version": "1.7.1",
      "model": "MidiCat",
      "params": [],
      "rightModuleId": 97,
      "data": {
        "panelTheme": 1,
        "textScrolling": true,
        "mappingIndicatorHidden": true,
        "locked": false,
        "maps": [
          {
            "cc": 31,
            "ccMode": 0,
            "note": -1,
            "noteMode": 0,
            "moduleId": 60,
            "paramId": 0,
            "label": "",
            "midiOptions": 0
          },
          {
            "cc": 32,
            "ccMode": 0,
            "note": -1,
            "noteMode": 0,
            "moduleId": 60,
            "paramId": 1,
            "label": "",
            "midiOptions": 0
          },

And the mem with plateau stored:

  {
      "id": 97,
      "plugin": "Stoermelder-P1",
      "version": "1.7.1",
      "model": "MidiCatEx",
      "params": [
        {
          "id": 0,
          "value": 0.0
        }
      ],
      "leftModuleId": 91,
      "data": {
        "panelTheme": 1,
        "midiMap": [
          {
            "pluginSlug": "Bogaudio",
            "moduleSlug": "Bogaudio-AddrSeq",
            "pluginName": "Bogaudio",
            "moduleName": "ADDR-SEQ",
            "paramMap": [
              {
                "paramId": 0,
                "cc": 31,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 1,
                "cc": 32,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 2,
                "cc": 33,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 3,
                "cc": 34,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 4,
                "cc": 35,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 5,
                "cc": 36,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 6,
                "cc": 37,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 7,
                "cc": 38,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 8,
                "cc": 39,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 10,
                "cc": 41,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              }
            ]
          },
          {
            "pluginSlug": "Valley",
            "moduleSlug": "Plateau",
            "pluginName": "Valley",
            "moduleName": "Plateau",
            "paramMap": [
              {
                "paramId": 0,
                "cc": 0,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },
              {
                "paramId": 1,
                "cc": 1,
                "ccMode": 0,
                "note": -1,
                "noteMode": 0,
                "label": "",
                "midiOptions": 0
              },

So almost everything is there. Could you additionally store the default label which is shown as mapping text.

re midi-cat feedback value: i mentioned that and the link to the iversion approach as i thought that it was solved there quite nicely in the context menu and doing it in a simlar way would maybe make both approaches kind of consistent to each other - but of course if you find or like another approach better this would be fine too

What is the reason why the midi-cat is limited to 128 inputs. Midi related? Or performance? Could there be an option to extend? like 256, 512, 1024, 2048. This would help me tremendously with my workflow. I could just create a custom build and test it, but if it makes sense this might be an option for others as well.

Another Idea I got for strip from the python scripting I’m doing. Let the user select the paramters he wants to randomize or he want’s to exclude from randomization. I’m doing this in my scripting stuff with 2 regex expressions.

Or another Idea for randomization. You have code in MIDI-CAT to select a module and map all of it’s parameters. How about a new module (possible Name: RAND) which has the paramter selection/mapping features from MIDI-CAT but doesn’t map to midi, but just creates a list of parameters (randomize and exclude from randomization lists).

I really used the strip randomize feature a lot, but more often I just wanted to exclude some parameters, or just have a bunch from different modules randomized which are spread across the path. (That’s why I creted the pthon script_

One midi channel is limited to 128 cc parameters. If you wanna more just add another midi cat!

I guess this can be relaxed or expanded with V2 when sysex arrives.

Never the less. I made good progress today. Maybe this is something ben likes to integrate in one of his modules.

With the setup of midi-cat and T7-Ctrl I can now auto generate mappings for defined modules and than randomize and random patch outputs to inputs. There is still work left … but with this setup one could define a ruleset of which inputs are alllowed to be pathed to outputs (for restrictions and getting useable results).

I’m pretty sure this will yield some nice experiements and sounds. As soon as it’s poished I’l create a separate thread and release the code for the people interested in this kind of stuff. In the meantime, maybe there is some idea from this setup you like to pickup

this is already possible with the in/ex button and the right click menue, or do you think of something different?

1 Like

Totally did not see that. My bad. Would be nice to toggle the button somehow for excluding more than one in a row or be able to include one again after excluding

1 Like

Wow, i guess i have offended you somehow? Who are you to tell people what is the right place for them? I am absolutely sure, because there’s NO real cables when using VCV, just a virtual ones, which i don’t see anyways since the settings allow that, so in case of Rack they just represent the signal flow logic, nothing more…

PHYSICAL cables, which i meant, are, for me personally, are the thing of the past.

P.S. Next time you have nothing to say on topic, maybe just don’t say anything?

I’m saying this as a moderator: everybody please try to be friendly with each other and do not escalate the conversation. If you think someone else’s messages are inappropriate do not argue with them but report/flag the messages. Thanks.

3 Likes

I apologize, @nnbveh. That was 100% intended as a jest and absolutely nothing more.

4 Likes

Given the picture that accompanied your comment, it was pretty clearly a jest.

1 Like

Well, it was my first interaction with @nnbveh and we have no context for one another. The risk of making someone feel unwelcome was really not worth the reward of that (or any) joke. At the very least, I should have put an emoji on it.

2 Likes

Fair enough :slight_smile:

1 Like

MIDI-CAT and 8FACE work together when targeting the same module just fine, meaning that i can control parameters from external midi controller, and then save it all as a preset in 8FACE. But this doesn’t work with TRANSIT module. Is it because 8FACE is extender kind of module and TRANSIT is not or something? Would be great if TRANSIT would work the same way as 8FACE…

It makes sense for MIDI-CAT and 8FACE working together as you can switch mappings of your MIDI controller. I don’t see any meaningful use-case for TRANSIT. Can you explain what you are trying to achieve?

I have a 16n faderbank midi controller mapped to the ‘unless towers’ module, which is a virtual faderbank. Output of Towers goes to CV-MAP and split modules, so i can have two ways of controlling my patches, by cv directly or by direct mapping. What i achieve by this is that 1 i have a physical controller permanently set up and ready to be used in my template, and 2 i can store the presets of Towers(effectively saving those mapped parameters as well) all in one place, and switch between them any moment for composition/performance needs. MIDI-CAT of course set-up with takeover mode. SO basically i am able to store the presets of my physical midi controller, kind of, and go back to them any time. The only thing is missing here is the smooth transition between the Tower presets, which i can live without, but in some patches and makes a lot of sense and would make things sound much nicer…

I hope i am more or less clear…

I suspect it could be useful for people who use other controllers/modules as well, although i’m not aware of any other modules which can act as a “bank” of values, would be very interested actually.

p.s. the picture is not of my set up template, but just for reference, in case you haven’t seen the Towers module

1 Like

8Face “not-so-random” slot mode suggestion: Right now in random mode 8face might just stay on the same slot twice or even longer, which doesn’t sound that good in some cases, the way i use it anyways. Could there be another random mode in which every slot triggers only ONCE and never repeats unless the module is out of slots to choose from? There’s probably a proper name for such a rule, but i don’ know it yet…

2 Likes

My Entrian Sequencers have this feature, calling it “random but fair”, with the alternative being called “truly random”.

I struggled to come up with a better name for it, and couldn’t. For the C++ programmers among us, it’s called std::shuffle(). :slight_smile:

3 Likes