Simon-L / ModScript

10 stars 1 forks source link

ModScript

Modular Scripting

Scripting in VCV Rack for better integration with your patch and designed for use with MIDI controllers!

Lune & Pleine Lune

Lua scripting in VCV Rack

In Lune, you can control arbitrary parameters from any module in the patch.
The accompanying "Lune Helper" module helps with finding the info you need to write scripts for the patch you are working on.

ModScript's approach differs from the usual "everything-is-a-module" paradigm: it allows you to write all the MIDI interaction you need using code that is easy to read and write and to remain focused on musical elements in the patch.

Image

Interested? Please join the conversation on VCV Rack forum!

Features:

Expected super cool usecases:

Videos

https://synthe.tiseur.fr/userfiles/videos/lune/lune3.mp4

See also this video and this one for a bit of live coding! (resulting script)

Example and API demo

Modules

mymodule = Module(0xdeadbeef12345) -- a module is identified by its ID

myVCO = NewVCO(0x123456789) -- known modules made from the helper's dump

mymodule.params = { -- optionally, a map of names to ids can be defined for the parameters
    ["freq"] = {index = 0},
    ["res"] = {index = 1}
}

Parameters

-- afterwards in process...
-- by default parameters are normalized to 0.0-1.0
mymodule:setParam("freq", 0,3) -- the module and name can be used to set parameters
mymodule:setParam(12, 0.98) -- or an arbitrary parameter id

 -- use Raw to set exact value (use the Helper to find the correct values)
mymodule:setParamRaw("waveform", 4.0)
-- relative mode to increment or decrement parameter from its current value - useful for relative knobs!
mymodule:setParamRelative("cutoff", 0.05)

-- do not show red indicator, useful if you set many parameters rapidly and often
mymodule:setParamNoIndicator("obscureparam", 0.0)

__setParamValue(0x12acab345abc, 3, 1.0) -- or you can even use any module and parameter id using the low-level call

-- retrieve parameter value
myVCO:getParam("dry_level")
-- and light value
myVCO:getLight(17) -- unfortunately lights aren't named most of the time and multi-color lights have one index for each color, eg. an RGB light will span accross 3 indices
-- it is recommended to get a dump of the module or even read the source code if available for a better understanding of the module's lights

MIDI

-- handling is done in process(), see scripts/example.lua, details in scripts/lib/lib.lua

-- Easy to use table generated using the Message() function
msg = Message(block.midiInput[i])
display('type ' .. string.format("0x%x", msg.type) .. ' channel ' .. msg.channel .. ' note ' .. msg.note .. ' value ' .. msg.value)
display(status(msg)) -- get the message type as a string

-- sending
sendMidiMessage(NOTE_ON, 64, 64)
sendMidiMessage(NOTE_OFF, 64, 64)

-- SysEX
sendSysex(bytes)
-- utility function to include text in sysex at designated offset with padding
writeString(buffer, start_offset, "text string", pad_to_offset) -- buffer is modified in-place

Cables (experimental, not tested recently)

-- Cables, up to 256 cables can be managed from the script
id = addCable(moduleWithOutput, outputId, moduleWithInput, inputId) -- returns an id to use when deleting (not the actual Rack id)
removedCable(id) -- removes cable from the patch, only cables added from the script can be removed
-- Note: cables added from the script that are not removed from the script will not free their slot in the 256 pool

Building

make dep
make

License info

Plugin is licensed under GNU General Public License v3.0 or later (GPL-3.0-or-later)
Panel font is https://velvetyne.fr/fonts/facade/ by Éléonore Fines

Authorship note

This plugin borrows a lot of code from https://github.com/VCVRack/VCV-Prototype/tree/v2
File watching and all engines except LuaJIT have been removed
Where appropriate, any other reference to orignal code is included.
The repositories linked above contain additional licensing information in LICENSE.md at their root.