/*
Anything that is set to OFF (value depends of the slider) is NEVER sent.
There are different options on when to send the info to the external synth, 
the best is probably Seq Start @ 1.1.00, so the data will be sent only if you start playback from the start. 
But there are other options.

For bank and patch info, you need to create a folder in your \REAPER\Data\ folder and create a file for each patch.
The content must be:

50
-1
40

which means that we want to send patch 50, no bank msb, bank lsb = 40.
So any value between -1 and 127 is good.
*/

desc: Read info...

slider1:1<1,16,1>Output Channel
slider2:/GM_Patch:- OFF.txt:GM Patch 

slider3:0<-65,63,1>Pitch Wheel -65 = OFF
slider4:0<-1,127,1>Mod Wheel (CC1) -1 = OFF
slider5:0<-1,127,1>Breath Ctrl (CC2) -1 = OFF
slider6:0<-1,127,1>Ctrl 3 (CC3) -1 = OFF
slider7:0<-1,127,1>Foot Ctrl (CC4) -1 = OFF
slider8:0<-1,127,1>Porta Time (CC5) -1 = OFF
slider9:0<-1,127,1>Data Entry (CC6) -1 = OFF
slider10:64<-1,127,1>Volume (CC7) -1 = OFF
slider11:0<-65,63,1>Balance (CC8) -65 = OFF
slider12:0<-1,127,1>Ctrl 9 (CC9) -1 = OFF
slider13:0<-65,63,1>Pan (CC10) -65 = OFF
slider14:0<-1,127,1>Expression (CC11) -1 = OFF

slider15:0<0,4,1{OFF,NOW,Seq Stop,Seq Start,Seq Start @ 1.1.00}>Update Mode

in_pin:none
out_pin:none

@init
ext_noinit = 1;
seqState = 0;
//UpdateMode = 0;
outChn = 0;
patchfile = 1;
patchchange = 0;
patch = -1;
bankmsb = -1;
banklsb = -1;
cc1 = -1;
cc2 = -1;
cc3 = -1;
cc4 = -1;
cc5 = -1;
cc6 = -1;
cc7 = -1;
cc8 = -65;
cc9 = -1;
cc10 = -65;
cc11 = -1;
pitch = 0;

@slider
outChn = slider1-1;
slider2 = floor(slider2);
slider2 != patchfile ?
(
patchfile = slider2;
fileHandle = file_open(slider2);
fileHandle > 0 && file_text(fileHandle) ?
(
file_var(fileHandle, patch);
file_var(fileHandle, bankmsb);
file_var(fileHandle, banklsb);
file_close(fileHandle);
patchchange = 1;
);
);

slider3 = floor(slider3);
slider4 = floor(slider4);
slider5 = floor(slider5);
slider6 = floor(slider6);
slider7 = floor(slider7);
slider9 = floor(slider9);
slider10 = floor(slider10);
slider11 = floor(slider11);
slider12 = floor(slider12);
slider13 = floor(slider13);
slider14 = floor(slider14);

@block
refresh = 0;
seqstate != play_state&1 ?
(
seqstate = play_state&1;
slider15 > 1 ?
(
seqstate ?
(
refresh = slider15 == 3 || (slider15 == 4 && beat_position == 0);
):(
refresh = slider15 == 2;
);
)
);

slider15 == 1 ?
(
refresh = 1;
slider15 = 0;
);

refresh ?
(
patchchange = 1;
cc1 = -1000;
cc2 = -1000;
cc3 = -1000;
cc4 = -1000;
cc5 = -1000;
cc6 = -1000;
cc7 = -1000;
cc8 = -1000;
cc9 = -1000;
cc10 = -1000;
cc11 = -1000;
pitch = -1000;
);

patchchange ?
(
patchchange = 0;
patch > -1 ?
(
bankmsb > -1 ? midisend(0,$xB0 | outChn, 0 | ($x100*bankmsb));
banklsb > -1 ? midisend(0,$xB0 | outChn, 32 | ($x100*banklsb));
midisend(0,$xC0 | outChn, patch);
);
);

slider3 > -65 && pitch != slider3 ?
(
pitch = slider3;
midisend(offset>=1 ? offset-1 : 0, $xE0+outChn, (((pitch+64)*256) & $x7F00));
);
slider4 > -1 && cc1 != slider4 ?
(
cc1 = slider4;
midisend(0,$xB0 | outChn, 1 | ($x100*cc1));
);
slider5 > -1 && cc2 != slider5 ?
(
cc2 = slider5;
midisend(0,$xB0 | outChn, 2 | ($x100*cc2));
);
slider6 > -1 && cc3 != slider6 ?
(
cc3 = slider6;
midisend(0,$xB0 | outChn, 3 | ($x100*cc3));
);
slider7 > -1 && cc4 != slider7 ?
(
cc4 = slider7;
midisend(0,$xB0 | outChn, 4 | ($x100*cc4));
);
slider8 > -1 && cc5 != slider8 ?
(
cc5 = slider8;
midisend(0,$xB0 | outChn, 5 | ($x100*cc5));
);
slider9 > -1 && cc6 != slider9 ?
(
cc6 = slider9;
midisend(0,$xB0 | outChn, 6 | ($x100*cc6));
);
slider10 > -1 && cc7 != slider10 ?
(
cc7 = slider10;
midisend(0,$xB0 | outChn, 7 | ($x100*cc7));
);
slider11 > -65 && cc8 != slider11 ?
(
cc8 = slider11;
midisend(0,$xB0 | outChn, 8 | ($x100*(cc8+64)));
);
slider12 > -1 && cc9 != slider12 ?
(
cc9 = slider12;
midisend(0,$xB0 | outChn, 9 | ($x100*cc9));
);
slider13 > -65 && cc10 != slider13 ?
(
cc10 = slider13;
midisend(0,$xB0 | outChn, 10 | ($x100*(cc10+64)));
);
slider14 > -1 && cc11 != slider14 ?
(
cc11 = slider14;
midisend(0,$xB0 | outChn, 11 | ($x100*cc11));
);

while
(
midirecv(offset,msg1,msg23) ?
midisend(offset,(msg1 & $xF0) | outChn ,msg23);
);
