Skip to content

Commit

Permalink
Release MIDI Split Pitch Bend to CCs v0.5 (Initial Release) (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenTalagan committed Feb 21, 2024
1 parent 7c07d12 commit 99a12ab
Showing 1 changed file with 131 additions and 0 deletions.
131 changes: 131 additions & 0 deletions MIDI/talagan_MIDI Split Pitch Bend to CCs.jsfx
Original file line number Diff line number Diff line change
@@ -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&currency_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();

0 comments on commit 99a12ab

Please sign in to comment.