From 99a12abd264bfb2da185457ed136c8999bee6163 Mon Sep 17 00:00:00 2001 From: Ben Talagan Babut Date: Wed, 21 Feb 2024 22:06:23 +0100 Subject: [PATCH] Release MIDI Split Pitch Bend to CCs v0.5 (Initial Release) (#379) --- .../talagan_MIDI Split Pitch Bend to CCs.jsfx | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 MIDI/talagan_MIDI Split Pitch Bend to CCs.jsfx diff --git a/MIDI/talagan_MIDI Split Pitch Bend to CCs.jsfx b/MIDI/talagan_MIDI Split Pitch Bend to CCs.jsfx new file mode 100644 index 0000000..cad53eb --- /dev/null +++ b/MIDI/talagan_MIDI Split Pitch Bend to CCs.jsfx @@ -0,0 +1,131 @@ +desc: MIDI Split Pitch Bend to CCs +author: Ben 'Talagan' Babut +version: 0.5 +changelog: + - Initial version +donation: + https://www.paypal.com/donate/?business=3YEZMY9D6U8NC&no_recurring=1¤cy_code=EUR +about: + Splits the pitch bend wheel into two CCs, one for the positive, and one for the negative part. + + - Channel Pressure may be used, as CC#128. + - Channels may be set to "same as received" + + The rest should be straight forward. + +slider1:0<0,15,0{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Input Pitch Bend Channel + +slider2:1<0,128,1{0 Bank Sel M,1 Mod Wheel M,2 Breath M,3,4 Foot P M,5 Porta M,6 Data Entry M,7 Vol M,8 Balance M,9,10 Pan M,11 Expression M,12 Ctrl 1 M,13 Ctrl 2 M,14,15,16 GP Slider 1,17 GP Slider 2,18 GP Slider 3,19 GP Slider 4,20,21,22,23,24,25,26,27,28,29,30,31,32 Bank Sel L,33 Mod Wheel L,34 Breath L,35,36 Foot P L,37 Porta L,38 Data Entry L,39 Vol L,40 Balance L,41,42 Pan L,43 Expression L,44 Ctrl 1 L,45 Ctrl 2 L,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 Hold P sw,65 Porta sw,66 Sustenuto sw,67 Soft P sw,68 Legato P sw,69 Hold 2 P sw,70 S.Variation,71 S.Timbre,72 S.Release,73 S.Attack,74 S.Brightness,75 S.Ctrl 6,76 S.Ctrl 7,77 S.Ctrl 8,78 S.Ctrl 9,79 S.Ctrl 10,80 GP B.1 sw,81 GP B.2 sw,82 GP B.3 sw,83 GP B.4 sw,84,85,86,87,88,89,90,91 Effects Lv,92 Trem Lv,93 Chorus Lv,94 Celeste Lv,95 Phaser Lv,96 Data B. Inc,97 Data B. Dec,98 NRP L,99 NRP M,100 RP L,101 RP M,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,Virtual 128 Channel Pressure}>Positive part CC num +slider3:16<0,16,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,same as received}> Positive part Channel + +slider4:1<0,128,1{0 Bank Sel M,1 Mod Wheel M,2 Breath M,3,4 Foot P M,5 Porta M,6 Data Entry M,7 Vol M,8 Balance M,9,10 Pan M,11 Expression M,12 Ctrl 1 M,13 Ctrl 2 M,14,15,16 GP Slider 1,17 GP Slider 2,18 GP Slider 3,19 GP Slider 4,20,21,22,23,24,25,26,27,28,29,30,31,32 Bank Sel L,33 Mod Wheel L,34 Breath L,35,36 Foot P L,37 Porta L,38 Data Entry L,39 Vol L,40 Balance L,41,42 Pan L,43 Expression L,44 Ctrl 1 L,45 Ctrl 2 L,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 Hold P sw,65 Porta sw,66 Sustenuto sw,67 Soft P sw,68 Legato P sw,69 Hold 2 P sw,70 S.Variation,71 S.Timbre,72 S.Release,73 S.Attack,74 S.Brightness,75 S.Ctrl 6,76 S.Ctrl 7,77 S.Ctrl 8,78 S.Ctrl 9,79 S.Ctrl 10,80 GP B.1 sw,81 GP B.2 sw,82 GP B.3 sw,83 GP B.4 sw,84,85,86,87,88,89,90,91 Effects Lv,92 Trem Lv,93 Chorus Lv,94 Celeste Lv,95 Phaser Lv,96 Data B. Inc,97 Data B. Dec,98 NRP L,99 NRP M,100 RP L,101 RP M,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,Virtual 128 Channel Pressure}>Negative part CC num +slider5:16<0,16,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,same as received}> Negative part Channel + +slider6:0<0,1,1{no, yes}>Passthrough original PB event + +// Notes : +// Pitch bend goes from 0 to 0x3FFF, center value is 0x2000. +// There are thus 0x4000 possible values +// +// - [0x0000 - 0x1FFF] is the negative part, it makes 0x2000 possible values, in ReaControlMIDI [-8192..-1] +// - 0x2000 is the zero +// - [0x2001 - 0x3FFF] is the positive part, it makes 0x1FFF possible values, in ReaControlMIDI [1..8191] +// +// It is not symmetrical, between the positive and negative part, so be careful when performing calculations on those values. + +@init + +function outChanForNegativePart() +( + (slider5 == 16)?(slider1):(slider5); +); +function outChanForPositivePart() +( + (slider3 == 16)?(slider1):(slider3); +); +function roundi(valf) ( + floor(valf+0.5) | 0; +); + +@block + +MSG_CC = 11; +MSG_CP = 13; +MSG_PITCH_BEND = 14; + +last_zone = 0; + +function emitCC(offset, chan, ccnum, ccval) + local(msg1,msg2,msg3) +( + (ccnum == 128)?( + // Channel pressure + midisend(offset, ((MSG_CP<<4)|chan), roundi(ccval), 0); + ):( + // Standard CC + midisend(offset, ((MSG_CC<<4)|chan), ccnum, roundi(ccval)); + ); +); + +function emitNegativeCC(offset, ccval) ( + emitCC(offset, outChanForNegativePart(), slider4, ccval); +); + +function emitPositiveCC(offset, ccval) ( + emitCC(offset, outChanForPositivePart(), slider2, ccval); +); + +function handlePBEvent(offset,msg1,msg2,msg3) + local(type, val, cc_val) +( + val = ((msg3 & 0x7F) << 7) | (msg2 & 0x7F); + val = val - 0x2000; // Center on zero + + (val > 0)?( + cc_val = (val/0x1FFF) * 127; + + emitPositiveCC(offset, cc_val); + + (last_zone < 0)?( emitNegativeCC(offset, 0); ); + + last_zone = 1; + ):( + (val < 0)?( + cc_val = (-val/0x2000) * 127; + + emitNegativeCC(offset, cc_val); + + (last_zone > 0)?( emitPositiveCC(offset, 0); ); + + last_zone = -1; + ):( + cc_val = 0; + + emitNegativeCC(offset, 0); + emitPositiveCC(offset, 0); + + last_zone = 0; + )); +); + +function listenToMidiEvents() + local(type,chan,offset,msg1,msg2,msg3) +( + while(midirecv(offset,msg1,msg2,msg3)) ( + type = (msg1 >> 4) & 0x0F; + chan = (msg1 & 0x0F); + + (type == MSG_PITCH_BEND && chan == slider1 )?( + // Handle Pitch Bend + handlePBEvent(offset,msg1,msg2,msg3); + + // Passthrough if asked + (slider6)?(midisend(offset,msg1,msg2,msg3)); + ):( + midisend(offset,msg1,msg2,msg3); + ); + ); +); + +listenToMidiEvents(); +