Lua Protoplug

[home] [downloads] [API docs]

What is Protoplug?

Protoplug is a VST/AU plugin that lets you load and edit Lua scripts as audio effects and instruments. The scripts can process audio and MIDI, display their own interface, and use external libraries.



Cross-platform: builds for Windows, Mac OS X and Linux. This means that all protoplug scripts are compatible with these platforms and can be loaded into a huge amount of audio software (glory to JUCE)

Fast: Use the speed of LuaJIT, and perform DSP tasks as efficiently as old school C implementations.

Free and open source: Want a new feature? Add it yourself. The source is MIT-licensed and available on Github.


Example Scripts

Simple distortion
Better distortion
Badass distortion
Simple GUI and MIDI-out

require "include/protoplug"

local function clamp (x, min, max)
    return math.min (math.max (x, min), max)
end

function plugin.processBlock (samples, smax)
    for i = 0, smax do
        samples[0][i] = clamp (samples[0][i], -0.1, 0.1) -- left
        samples[1][i] = clamp (samples[1][i], -0.1, 0.1) -- right
    end
end
This bare-bones distortion clips the signal to a fixed value.
require "include/protoplug"

local clip

local function clamp (x, min, max)
    return math.min (math.max (x, min), max)
end

function plugin.processBlock (samples, smax)
    for i = 0, smax do
        samples[0][i] = clamp (samples[0][i], -1*clip, clip)
        samples[1][i] = clamp (samples[1][i], -1*clip, clip)
    end
end

params = plugin.manageParams {
    Clip= {
        min = 0;
        max = 1;
        changed = function (val) clip = val end;
    };
}
Adding a parameter to the script: the VST/AU now has a "Clip" parameter that can be changed and automated to tune the distortion.
require "include/protoplug"
local cbFilter = require "include/pac/cookbook filters"

local power

local function dist (x)
    if x<0 then return -1*math.pow (-1*x,power) end
    return math.pow (x,power)
end

stereoFx.init ()
function stereoFx.Channel:init ()
    -- create per-channel fields (filters)
    self.low = cbFilter {type = "lp"; f = 100; gain = 0; Q = 0.3}
    self.high = cbFilter {type = "hp"; f = 50; gain = 0; Q = 0.3}
end

function stereoFx.Channel:processBlock (samples, smax)
    for i = 0, smax do
        local s = dist (self.high.process (samples[i]))
        samples[i] = s + self.low.process (samples[i])*2
    end
end

params = plugin.manageParams {
    Power = {
        min = 1;
        max = 0.01;
        changed = function (val) power = val end;
    };
}
This version uses filters, which require per-channel treatment. The stereoFx module facilitates per-channel processing.
require "include/protoplug"

function plugin.processBlock (samples, smax, midiBuf)
    if testEvent ~= nil then
        midiBuf:addEvent (testEvent)
        testEvent = nil
    end
end

local frame = juce.Rectangle_int (100,10,200,117)
function gui.paint (g)
    g:fillAll ()
    g:setColour (juce.Colour.green)
    g:drawRect (frame)
end

gui.addHandler ("mouseDown", function (event)
    x, y = event.x, event.y
    if x<100 or x>300 or y<10 or y>127 then return end
    testEvent = midi.Event.noteOn (1, x/3, 127-y)
end)

gui.addHandler ("mouseUp", function (event)
    if x ~= nil then
        testEvent = midi.Event.noteOff (1, x/3)
        x = nil
    end
end)
This shows a simple GUI with a large square frame. When you click in the frame, a note is sent on the plugin's MIDI out with pitch and velocity corresponding to the mouse position.

The above examples are pretty lame, but should serve their humble demonstration purposes: the scripts use the protoplug API and work as fully functional plugins.

More scripts can be found in the standard distribution's effects and generators folder.

Scripts wanted: Made any cool protoplug scripts? You can contribute them by sending them to me or by submitting them as a pull request and I'll add them to the distribution or to the future scripts repository (currently in early planning stage).


Why Protoplug

The scene: There are very few on-the-fly scriptable VSTs out there. In fact, the only real contender is ReaJS.

The applications: Study, research and prototyping are good causes, and this is fast enough that you can also use it for real-world applications.

The language: We've seen enough raving accounts of LuaJIT's now legendary performance, so let's try it in the very demanding field of realtime audio. So far, the only slowdown is that all floating-point operations are done with double precision. This does not always have an impact, but it can be slower than vectorized SSE float processing.


Download

Latest binary release: 1.0.0

 Download