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
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!