____  _______   ___
 / __ \/ __/ _ | / _ \
/ /_/ /\ \/ __ |/ , _/
\____/___/_/ |_/_/|_|
OSAR > protoplug:
[about] [releases] [forums] [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. Transform any music software into a live coding environment!

protoplug running in REAPER


Cross-platform: builds for Windows, Linux, and macOS. 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 to perform complex DSP tasks in realtime.

Free and open source: 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 {
    {
        name = "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/dsp/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 {
    {
        name = "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. And yet, the scene of live coding is rapidly expanding.

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 main 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.4.0

> > Get it now on Github releases!