Skip to content
2 changes: 1 addition & 1 deletion scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2026 Kushview, LLC
# SPDX-License-Identifier: GPL-3.0-or-later

file(GLOB ELEMENT_LUA_SCRIPTS "${CMAKE_CURRENT_SOURCE_DIR}/*.lua")
file(GLOB ELEMENT_LUA_SCRIPTS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.lua")
# Lua scripts are currently built into the the binaries until the app and plugins
# are able to deal with search paths and so forth.
if(TRUE)
Expand Down
3 changes: 2 additions & 1 deletion scripts/amp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ end
return {
type = 'DSP',
layout = amp_layout,
process = amp_process
process = amp_process,
dspName = 'Amp'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
3 changes: 2 additions & 1 deletion scripts/channelize.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ return {
parameters = parameters,
prepare = prepare,
process = process,
release = release
release = release,
dspName = 'Channelizer'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
3 changes: 2 additions & 1 deletion scripts/dial.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ end
return {
type = 'DSP',
layout = layout,
process = process
process = process,
dspName = 'Value'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
3 changes: 2 additions & 1 deletion scripts/midicc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ return {
type = 'DSP',
layout = layout,
prepare = prepare,
process = process
process = process,
dspName = 'MIDI CC'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
90 changes: 90 additions & 0 deletions scripts/miditranspose.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
--- MIDI Transposer.
--
-- This is a MIDI filter which shifts the note number of all Note On/Off
-- messages by a specified number of semitones. Set the transpose parameter
-- to '0' to bypass the filter.
--
-- @script transpose
-- @type DSP
-- @license GPL v3
-- @author Buzz Burrowes

local io = require ('io')
local midiBuffer = require ('el.MidiBuffer')
local midi = require ('el.midi')
local script = require ('el.script')
local round = require ('el.round')

local lastSemitones = 0
local lastMidiChannelSeen = 1

-- Buffer to render filtered output
local output = midiBuffer.new()

local function layout()
return {
audio = { 0, 0 },
midi = { 1, 1 },
control = {{
{
name = "Transpose",
symbol = "transpose",
min = -24,
max = 24,
default = 0
}
}}
}
end

-- prepare for rendering
local function prepare()
-- reserve 128 bytes of memory and clear the output buffer
output:reserve (128)
output:clear()
end

local function process (_, m, p)
-- Get MIDI input buffer from the MidiPipe
local input = m:get (1)

-- Get the transpose amount from the parameter array, and round to integer
local semitones = round.integer (p[1])

output:clear()

-- Send an allNotesOff message is the transposition has changed
if semitones ~= lastSemitones then
output:insertPacked (midi.controller (lastMidiChannelSeen, 123, 0), 0)
lastSemitones = semitones
end

-- For each input message, shift the note number if it's a note on/off
for msg, frame in input:messages() do
if semitones ~= 0 and (msg:isNoteOn() or msg:isNoteOff()) then
local note = msg:note(msg) + semitones
-- clamp to valid MIDI note range
if note < 0 then note = 0 end
if note > 127 then note = 127 end
msg:setNote (note)
lastMidiChannelSeen = msg:channel()
end
output:insert (msg, frame)
end

-- DSP scripts use replace processing, so swap in the rendered output
input:swap (output)
end

return {
type = 'DSP',
layout = layout,
parameters = parameters,
prepare = prepare,
process = process,
release = release,
dspName = 'MIDI Transpose'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
-- SPDX-License-Identifier: GPL-3.0-or-later
3 changes: 2 additions & 1 deletion scripts/mtc_generator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ return {
type = 'DSP',
layout = layout,
prepare = prepare,
process = process
process = process,
dspName = 'MIDI Timecode (MTC) Generator'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
1 change: 1 addition & 0 deletions scripts/spontonchordchooser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ return {
type = 'DSP',
layout = layout,
process = process,
dspName = 'Spoton Scale Chooser'
}

-- SPDX-FileCopyrightText: Copyright (C) Lokki.
Expand Down
3 changes: 2 additions & 1 deletion scripts/testtone.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ return {
type = 'DSP',
layout = layout,
prepare = prepare,
process = process
process = process,
dspName = 'Test Tone'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
3 changes: 2 additions & 1 deletion scripts/tremolo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ return {
type = 'DSP',
layout = layout,
prepare = prepare,
process = process
process = process,
dspName = 'Tremolo'
}

-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
Expand Down
80 changes: 16 additions & 64 deletions src/nodes/scriptnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "scripting/bindings.hpp"
#include "scripting/dspscript.hpp"
#include "scripting/scriptloader.hpp"
#include "scripting/scriptregistry.hpp"

#define EL_LUA_DBG(x)
// #define EL_LUA_DBG(x) DBG(x)
Expand Down Expand Up @@ -237,86 +238,37 @@ void ScriptNode::setParameter (int index, float value)
}

//==============================================================================
int ScriptNode::getNumPrograms() const
{
return (int)ScriptRegistry::instance().getScripts().size();
}

const String ScriptNode::getProgramName (int index) const
{
if (! juce::isPositiveAndBelow (index, getNumPrograms()))
return {};

switch (index)
{
case 0:
return "Amp";
break;
case 1:
return "Channelizer";
break;
case 2:
return "Spoton Scale Chooser";
break;
case 3:
return "MIDI Timecode (MTC) Generator";
break;
case 4:
return "Value";
break;
case 5:
return "MIDI CC";
break;
case 6:
return "Tremolo";
break;
case 7:
return "Test Tone";
break;
}

String name = TRANS ("Program");
name << " " << int (index + 1);
return name;
return ScriptRegistry::instance().getScripts()[index].name;
}

void ScriptNode::setCurrentProgram (int index)
{
if (! juce::isPositiveAndBelow (index, getNumPrograms()))
return;

_program = index;

String newDspCode, newUiCode;
const BuiltInScripts& scriptInfo = ScriptRegistry::instance().getScripts()[index];

switch (index)
newDspCode = String::fromUTF8 (scriptInfo.dspScript, scriptInfo.dspSize);
if (scriptInfo.uiSize > 0)
{
newUiCode = String::fromUTF8 (scriptInfo.uiScript, scriptInfo.uiSize);
}
else
{
case 0:
newDspCode = String::fromUTF8 (scripts::amp_lua, scripts::amp_luaSize);
newUiCode = String::fromUTF8 (scripts::ampui_lua, scripts::ampui_luaSize);
break;
case 1:
newDspCode = String::fromUTF8 (scripts::channelize_lua, scripts::channelize_luaSize);
newUiCode.clear();
break;
case 2:
newDspCode = String::fromUTF8 (scripts::spontonchordchooser_lua, scripts::spontonchordchooser_luaSize);
newUiCode.clear();
break;
case 3:
newDspCode = String::fromUTF8 (scripts::mtc_generator_lua, scripts::mtc_generator_luaSize);
newUiCode.clear();
break;
case 4:
newDspCode = String::fromUTF8 (scripts::dial_lua, scripts::dial_luaSize);
newUiCode.clear();
break;
case 5:
newDspCode = String::fromUTF8 (scripts::midicc_lua, scripts::midicc_luaSize);
newUiCode.clear();
break;
case 6:
newDspCode = String::fromUTF8 (scripts::tremolo_lua, scripts::tremolo_luaSize);
newUiCode.clear();
break;
case 7:
newDspCode = String::fromUTF8 (scripts::testtone_lua, scripts::testtone_luaSize);
newUiCode.clear();
break;
newUiCode.clear();
}

dspCode.replaceAllContent (newDspCode);
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/scriptnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ScriptNode : public Processor,
void setPlayHead (juce::AudioPlayHead*) override;

//==========================================================================
int getNumPrograms() const override { return 8; }
int getNumPrograms() const override;
int getCurrentProgram() const override { return _program; }
const String getProgramName (int index) const override;
void setCurrentProgram (int index) override;
Expand Down
Loading
Loading