// Copyright 2009 Brian Rzycki
// brzycki at gmail dot com
// Version 1.1
// This is released to the public domain.  Don't blame me if it breaks your hardware. :)

desc:Automation to MIDI RPN/NRPN

slider1:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Channel
slider2:0<0,2,1{RPN,NRPN}>Type
slider3:0<0,127,1{00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F,30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F,40,41,42,43,44,45,46,47,48,49,4A,4B,4C,4D,4E,4F,50,51,52,53,54,55,56,57,58,59,5A,5B,5C,5D,5E,5F,60,61,62,63,64,65,66,67,68,69,6A,6B,6C,6D,6E,6F,70,71,72,73,74,75,76,77,78,79,7A,7B,7C,7D,7E,7F}>MSB Address
slider4:0<0,127,1{00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F,30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F,40,41,42,43,44,45,46,47,48,49,4A,4B,4C,4D,4E,4F,50,51,52,53,54,55,56,57,58,59,5A,5B,5C,5D,5E,5F,60,61,62,63,64,65,66,67,68,69,6A,6B,6C,6D,6E,6F,70,71,72,73,74,75,76,77,78,79,7A,7B,7C,7D,7E,7F}>LSB Address
slider5:0<0,16383,1>Value

@init
val_curr = ceil(slider5);
cc_msg = 176; // 0xB0 or CC messages

@slider
// Bad floats!  You be good little ints like mommy MIDI taught you!
slider5 = ceil(slider5);

val_curr != slider5 ? (
    val_curr = slider5;
    run = 1;
);

@block
run ? (
    slider2 == 0 ? (
        // RPN mode
        cc_msb = 101;
        cc_lsb = 100;
    ) : (
        // NRPN mode
        cc_msb = 99;
        cc_lsb = 98;
    );

    num_msb = slider3;
    num_lsb = slider4;
    val_msb = (val_curr / 128) | 0;
    val_lsb = (val_curr & 127) | 0;

    midisend(offset, (cc_msg + slider1), (cc_msb) | (num_msb * 256)); // MSB Address
    midisend(offset, (cc_msg + slider1), (cc_lsb) | (num_lsb * 256)); // LSB Address
    midisend(offset, (cc_msg + slider1),      (6) | (val_msb * 256)); // MSB Data byte
    midisend(offset, (cc_msg + slider1),     (38) | (val_lsb * 256)); // LSB Data byte

    // The website http://www.philrees.co.uk/nrpnq.htm recommends all RPN/NRPN should
    // send the registered RPN (127,127) after sending a data change.  This prevents
    // a device from accidentally accepting a second change to the RPN/NRPN if CC
    // messages 6 or 38 are sent sometime in the future withouth a corresponding
    // address.
    midisend(offset, (cc_msg + slider1), 32613); // (101 | (127 * 256))
    midisend(offset, (cc_msg + slider1), 32612); // (100 | (127 * 256))

    run = 0;
);
