Lua Program Change plugin

I’ve written a Lua plugin script that changes my session settings (active tracks, active plugins, plugin presets) based on MIDI Program Change messages.

I think it’s similar to what was discussed here: Change plugin presets with Lua DSP script

A suggestion in that discussion thread was to put Program Changes in a MIDI track, but I want to handle Program Changes from my controller, so I push a button on the keyboard and trigger actions in Ardour.

I haven’t found anything else that quite does this. Have I missed something?

My plugin works fine, but I’ve got some questions.

  1. If I update the code in the script file, how can I easily load the new code into the plugin? Right now, I’m deleting the plugin and re-adding it to the track.

  2. Same question for Editor Actions. It seems like if I change an Editor Action script, even restarting Ardour doesn’t pick up the change. I have to remove the action and re-add it. Are the scripts cached somewhere?

  3. How can I add an “Edit…” GUI to a Lua plugin script?

I know that the quick answer to #3 is, “you can’t”, at least not without modifying the C++ code. That’s what I’m asking - where should a call to a Lua plugin GUI function (using an Lua plugin API call that doesn’t exist yet) be added to the C++ code? It seems like some of the non-Lua plugins map a GUI window when has_editor is called (vst3 calls try_create_view from has_editor), but that doesn’t seem like the right place to do it. has_editor should just return true, I think, but when should an actual dialog box be displayed?

My code currently looks like this:

  if d[2] == 0 or d[2] == 29 then
    Session:route_by_name("OT P1ANO II"):set_active(true, nil);                                                                    
    deactivate_processor_by_name(Session:route_by_name("OT P1ANO II"), "MIDI Velocity-Range Filter")
    Session:route_by_name("Dexed"):set_active(false, nil);                                                                         
    Session:route_by_name("Yoshimi"):set_active(false, nil);                                                                       
    Session:route_by_name("Yoshimi 1"):set_active(false, nil);                                                                     
  elseif d[2] == 1 then
    Session:route_by_name("OT P1ANO II"):set_active(true, nil);                                                                    
    activate_processor_by_name(Session:route_by_name("OT P1ANO II"), "MIDI Velocity-Range Filter")
    Session:route_by_name("Dexed"):set_active(false, nil);                                                                         
    Session:route_by_name("Yoshimi"):set_active(false, nil);                                                                       
    Session:route_by_name("Yoshimi 1"):set_active(false, nil);
  elseif d[2] == 2 then
    Session:route_by_name("OT P1ANO II"):set_active(false, nil);                                                                   
    Session:route_by_name("Dexed"):set_active(true, nil);                                                                          
    load_preset(Session:route_by_name("Dexed"), "Dexed", "BWB GLOCK");                                                             
    Session:route_by_name("Yoshimi"):set_active(false, nil);                                                                       
    Session:route_by_name("Yoshimi 1"):set_active(false, nil);                                                                     

etc, etc.

I want to put those if-blocks into text boxes in a dialog box so that they can be changed from the GUI.

Lua really does seem like the best way to go. We certainly can’t set routes and processors active or inactive from any other kind of plugin (VST3, LV2, etc).

Any feedback is welcome.

2 Likes

I made a script that activates/deactivates tracks when a MIDI message is received based on their naming. All tracks whose names start with the number of the received MIDI message value are activated, others are deactivated. Tracks whose names do not start with numbers are ignored.

This allows you to set up “patches” simply by renaming tracks. It’s quick to change and you don’t have to continuously edit the script.

It doesn’t support changing plugin presets yet, but one could come up with a naming convention to achieve that too, and/or do some clever routing.

See the comment in the script for more info. Change the variable values under “User Settings” to suit your needs.

Find the script “noedig_midi_activate_tracks.lua” at: https://github.com/noedigcode/Ardour-Tools

Interesting idea. Is there a reason why you chose to de/activate the tracks, rather than just muting them (or toggle MidiTrack:set_input_active)?

Deactivating a track is rather drastic. Also one can one change active state when the transport is not rolling.

Thanks for sharing the script. Am I assuming correctly that this is for live performance where you want to use your MIDI keyboard to select which MIDI track(s) to play live? Or do you use a MIDI controller to remote control audio live mixes?

I actually just went with the idea that the OP had. I assumed he had a reason to deactivate tracks, i.e. to save CPU usage. But yes, disabling input or muting is possibly better. I did a similar script for Reaper a while back, where I both muted tracks and fully controlled routing of MIDI to the tracks through the plugin. This allows for the possibility of things like keeping notes sustained when changing patches until it is eventually released.

From my point of view, this is for live keyboard playing, but I haven’t actually used it. To tell you the truth, I was kind of nerd sniped, especially after I thought about using track naming to easily achieve this with minimal user input.

1 Like

Yes, this is for live performance, and that’s why I disable the tracks, to limit CPU utilization, since I have latency issues: 256 samples @ 48 kHz = 5.3 ms running Ubuntu’s new realtime kernel. It’s playable, but I still get occasional xruns. It’s still not ready for a serious performance.

Naming the tracks with numbers is a clever idea, but do we all agree that allowing the plugin to be configurable with snippets of Lua code is the better way to go?

If somebody can suggest to me where in the C++ code I should add a call to a new Lua plugin function, to be triggered when the “Edit…” button is clicked, I think I can put together a PR that does this. We’ve already got Lua functions to build a dialog box, and the “Edit…” function should run in the GUI thread, not the DSP, so a simple plugin with textboxes for Lua code might not be too hard.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.