Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
JS Meeblip Controller for Reaper
/*******************************************************************************
* Copyright 2012, Damien Di Fede *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/)for more details. *
*******************************************************************************/
desc: MIDI CC Generator for Meeblip Oscillators
////////////////////////////////////////////////////////////////////////////////
slider1:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Channel
slider2:1<0,1,1{saw,pwm}>osc a wave
slider3:127<0,127,1>pwm
slider4:0<0,1,1{off,on}>pwm sweep
slider5:0<0,127,127{off,on}>osc a noise
slider6:1<0,1,1{triangle,square}>osc b wave
slider7:64<0,127,1>osc detune
slider8:0<0,1,1{off,on}>osc b enable
slider9:0<0,1,1{normal,up}>osc b octave
slider10:0<0,1,1{off,on}>anti-alias
slider11:0<0,127,1>amp attack
slider12:64<0,127,1>amp decay
slider13:1<0,1,1{off,on}>amp env sustain
slider14:0<0,1,1{low,high}>filter mode
slider15:64<0,127,1>filter cutoff
slider16:64<0,127,1>filter resonance
slider17:64<0,127,1>filter attack
slider18:64<0,127,1>filter decay
slider19:0<0,1,1{off,on}>lfo enable
slider20:0<0,1,1{filter,osc}>lfo destination
slider21:0<0,1,1{triangle,square}>lfo wave
slider22:0<0,1,1{off,on}>lfo random
slider23:64<0,127,1>lfo depth
slider24:64<0,127,1>lfo rate
slider25:0<0,1,1{off,on}>distortion
slider26:0<0,1,1{off,on}>osc fm
slider27:24<0,127,1>glide
in_pin:none
out_pin:none
@init
statController = $xB0;
updateFreq = 8;
updateCounter = 0;
offset = 0;
@slider
// Remove fractions and clamp to legal range
slider3 = min(max(slider3 | 0, 0), 127);
slider7 = min(max(slider7 | 0, 0), 127);
slider11 = min(max(slider11 | 0, 0), 127);
slider12 = min(max(slider12 | 0, 0), 127);
slider15 = min(max(slider15 | 0, 0), 127);
slider16 = min(max(slider16 | 0, 0), 127);
slider17 = min(max(slider17 | 0, 0), 127);
slider18 = min(max(slider18 | 0, 0), 127);
slider23 = min(max(slider23 | 0, 0), 127);
slider24 = min(max(slider24 | 0, 0), 127);
slider27 = min(max(slider27 | 0, 0), 127);
channel = statController + slider1;
////////////////////////////////////////////////////////////////////////////////
@block
function sendKnobIfChanged( cc, currentValue, slide ) local(newValue)
(
newValue = cc | (slide << 8);
currentValue != newValue ?
(
midisend( offset, channel, newValue );
);
newValue;
);
function sendSwitchIfChanged( cc, currentValue, slide ) local(newValue)
(
newValue = cc | (slide*64 << 8);
currentValue != newValue ?
(
midisend( offset, channel, newValue );
);
newValue;
);
function sendAll()
(
oscawave = sendSwitchIfChanged( 79, oscawave, slider2 );
oscapwm = sendKnobIfChanged( 54, oscapwm, slider3 );
pwmsweep = sendSwitchIfChanged( 78, pwmsweep, slider4 );
oscanoiz = sendSwitchIfChanged( 77, oscanoiz, slider5 );
oscbwave = sendSwitchIfChanged( 75, oscbwave, slider6 );
oscdetun = sendKnobIfChanged( 55, oscdetun, slider7 );
oscbenab = sendSwitchIfChanged( 74, oscbenab, slider8 );
oscboctv = sendSwitchIfChanged( 73, oscboctv, slider9 );
antialis = sendSwitchIfChanged( 72, antialis, slider10 );
ampattak = sendKnobIfChanged( 61, ampattak, slider11 );
ampdecay = sendKnobIfChanged( 60, ampdecay, slider12 );
ampsustn = sendSwitchIfChanged( 76, ampsustn, slider13 );
filtmode = sendSwitchIfChanged( 68, filtmode, slider14 );
filtcutt = sendKnobIfChanged( 49, filtcutt, slider15 );
filtreso = sendKnobIfChanged( 48, filtreso, slider16 );
filtattk = sendKnobIfChanged( 59, filtattk, slider17 );
filtdecy = sendKnobIfChanged( 58, filtdecy, slider18 );
lfoenabl = sendSwitchIfChanged( 70, lfoenabl, slider19 );
lfodesti = sendSwitchIfChanged( 71, lfodesti, slider20 );
lfowavet = sendSwitchIfChanged( 67, lfowavet, slider21 );
lforandm = sendSwitchIfChanged( 66, lforandm, slider22 );
lfodepth = sendKnobIfChanged( 51, lfodepth, slider23 );
lforate = sendKnobIfChanged( 50, lforate, slider24 );
distort = sendSwitchIfChanged( 69, distort, slider25 );
oscfm = sendSwitchIfChanged( 65, oscfm, slider26 );
glide = sendKnobIfChanged( 53, glide, slider27 );
);
updateSamples = srate * 60 / tempo / updateFreq;
updateCounter + samplesblock >= updateSamples ?
(
updateSamples <= samplesblock ?
(
// Possibly more than one update in the block
samplesLeft = samplesblock;
offset = 0;
while
(
offset += updateSamples - updateCounter;
sendAll();
samplesLeft -= updateSamples - updateCounter;
updateCounter = 0;
samplesLeft >= updateSamples; // Loop condition
);
updateCounter = samplesLeft;
)
:
(
// Block is smaller than updateSamples, just one update
offset = updateCounter + samplesblock - updateSamples;
sendAll();
updateCounter = samplesblock - offset;
);
)
:
(
// Just update counters
updateCounter += samplesblock;
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment