MIDI Scripting

Scripts filter MIDI controller data as it passes from the controller to Deckadance and from Deckadance back to the controller, so that they understand each other. The data from Deckadance to the controller is 'controller feedback' and can be used to light buttons etc on the controller, where appropriate. If your controller is not already supported with a script, why not contact the controller manufacturer and let them know about Deckadance and scripting. Ask nicely and they may write you one.

For information on using a script see the MIDI Scripting preferences page.

Making Scripts

Scripts are essentially a list of MIDI input messages from a specific controller linked to Deckadance 2 commands, and Deckadance commands linked to MIDI output messages that light controls or buttons on the controller. For example, when a controller sends a MIDI note message from its play button, you can map that to the play (or any) command in Deckadance, and map the play state to the controller play button light. More complicated behaviors are also possible, such as changing the command a button sends if a shift button is also held, for example.

Script Language

Scripts use the AngelScript language that follows the widely known C / C++ syntax and data types. Writing scripts does require some time and inclination to learn the scripting language and Deckadance 2 commands. Generally we expect scripts to be written by manufacturers or advanced users. A good place to start looking for scripts for your controller is the Deckadance forum. You can also use a script to make a custom version of existing controllers.

To learn more about writing script files, check the script_files sub folder of the Deckadance 2 installation for the following:

Editing Scripts

Drag and drop a script file to Windows Notepad to edit it. MIDI messages are handled in Hexadecimal number format. Deckadance commands are listed in the included dd_commands.h file.

To discover what messages a controller sends, you can either refer to its documentation, or when the MIDI scripting tab is open and you press a button or move a knob or fader, the message recieved is shown, so you can make a note of it to add in the script. Most of the time, the message a button needs to receive to illuminate is the same as the message it sends.

You can also map a controller manually on the normal MIDI mapping editor, that includes a learn function, then export a script file you can continue to edit. Although this wont map LED feedback or any special behaviors. Use two forward slashes '//' before words you want to use as a comment or reminder in the script text, without them actually being included in the script when it runs. This is also useful for excluding parts of the script when testing. Here are basic and intermediate script examples with comments at the various lines of code. Note that scripts are based on C/C++ syntax.

Basic example script

//=================================================================================================================================== // Deckadance Remote Control Basic Test Implementation //=================================================================================================================================== #include "dd_commands.h" void OnStart() { // Not used } void OnMidiMessageReceived(const string &in name, int status, int data, int value) { // stack // The line below converts the MIDI input values of 0 to 127 to 0 to 1 format to link to parameters float value01 = value / 127.0; // NN's if((status & 0xF0) == 0x90 || (status & 0xF0) == 0x80) { switch(data) { //The line below controls the Deckadance Deck A Play command from a MIDI note input 3B. case 0x3B: if(value > 0) set(PLAY_PAUSE_A); break; } } // CC's if((status & 0xF0) == 0xB0) { switch(data) { // The line below controls Deckadance Deck A volume from a MIDI continuous controller input 16. case 0x16: set(VOLUME_A, value01); break; } } return; } void OnTimerCallback() { // stack int off = 0x00; int on = 0x7F; //The line below sends the same MIDI note back to the controller to light the LED, if the play is active in Deckadance. (get(PLAY_PAUSE_A) > 0) ? sendMidiMessage(0x90, 0x3B, on) : sendMidiMessage(0x90, 0x3B, off); return; } void OnStop() { // Not used }

Advanced example script

//=================================================================================================================================== // Deckadance Remote Control Test Implementation //=================================================================================================================================== #include "dd_commands.h" // globals // Variables that exist in the script, used for Shift type behaviors, set the value you want DD to start up using. int ScratchA = 1; int ShiftA = 0; void OnStart() { // Sends messages when the script runs or when you open DD. // In this case a specific sysex command to get the current hardware control positions. // request the status of every item on the control surface at startup sendSysExMessage("F000013F7F4B60000404010703F7"); return; } void OnMidiMessageReceived(const string &in name, int status, int data, int value) { // stack // Adapted MIDI values used in the various links. // For continuous parameters that need input in 0 to 1 format and not the original 0 to 127 MIDI format. float value01 = value / 127.0; // To define a value only when a button is held down. float isDown = (value > 0) ? 1.0 : 0.0; // For values from encoder knobs on the CC section below to increase or decrease parameter values. float valueInc = (value < 0x40) ? -1.0 : 1.0; // NN's // MIDI note messages, mostly used for switching commands or parameter values. if((status & 0xF0) == 0x90 || (status & 0xF0) == 0x80) { switch(data) { //Play button controls the Play command. case 0x3B: if(value > 0) set(PLAY_PAUSE_A); break; //Scratch button sets the ScratchA variable to toggle on or off. case 0x48: if(value > 0) ScratchA = 1 - ScratchA; break; //Jog wheel will only register a held scratch if the Scratch button is also on. case 0x4D: if(ScratchA == 1) set(JOG_SCRATCH_ON_A, isDown); break; //Shift button sets the ShiftA variable to momentary on or off. case 0x61: if(value > 0) {ShiftA = 1; break;} else {ShiftA = 0; break;} //Normally button sets Pitch bend nudge, if Shift is also held down, sets Key lock instead. case 0x45: if (ShiftA == 1) {if(value > 0) set(KEY_LOCK_A); break;} else {set(PITCH_BEND_NUDGE_MINUS_A, isDown); break;} } } // CC's // MIDI controller messages, mostly used to change parameters. if((status & 0xF0) == 0xB0) { switch(data) { // Normal knob or fader. case 0x16: set(VOLUME_A, value01); break; // Jog wheel, second value is pitch bend sensitivity, third value is scratch sensitivity. case 0x19: set(JOG_A, value - 64.0, 0.0001, -0.002); break; // Encoder knob used to increas or decrease a parameter value. case 0x1B: set(EFFECT_PARAM_1_GROUP_A, get(EFFECT_PARAM_1_GROUP_A) + valueInc * 0.1); break; } } return; } void OnTimerCallback() { // stack // MIDI values for lighting LED on or off. Some controllers may support other values for brightness or blinking. int off = 0x00; int on = 0x7F; //Lights the Play button LED when Play is active. (get(PLAY_PAUSE_A) > 0) ? sendMidiMessage(0x90, 0x3B, on) : sendMidiMessage(0x90, 0x3B, off); //Lights the Scratch button on or off if the ScratchA variable is on or off. (ScratchA > 0) ? sendMidiMessage(0x90, 0x48, on) : sendMidiMessage(0x90, 0x48, off); return; } void OnStop() { // Sends messages just before the script stops running when you close Deckadance. // In this case a MIDI note that turns off all LED. sendMidiMessage(0x90, 0x75, 0x00); return; }