diff --git a/pkgs/reaper/default.nix b/pkgs/reaper/default.nix index 7ca60c0..cede80e 100644 --- a/pkgs/reaper/default.nix +++ b/pkgs/reaper/default.nix @@ -1,7 +1,7 @@ { stdenv, fetchurl, autoPatchelfHook, makeWrapper -, alsaLib, xorg -, gnome3, gtk3, pango, gdk_pixbuf, cairo, glib, freetype -, libpulseaudio, libjack2, xdg_utils +, alsaLib, xorg, libjack2 +, gtk3, pango, gdk-pixbuf, cairo, glib, freetype +, libpulseaudio, xdg_utils }: stdenv.mkDerivation rec { @@ -21,7 +21,7 @@ stdenv.mkDerivation rec { xorg.libX11 xorg.libXi - gdk_pixbuf + gdk-pixbuf pango cairo glib @@ -43,8 +43,9 @@ stdenv.mkDerivation rec { rm $out/opt/REAPER/uninstall-reaper.sh wrapProgram $out/opt/REAPER/reaper \ - --prefix LD_LIBRARY_PATH : ${stdenv.lib.makeLibraryPath [ libpulseaudio libjack2 ]} + --prefix LD_LIBRARY_PATH : "${stdenv.lib.makeLibraryPath [ libpulseaudio libjack2 ]}" + cp -rv ${./jsfx}/* $out/opt/REAPER/InstallData/Effects/ mkdir $out/bin ln -s $out/opt/REAPER/reaper $out/bin/ @@ -53,8 +54,9 @@ stdenv.mkDerivation rec { meta = with stdenv.lib; { description = "Digital audio workstation"; - homepage = https://www.reaper.fm/; + homepage = "https://www.reaper.fm/"; license = licenses.unfree; platforms = [ "x86_64-linux" ]; + maintainers = with maintainers; [ jfrankenau ]; }; } diff --git a/pkgs/reaper/jsfx/AS_Midi_monoizer b/pkgs/reaper/jsfx/AS_Midi_monoizer new file mode 100644 index 0000000..2ccfefb --- /dev/null +++ b/pkgs/reaper/jsfx/AS_Midi_monoizer @@ -0,0 +1,118 @@ +desc:Midi Monoizer +/* Midi Monoizer (c)2019 by Andrew Shakinovsky andrew@afrittemple.com + I welcome comments or suggestions. +Description: + Insert this before a VSTi in the chain. It will prevent multiple midi notes from + sounding at the same time. When a note is playing and another note is received, + a note-off is sent for the first note before(*) the new note is sent. This is akin + to typical monosynths when you are holding a key and then press and release another + key: the first key plays, then the second, and when you release the second, the first + key will play again. A lot of VSTi's behave in this way, but there are some that do + not, and that is where this becomes helpful. + + (*) will be sent after the note on depending on the legato slider. If the legato slider + is no zero, the note off will be delayed by that many samples to allow the synth to + treat it as legato playing +*/ +slider1:0<0,256>Legato Delay Samples +@init +stackptr=-1; +// array offsetting (there is only one local mem space) +stacknote=0; +stackvel=1024; +stackchan=2048; +nno_Off=0; +nno_Chan=0; +nno_Note=0; +@block + +// play note off, applying legator delay +function note_off(pos, chan, note) ( + // make sure it fits in this block given the delay + pos+slider1 < samplesblock ? ( + midisend(pos+slider1,0x80 | chan, note); + ) : ( + // doesn't belong in this block, send it in the next block + nno_Off = 1 + ((pos+slider1) - samplesblock); + nno_Chan=chan; + nno_Note=note; + ); +); + +// do we have a note off to send? +nno_Off ? ( + midisend(nno_Off,0x80 | nno_Chan, nno_Note); + nno_Off=0; +); + +while ( + // if we receive a message + midirecv(ofs, msg1, msg23) ? ( + + status = msg1 & 0xF0; // hi 4 bits + chan = msg1 & 0x0F; // low 4 bits + note = msg23 & 0xFF; //low order byte is note + velocity = msg23 >> 8; // high order byte is velocity + + // if its a Note On + status == 0x90 && velocity ? ( + // if we have items on stack + stackptr > -1 ? ( + note_off(ofs, stackchan[stackptr], stacknote[stackptr]); + ); + + // push curent new note to stack + stackptr+=1; + stacknote[stackptr]=note; + stackvel[stackptr]=velocity; + stackchan[stackptr]=chan; + ); + + // if its a Note Off + status == 0x80 || (status == 0x90 && !velocity) ? ( + + // if the note doesn't match top of stack, remove it below in the stack + // shifting everything down (we don't care about it just get rid of it) + note != stacknote[stackptr] ? ( + i=0; + rp=0; + while(i <= stackptr) ( + stacknote[i]==note ? ( // if it matches the note, move our read position + rp += 1; + ); + // copy source to target + stacknote[i] = stacknote[rp]; + stackvel[i] = stackvel[rp]; + stackchan[i] = stackchan[rp]; + i += 1; + rp += 1; + ); + // set new top of stack + stackptr-= (rp-i); + + ) : ( // otherwise, note matches top of stack ... + stackptr > -1 ? ( + // pop stack + stackptr-=1; + // send note on for tos (if any) + midisend(ofs,0x90 | stackchan[stackptr], + (stackvel[stackptr] << 8) | stacknote[stackptr]); + ); + ); + ): + + // All Notes Off + status == 0xB0 && cc == 123 & n ? ( + stackptr=-1; // discard all + ); + + // send original incoming message, but if it's a note off, apply delay + msg1 ? ( + status == 0x80 || (status == 0x90 && !velocity) ? ( + note_off(ofs, chan, note); + ):( + midisend(ofs, msg1, msg23); + ); + ); + ); // if we recv a msg (otherwise the while will exit) +); // while diff --git a/pkgs/reaper/jsfx/MB_Filter2 b/pkgs/reaper/jsfx/MB_Filter2 new file mode 100644 index 0000000..17bd958 --- /dev/null +++ b/pkgs/reaper/jsfx/MB_Filter2 @@ -0,0 +1,94 @@ +// MB MIDI Event Filter2 +// 16.05.2010 + +desc:MB MIDI Event Filter2 (v1.0) + +slider1:0<0,17,1{Off,All,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Channel for filters +slider2:0<0,16,1{Same as input,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Channel for output +slider3:0<0,1,1{Off,On}>Pitch Wheel filter +slider4:0<0,1,1{Off,On}>Polyphonic Aftertouch filter +slider5:0<0,1,1{Off,On}>Channel Aftertouch filter +slider6:0<0,1,1{Off,On}>Program Change filter +slider7:0<0,129,1{Off,All,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>Control Change filter #1 +slider8:0<0,129,1{Off,All,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>Control Change filter #2 +slider9:0<0,129,1{Off,All,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>Control Change filter #3 +slider10:0<0,129,1{Off,All,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>Control Change filter #4 + + +in_pin:none +out_pin:none + +@init + NOTE_OFF = $x80; // note off MIDI message code + NOTE_ON = $x90; // note on MIDI message code + AFTERTOUCH_POLY = $xA0; // poly aftertouch MIDI message code + CONTROL_CHANGE = $xB0; // control change MIDI message code + PROGRAM_CHANGE = $xC0; // program change MIDI message code + AFTERTOUCH_CHANNEL = $xD0; // channel aftertouch MIDI message code + PITCH_BEND = $xE0; // pitch bend MIDI message code + OTHER = $xF0; + +@block +while +( + midirecv(mpos, msg1, msg23) ? + ( + // get message components + msg = (msg1 & $xf0); // message type nibble + channel = (msg1 & $x0f) + 1; // channel nibble + eat = 0; + + ( + ((msg != 0) && (msg != OTHER) && ((slider1 == 1) || (slider1 == channel + 1)))) ? + ( + lastmsg = msg; + + (msg == CONTROL_CHANGE) ? // control change filter + ( + cnum = (msg23 & $xff); + ( + ((slider7 == 1) || (slider7 == cnum + 2)) || + ((slider8 == 1) || (slider8 == cnum + 2)) || + ((slider9 == 1) || (slider9 == cnum + 2)) || + ((slider10 == 1) || (slider10 == cnum + 2)) + ) ? + ( + eat = 1; + ); + ); + + ((msg == PITCH_BEND) && (slider3 == 1)) ? // pitch bend filter + ( + eat = 1; + ); + + ((msg == AFTERTOUCH_POLY) && (slider4 == 1)) ? // polyphonic aftertouch filter + ( + eat = 1; + ); + + ((msg == AFTERTOUCH_CHANNEL) && (slider5 == 1)) ? // polyphonic aftertouch filter + ( + eat = 1; + ); + + ((msg == PROGRAM_CHANGE) && (slider6 == 1)) ? // program changes + ( + eat = 1; + ); + ); + + (eat == 0) ? + ( + // channel remap + ((msg != OTHER) && (slider2 > 0)) ? + ( + msg1 = msg | (slider2 - 1); + ); + + midisend(mpos, msg1, msg23); + ); + ); + + msg1; +); diff --git a/pkgs/reaper/jsfx/MB_Filter2.pdf b/pkgs/reaper/jsfx/MB_Filter2.pdf new file mode 100644 index 0000000..3773b59 Binary files /dev/null and b/pkgs/reaper/jsfx/MB_Filter2.pdf differ