/** * Gemini CDMP-7000 controller script v1.2 * For Mixxx 1.11.0 * Written by djtrinidad * Copyright 2014 **/ // Changelog v1.2 // Fixed clearing/lighting leds for hotcues if song has them set or not // Incorporated Pitch Ranges into Button/LCD // Incorprated BPM in LCD (may still not happen on first load) // Updates LCD with Vinyl and Hotcue messages // ---- remaining issues // slip mode doesn't work unless you manually turn it off (disable needs to be called on wheel hand lift) // no flashing play buttons, they turn off after first use (need to turn back on after track stop) // auto cue button doesn't do anything, easy fix // back button doesn't toggle directory mode // Set Master Tempo to Keylock, not sure what it is now // many more bug fixes where found // every once in a while scratch mode ignores vinyl button, hard to reproduce it's intermitent // Todo: // Song title to LCD (doesn't look possible with 1.11) // Elapsed time to LCD // implement engine connects // Work towards port to Mixxx 1.12 later // ------------------------------------------ // --- Initialization Functions --- // ------------------------------------------ function cdmp7000() {} // Initialize variables // cdmp7000.reverse_play_d1 = false; cdmp7000.reverse_play_d2 = false; directoryactive = false; // Global variables // cdmp7000.pitchRanges = [ 0.08, 0.16, 0.25, 0.5, 0.100 ]; // Available pitch ranges cdmp7000.sysex = [0xF0, 0x7D, 0x01]; // Preamble for all SysEx messages and song info for this device cdmp7000.LCD_CUE = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x63, 0x75, 0x65, 0x30, 0x3E ]; cdmp7000.LCD_CUE1 = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x63, 0x75, 0x65, 0x31, 0x3E ]; cdmp7000.LCD_CUE2 = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x63, 0x75, 0x65, 0x32, 0x3E ]; cdmp7000.LCD_CUE3 = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x63, 0x75, 0x65, 0x33, 0x3E ]; cdmp7000.LCD_LOOP_IN = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x6C, 0x69, 0x6E, 0x3E ]; cdmp7000.LCD_LOOP_OUT = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x6C, 0x6F, 0x75, 0x74, 0x3E ]; //cdmp7000.LCD_PLAY_POS = [0xF0, 0x7D, 0x01, 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x70, 0x6C, 0x61, 0x79, 0x3E]; cdmp7000.LCD_PLAY_POS = [0xF0, 0x7D, 0x01, 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E]; cdmp7000.LCD_PAUSE_POS = [ 0x3C, 0x74, 0x69, 0x6D, 0x65, 0x3E, 0x3C, 0x70, 0x61, 0x75, 0x73, 0x65, 0x3E]; cdmp7000.LCD_BPM = [0xF0, 0x7D, 0x01, 0x3C, 0x62, 0x70, 0x6D, 0x3E]; cdmp7000.LCD_PITCH = [0xF0, 0x7D, 0x01, 0x3C, 0x70, 0x69, 0x74, 0x63, 0x68, 0x3E]; cdmp7000.LCD_RANGE = [0xF0, 0x7D, 0x01, 0x3C, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x3E ]; cdmp7000.LCD_FX_PARAM = [ 0x3C, 0x65, 0x66, 0x78, 0x3E ]; // Format! // may be midi.sendSysexMsg(cdmp7000.sysex.concat([cdmp7000.LCD_BPM],message.toInt(), 0xF7),7+message.length); // var message = "Whatever"; // length can be adjusted, preamble is 3 bytes, plus close byte is 4 // Functions - init & shutdown // cdmp7000.init = function (channel, control, value, status, group) { cdmp7000.vinylButton_d1 = false; cdmp7000.memoButton_d1 = false; cdmp7000.fx1_state_d1 = false; cdmp7000.fx2_state_d1 = false; cdmp7000.fx3_state_d1 = false; cdmp7000.slip_state_d1 = false; cdmp7000.vinylButton_d2 = false; cdmp7000.memoButton_d2 = false; cdmp7000.fx1_state_d2 = false; cdmp7000.fx2_state_d2 = false; cdmp7000.fx3_state_d2 = false; cdmp7000.slip_state_d2 = false; cdmp7000.firstDeckGroup = "[Channel1]"; cdmp7000.secondDeckGroup = "[Channel2]"; engine.setValue(cdmp7000.firstDeckGroup,'rateRange', 0.08); engine.setValue(cdmp7000.secondDeckGroup,'rateRange', 0.08); engine.connectControl(cdmp7000.firstDeckGroup,"rate","cdmp7000.rate_d1"); engine.connectControl(cdmp7000.secondDeckGroup,"rate","cdmp7000.rate_d2"); // may need to add a connect here to turn play led on when stop is pressed // Turn off all leds to begin with for (i=0x01; i<=0x60; i++) midi.sendShortMsg(0x90,i,0x00); // Factory lcd clear method midi.sendSysexMsg(cdmp7000.sysex.concat([0x3C, 0x62, 0x79, 0x65, 0x3E, 0xF7]),9); // send welcome message message = "MIXXX<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); // sendto lcd song name slot } // Shutdown Function cdmp7000.shutdown = function() { for (i=0x01; i<=0x60; i++) midi.sendShortMsg(0x90,i,0x00); // Turn off all LEDs // lcd clear method midi.sendSysexMsg(cdmp7000.sysex.concat([0x3C, 0x62, 0x79, 0x65, 0x3E, 0xF7]),9); } /// ----- End of Init/Shutdown & Initialization section cdmp7000.playPositionChanged = function (channel, control, value, status, group) { var currentValue2 = engine.getValue(group,"playposition"); print ("Play Pos:"+currentValue2); } // ------------------------------------------ // --- Vinyl/Reverse/Slip Functions --- // ------------------------------------------ // Toggle vinyl mode deck 1 cdmp7000.vinyl_toggle_d1 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.vinylButton_d1 == false)) { cdmp7000.vinylButton_d1 = true; midi.sendShortMsg(0x90,0x0E,0x7F); cdmp7000.setSongLcd("vinyl", 1); } else if ((value == 0x7f) && (cdmp7000.vinylButton_d1 == true)) { cdmp7000.vinylButton_d1 = false; midi.sendShortMsg(0x90,0x0E,0x00); cdmp7000.setSongLcd("vinyl", 0); } } // Toggle vinyl mode deck 2 cdmp7000.vinyl_toggle_d2 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.vinylButton_d2 == false)) { cdmp7000.vinylButton_d2 = true; midi.sendShortMsg(0x90,0x0E,0x7F); cdmp7000.setSongLcd("vinyl", 1); } else if ((value == 0x7f) && (cdmp7000.vinylButton_d2 == true)) { cdmp7000.vinylButton_d2 = false; midi.sendShortMsg(0x90,0x0E,0x00); cdmp7000.setSongLcd("vinyl", 0); } } // Toggle reverse for deck 1, not sure if this works right cdmp7000.reverse_toggle_d1 = function(channel, control, value, status, group) { if (value == 0) { return; } if (cdmp7000.reverse_play_d1){ cdmp7000.reverse_play_d1 = false; midi.sendShortMsg(0x90,0x1E,0x00); } else if (!cdmp7000.reverse_play_d1){ cdmp7000.reverse_play_d1 = true; midi.sendShortMsg(0x90,0x1E,0x7F); } engine.setValue(group,'reverse',cdmp7000.reverse_play_d1); } // Toggle reverse for deck 2, not sure if this works right cdmp7000.reverse_toggle_d2 = function(channel, control, value, status, group) { if (value == 0) { return; } if (cdmp7000.reverse_play_d2){ cdmp7000.reverse_play_d2 = false; midi.sendShortMsg(0x90,0x1E,0x00); } else if (!cdmp7000.reverse_play_d2){ cdmp7000.reverse_play_d2 = true; midi.sendShortMsg(0x90,0x1E,0x7F); } engine.setValue(group,'reverse',cdmp7000.reverse_play_d2); } // slip mode (doesn't work, unless you press again to disable. Disable should occur on wheel touch disable) cdmp7000.slip_enabled_d1 = function(channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.slip_state_d1 == false)) { cdmp7000.slip_state_d1 = true; midi.sendShortMsg(0x90,0x1F,0x7F); engine.setValue(group, 'slip_enabled', 1); } else if ((value == 0x7f) && (cdmp7000.slip_state_d1 == true)) { cdmp7000.slip_state_d1 = false; midi.sendShortMsg(0x90,0x1F,0x00); engine.setValue(group, 'slip_enabled', 0); } } cdmp7000.slip_enabled_d2 = function(channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.slip_state_d2 == false)) { cdmp7000.slip_state_d2 = true; midi.sendShortMsg(0x90,0x1F,0x7F); engine.setValue(group, 'slip_enabled', 1); } else if ((value == 0x7f) && (cdmp7000.slip_state_d2 == true)) { cdmp7000.slip_state_d2 = false; midi.sendShortMsg(0x90,0x1F,0x00); engine.setValue(group, 'slip_enabled', 0); } } // ------------------------------------------ // -------- Jog Wheel Functions -------- // ------------------------------------------ // Deck 1 - Step 1 If wheels are touched and vinyl is on, then scratch is enabled cdmp7000.wheelTouch_d1 = function (channel, control, value, status) { if ((value == 0x7f) && (cdmp7000.vinylButton_d1 == true)) { var alpha = 1.0/8; var beta = alpha/32; engine.scratchEnable(1, 128, 33+1/3, alpha,beta); } else { engine.scratchDisable(1); } } // Deck 1 - Step 2 If scratch is enabled by wheelTouch_d1 then scratch on wheel turn, otherwise jog cdmp7000.wheelTurn_d1 = function (channel, control, value, status, group) { var newValue=(value-64); if (!engine.isScratching(1)) { engine.setValue(group, "jog", newValue); return; } engine.scratchTick(1,newValue); } // Deck 2 - Step 1 If wheels are touched and vinyl is on, then scratch is enabled cdmp7000.wheelTouch_d2 = function (channel, control, value, status) { if ((value == 0x7f) && (cdmp7000.vinylButton_d2 == true)) { var alpha = 1.0/8; var beta = alpha/32; engine.scratchEnable(2, 128, 33+1/3, alpha,beta); } else { engine.scratchDisable(2); } } // Deck 2 - Step 2 If scratch is enabled by wheelTouch_d2 then scratch on wheel turn, otherwise jog cdmp7000.wheelTurn_d2 = function (channel, control, value, status, group) { var newValue=(value-64); // if vinyl mode isn't on then just jog if (!engine.isScratching(2)) { engine.setValue(group, "jog", newValue); return; } engine.scratchTick(2,newValue); } // ------------------------------------------ // ----- Track Selection Functions ----- // ------------------------------------------ // Back button - Directory/File future code // Select Track knob - goes positive and negative cdmp7000.select_track_knob_pos = function(channel, control, value, status, group) { // The encoder goes positive and negative if (value >= 0x01 && value <= 0x1e) { value = value; } else if (value >= 0x62 && value <= 0x7f) { value = 0 - (0x7f-value+1); } else { return; } engine.setValue(group,'SelectTrackKnob',value); }; cdmp7000.select_track_knob_neg = function(channel, control, value, status, group) { if (value >= 0x01 && value <= 0x1e) { value = value; } else if (value >= 0x62 && value <= 0x7f) { value = 0 - (0x7f-value-1); } else { return; } engine.setValue(group,'SelectTrackKnob',value); }; cdmp7000.ToggleDirectory = function(channel, control, value, status, group) { if (value == 0x7f) { print( "Directory Mode!: Coming soon!"); } } // ------------------------------------------ // ------ Hotcue/Loops Functions -------- // ------------------------------------------ // Toggle memo mode deck 1 - next hotcue pushed is deleted if on, if false no action cdmp7000.memoActive_d1 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.memoButton_d1 == false)) { cdmp7000.memoButton_d1 = true; midi.sendShortMsg(0x90,0x08,0x7F); } else if ((value == 0x7f) && (cdmp7000.memoButton_d1 == true)) { cdmp7000.memoButton_d1 = false; midi.sendShortMsg(0x90,0x08,0x00); } } // Toggle memo mode deck 2 - next hotcue pushed is deleted if on, if false no action cdmp7000.memoActive_d2 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.memoButton_d2 == false)) { cdmp7000.memoButton_d2 = true; midi.sendShortMsg(0x90,0x08,0x7F); } else if ((value == 0x7f) && (cdmp7000.memoButton_d2 == true)) { cdmp7000.memoButton_d2 = false; midi.sendShortMsg(0x90,0x08,0x00); } } // Deck 1 - HotCues - Checks for memo button active to delete hotcue and turn off LED cdmp7000.hotcue_activate_d1 = function(group,hotcue,value,led) { hotcue_state_d1 = 'hotcue_' + hotcue + '_enabled'; result = engine.getValue("[Channel1]", hotcue_state_d1); if ((value == 0x7f) && (cdmp7000.memoButton_d1 == true)) { key = 'hotcue_' + hotcue + '_clear'; engine.setValue(group,key,value); midi.sendShortMsg(0x90,0x08,0x00); // turn off memo led midi.sendShortMsg(0x90,led,0x00); // turn off efx led cdmp7000.memoButton_d1 = false; cdmp7000.setSongLcd(key, 1); } else if ((value == 0x7f) && (cdmp7000.memoButton_d1 == false) && (result == 0)) { key = 'hotcue_' + hotcue + '_set'; engine.setValue(group,key,value); midi.sendShortMsg(0x90,led,0x7F); cdmp7000.setSongLcd(key, 1); } else { key = 'hotcue_' + hotcue + '_gotoandplay'; engine.setValue(group,key,value); } } // Deck 1 - Hotcues - Actually does the work and calls cdmp7000.hotcue_activate_d1 cdmp7000.hotcue_1_activate_d1 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d1(group,1,value, 0x05); } cdmp7000.hotcue_2_activate_d1 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d1(group,2,value, 0x06); } cdmp7000.hotcue_3_activate_d1 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d1(group,3,value, 0x07); } // Deck 2 - HotCues - Checks for memo button active to delete hotcue and turn off LED cdmp7000.hotcue_activate_d2 = function(group,hotcue,value,led) { hotcue_state_d2 = 'hotcue_' + hotcue + '_enabled'; result = engine.getValue("[Channel2]", hotcue_state_d2); if ((value == 0x7f) && (cdmp7000.memoButton_d2 == true)) { key = 'hotcue_' + hotcue + '_clear'; engine.setValue(group,key,value); midi.sendShortMsg(0x90,0x08,0x00); // turn off memo led midi.sendShortMsg(0x90,led,0x00); // turn off efx led cdmp7000.memoButton_d2 = false; cdmp7000.setSongLcd(key, 1); } else if ((value == 0x7f) && (cdmp7000.memoButton_d2 == false) && (result == 0)) { key = 'hotcue_' + hotcue + '_set'; engine.setValue(group,key,value); midi.sendShortMsg(0x90,led,0x7F); cdmp7000.setSongLcd(key, 1); } else { key = 'hotcue_' + hotcue + '_gotoandplay'; engine.setValue(group,key,value); } } // Deck 2 - Hotcues - Actually does the work and calls cdmp7000.hotcue_activate_d2 cdmp7000.hotcue_1_activate_d2 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d2(group,1,value, 0x05); } cdmp7000.hotcue_2_activate_d2 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d2(group,2,value, 0x06); } cdmp7000.hotcue_3_activate_d2 = function(channel, control, value, status, group) { cdmp7000.hotcue_activate_d2(group,3,value, 0x07); } // Loop functions cdmp7000.loopIn = function(channel, control, value, status, group) { if (!value) return; engine.setValue(group, "loop_in", status?1:0); midi.sendShortMsg(0x90,0x10,0x7F); // turn on the loop_in led return; } cdmp7000.loopOut = function(channel, control, value, status, group) { if (!value) return; engine.setValue(group, "loop_out", status?1:0); midi.sendShortMsg(0x90,0x11,0x7F); // turn on the loop_out led return; } cdmp7000.loopExit = function(channel, control, value, status, group) { if (!value) return; engine.setValue(group, "reloop_exit", status?1:0); midi.sendShortMsg(0x90,0x10,0x00); // turn off the loop_in led midi.sendShortMsg(0x90,0x11,0x00); // turn off the loop_out led return; } // ------------------------------------------ // -------- Effects Functions ----------- // ------------------------------------------ // Need to add efx4,efx5,efx6 but what to do with them? also incorporate jog function for effect // Deck 1 efx cdmp7000.fx1_enable_d1 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx1_state_d1 == false)) { cdmp7000.fx1_state_d1 = true; midi.sendShortMsg(0x90, 0x14, 0x7F); engine.setValue(group, "filterHighKill", cdmp7000.fx1_state_d1); engine.setValue(group, "filterMidKill", cdmp7000.fx1_state_d1); } else if ((value == 0x7f) && (cdmp7000.fx1_state_d1 == true)) { cdmp7000.fx1_state_d1 = false; midi.sendShortMsg(0x90,0x14,0x00); engine.setValue(group, "filterHighKill", cdmp7000.fx1_state_d1); engine.setValue(group, "filterMidKill", cdmp7000.fx1_state_d1); } } cdmp7000.fx2_enable_d1 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx2_state_d1 == false)) { cdmp7000.fx2_state_d1 = true; midi.sendShortMsg(0x90, 0x15, 0x7F); engine.setValue(group, "flanger", cdmp7000.fx2_state_d1); } else if ((value == 0x7f) && (cdmp7000.fx2_state_d1 == true)) { cdmp7000.fx2_state_d1 = false; midi.sendShortMsg(0x90,0x15,0x00); engine.setValue(group, "flanger", cdmp7000.fx2_state_d1); } } cdmp7000.fx3_enable_d1 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx3_state_d1 == false)) { cdmp7000.fx3_state_d1 = true; midi.sendShortMsg(0x90, 0x16, 0x7F); engine.brake(1, true); } else if ((value == 0x7f) && (cdmp7000.fx3_state_d1 == true)) { cdmp7000.fx3_state_d1 = false; midi.sendShortMsg(0x90,0x16,0x00); engine.brake(1, false); } } // Deck 2 efx cdmp7000.fx1_enable_d2 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx1_state_d2 == false)) { cdmp7000.fx1_state_d2 = true; midi.sendShortMsg(0x90, 0x14, 0x7F); engine.setValue(group, "filterHighKill", cdmp7000.fx1_state_d2); engine.setValue(group, "filterMidKill", cdmp7000.fx1_state_d2); } else if ((value == 0x7f) && (cdmp7000.fx1_state_d2 == true)) { cdmp7000.fx1_state_d2 = false; midi.sendShortMsg(0x90,0x14,0x00); engine.setValue(group, "filterHighKill", cdmp7000.fx1_state_d2); engine.setValue(group, "filterMidKill", cdmp7000.fx1_state_d2); } } cdmp7000.fx2_enable_d2 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx2_state_d2 == false)) { cdmp7000.fx2_state_d2 = true; midi.sendShortMsg(0x90, 0x15, 0x7F); engine.setValue(group, "flanger", cdmp7000.fx2_state_d2); } else if ((value == 0x7f) && (cdmp7000.fx2_state_d2 == true)) { cdmp7000.fx2_state_d2 = false; midi.sendShortMsg(0x90,0x15,0x00); engine.setValue(group, "flanger", cdmp7000.fx2_state_d2); } } cdmp7000.fx3_enable_d2 = function (channel, control, value, status, group) { if ((value == 0x7f) && (cdmp7000.fx3_state_d2 == false)) { cdmp7000.fx3_state_d2 = true; midi.sendShortMsg(0x90, 0x16, 0x7F); engine.brake(1, true); } else if ((value == 0x7f) && (cdmp7000.fx3_state_d2 == true)) { cdmp7000.fx3_state_d2 = false; midi.sendShortMsg(0x90,0x16,0x00); engine.brake(1, false); } } // ------------------------------------------ // --- Load Track - Cue/Play LED Functions --- // ------------------------------------------ cdmp7000.LoadTrack = function(channel, control, value, status, group) { // Load the selected track in the corresponding deck only if the track is paused if(value && engine.getValue(group, "play") != 1) { engine.setValue(group, "LoadSelectedTrack", 1); // Turn on Cue led solid & flash play button (this doesn't flash maybe a connect?) // cue midi.sendShortMsg(0x90,0x01,0x7F); // play midi.sendShortMsg(0x90,0x02,0x7F); } else engine.setValue(group, "LoadSelectedTrack", 0); // (NEW) check song for hotcues set, turn on appropriate led if needed or turn off from previous song if(engine.getValue(group, "hotcue_1_enabled") == 1) { midi.sendShortMsg(0x90,0x05,0x7F); } else { midi.sendShortMsg(0x90,0x05,0x00); } if(engine.getValue(group, "hotcue_2_enabled") == 1) { midi.sendShortMsg(0x90,0x06,0x7F); } else { midi.sendShortMsg(0x90,0x06,0x00); } if(engine.getValue(group, "hotcue_3_enabled") == 1) { midi.sendShortMsg(0x90,0x07,0x7F); } else { midi.sendShortMsg(0x90,0x07,0x00); } var currentBpm = engine.getValue(group,'bpm'); var currentRange = engine.getValue(group,'rateRange'); var currentDur = engine.getValue(group,'duration'); // convert decimal to real number currentRange = currentRange*100 currentRange = Math.round(currentRange); currentDur = currentDur*312 // this is inaccurate, varies by 10 seconds or so and never updates print( "BPM!:"+currentBpm); // for debug print( "Range!:"+currentRange); // for debug print( "Duration!:"+currentDur); // for debug // convert int to string otherwise toInt() will not work currentBpm += '' currentRange += '' currentDur += '' midi.sendSysexMsg(cdmp7000.LCD_BPM.concat(currentBpm.toInt(), 0xF7),9+currentBpm.length); midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(currentRange.toInt(), 0xF7),11+currentRange.length); midi.sendSysexMsg(cdmp7000.LCD_PLAY_POS.concat(currentDur.toInt(), 0x3C, 0x70, 0x6C, 0x61, 0x79, 0x3E, 0xF7),16+currentDur.length); } // ------------------------------------------ // --------- Rate Functions ------------- // ------------------------------------------ cdmp7000.rate_d1 = function (channel, control, value, status, group) { var pitchValue = engine.getValue(cdmp7000.firstDeckGroup,'rate'); var currentBpm = engine.getValue(cdmp7000.firstDeckGroup,'bpm'); pitchValue = pitchValue*10 pitchValue.toFixed(0) pitchValue += '' print( "Deck 1 rate:"+pitchValue); // for debug midi.sendSysexMsg(cdmp7000.LCD_PITCH.concat(pitchValue.toInt(), 0xF7),11+pitchValue.length); // when the pitch slider is changed, we update the bpm as well currentBpm += '' midi.sendSysexMsg(cdmp7000.LCD_BPM.concat(currentBpm.toInt(), 0xF7),9+currentBpm.length); } cdmp7000.rate_d2 = function (channel, control, value, status, group) { var pitchValue = engine.getValue(cdmp7000.secondDeckGroup,'rate'); var currentBpm = engine.getValue(cdmp7000.secondDeckGroup,'bpm'); pitchValue = pitchValue*10 pitchValue.toFixed(0) pitchValue += '' print( "Deck 2 rate:"+pitchValue); // for debug midi.sendSysexMsg(cdmp7000.LCD_PITCH.concat(pitchValue.toInt(), 0xF7),11+pitchValue.length); // when the pitch slider is changed, we update the bpm as well! currentBpm += '' midi.sendSysexMsg(cdmp7000.LCD_BPM.concat(currentBpm.toInt(), 0xF7),9+currentBpm.length); } cdmp7000.rateRange = function (channel, control, value, status, group) { if (value == 0x7f) { var currentRange = engine.getValue(group,'rateRange'); currentRange = currentRange*100; currentRange = Math.round(currentRange); // code to toggle between 8 - 100 range // there has to be a more efficient way of doing this, maybe external lcd update function // set, then get, then update if (currentRange == "4") { engine.setValue(group,'rateRange', 0.08); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } if (currentRange == "8") { engine.setValue(group,'rateRange', 0.16); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } if (currentRange == "16") { engine.setValue(group,'rateRange', 0.24); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } if (currentRange == "24") { engine.setValue(group,'rateRange', 0.50); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } if (currentRange == 50) { engine.setValue(group,'rateRange', 1.00); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } if (currentRange == 100) { engine.setValue(group,'rateRange', 0.04); var newRange = engine.getValue(group,'rateRange'); newRange += '' midi.sendSysexMsg(cdmp7000.LCD_RANGE.concat(newRange.toInt(), 0xF7),11+newRange.length); } } // end if val = 0x7f } // Reproduces features of Gemini firmware cdmp7000.setSongLcd = function (control, value) { if ((control == "hotcue_1_set") && (value == true)) { message = "<artist><title>Hot Cue 1 is set<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "hotcue_1_clear") && (value == true)) { message = "<artist><title>Hot Cue 1 is clear<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "hotcue_2_set") && (value == true)) { message = "<artist><title>Hot Cue 2 is set<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "hotcue_2_clear") && (value == true)) { message = "<artist><title>Hot Cue 2 is clear<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "hotcue_3_set") && (value == true)) { message = "<artist><title>Hot Cue 3 is set<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "hotcue_3_clear") && (value == true)) { message = "<artist><title>Hot Cue 3 is clear<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "vinyl") && (value == true)) { message = "<artist><title>Vinyl On<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } if ((control == "vinyl") && (value == false)) { message = "<artist><title>Vinyl Off<album><genre><length>20<index>0"; midi.sendSysexMsg(cdmp7000.sysex.concat(message.toInt(), 0xF7),4+message.length); } } // end lcdupdates