Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Hercules-DJ-Control-MK2-scripts.js
- // TODO
- // - LED blink functions
- // - autosync LED with autosync buttton & pitch
- // - test play LED function (buggy)
- function HerculesMK2 () {}
- // defaults
- HerculesMK2.debug = false;
- HerculesMK2.scratchMode = false;
- HerculesMK2.decayLast = new Date().getTime();
- HerculesMK2.decayInterval = 300;
- HerculesMK2.decayRate = 1.5;
- HerculesMK2.leds = {};
- HerculesMK2.joystickValue = false;
- HerculesMK2.buttons123Modes = ["kill", "fx", "cue", "loop"];
- HerculesMK2.buttons123used = {"[Channel1]": false, "[Channel2]": false};
- // LED controller values
- HerculesMK2.ledOn = 0x7F;
- HerculesMK2.ledOff = 0x00;
- HerculesMK2.controls = {
- "inputs": {
- 0x09: { "channel": 1, "name": "cue", "type": "button" },
- 0x03: { "channel": 2, "name": "cue", "type": "button" },
- 0x08: { "channel": 1, "name": "play", "type": "button" },
- 0x02: { "channel": 2, "name": "play", "type": "button" },
- 0x07: { "channel": 1, "name": "fx select", "type": "button","mode": 0 },
- 0x01: { "channel": 2, "name": "fx select", "type": "button","mode": 0 },
- 0x0F: { "channel": 1, "name": "fx 1", "type": "button", "used": false },
- 0x10: { "channel": 2, "name": "fx 1", "type": "button", "used": false },
- 0x0E: { "channel": 1, "name": "fx 2", "type": "button", "used": false },
- 0x11: { "channel": 2, "name": "fx 2", "type": "button", "used": false },
- 0x0D: { "channel": 1, "name": "fx 3", "type": "button", "used": false },
- 0x12: { "channel": 2, "name": "fx 3", "type": "button", "used": false },
- 0x1B: { "channel": 1, "name": "mouse", "type": "button" },
- 0x1C: { "channel": 2, "name": "mouse", "type": "button" },
- 0x34: { "channel": 1, "name": "pitch", "type": "pot" },
- 0x35: { "channel": 2, "name": "pitch", "type": "pot" },
- 0x36: { "channel": 1, "name": "wheel", "type": "pot" },
- 0x37: { "channel": 2, "name": "wheel", "type": "pot" },
- 0x15: { "channel": 1, "name": "pfl", "type": "button" },
- 0x19: { "channel": 2, "name": "pfl", "type": "button" },
- 0x16: { "channel": 1, "name": "bpm", "type": "button" },
- 0x1A: { "channel": 2, "name": "bpm", "type": "button" },
- 0x0A: { "channel": 1, "name": "sync", "type": "button" },
- 0x04: { "channel": 2, "name": "sync", "type": "button" }
- },
- "outputs": {
- 0x0F: { "channel": 1, "name": "fx mode", "type": "led" },
- 0x10: { "channel": 2, "name": "fx mode", "type": "led" },
- 0x0E: { "channel": 1, "name": "cue mode", "type": "led" },
- 0x11: { "channel": 2, "name": "cue mode", "type": "led" },
- 0x0D: { "channel": 1, "name": "loop mode", "type": "led" },
- 0x12: { "channel": 2, "name": "loop mode", "type": "led" },
- 0x16: { "channel": 1, "name": "master tempo", "type": "led" },
- 0x1A: { "channel": 2, "name": "master tempo", "type": "led" },
- 0x0A: { "channel": 1, "name": "sync", "type": "led" },
- 0x04: { "channel": 2, "name": "sync", "type": "led" },
- 0x09: { "channel": 1, "name": "cue", "type": "led" },
- 0x03: { "channel": 2, "name": "cue", "type": "led" },
- 0x05: { "channel": 1, "name": "play blink", "type": "led" },
- 0x00: { "channel": 2, "name": "play blink", "type": "led" },
- 0x08: { "channel": 1, "name": "play", "type": "led" },
- 0x02: { "channel": 2, "name": "play", "type": "led" },
- 0x7E: { "channel": 1, "name": "pfl", "type": "led" },
- 0x7D: { "channel": 2, "name": "pfl", "type": "led" }
- }
- };
- // called when the device is opened & set up
- HerculesMK2.init = function (id) {
- HerculesMK2.initializeControls();
- engine.connectControl("[Channel1]","playposition","HerculesMK2.wheelDecay");
- engine.connectControl("[Channel2]","playposition","HerculesMK2.wheelDecay");
- print ("HerculesMK2 id: \""+id+"\" initialized.");
- };
- HerculesMK2.initializeControls = function () {
- for (control in HerculesMK2.controls.outputs)
- {
- if (HerculesMK2.controls.outputs[control].type == 'led')
- {
- key = "[Channel" + HerculesMK2.controls.outputs[control].channel + "] " + HerculesMK2.controls.outputs[control].name;
- HerculesMK2.leds[key] = control;
- }
- }
- HerculesMK2.setLeds("on");
- HerculesMK2.setLeds("off");
- // Set controls in Mixxx to reflect settings on the device
- midi.sendShortMsg(0xB0,0x7F,0x7F);
- };
- HerculesMK2.shutdown = function (id) {
- HerculesMK2.setLeds("off");
- };
- HerculesMK2.getGroup = function (control){
- // Get the "group" that used to be provided in group, this is not reusable
- // across devices and also breaks remapping of these functions to other
- // buttons.
- return "[Channel" + HerculesMK2.controls.inputs[control].channel + "]";
- };
- HerculesMK2.getControl = function (io, channel, name) {
- // Accept channel in form 'N' or '[ChannelN]'
- channel = channel.replace(/\[Channel(\d)\]/, "$1");
- for (control in HerculesMK2.controls.inputs)
- {
- if (HerculesMK2.controls.inputs[control].channel == channel && HerculesMK2.controls.inputs[control].name == name)
- return HerculesMK2.controls.inputs[control];
- }
- print ("HerculesMK2.getControl: Control not found: io=" + io + ": channel=" + channel + ": name=" + name);
- };
- HerculesMK2.setLeds = function (onOff) {
- for (LED in HerculesMK2.leds)
- {
- HerculesMK2.setLed(LED,onOff);
- // Seems that if midi messages are sent too quickly, leds don't behave as expected. A pause rectifies this.
- HerculesMK2.pauseScript(10);
- }
- };
- HerculesMK2.setLed = function (led, onOff) {
- if (onOff=="on" || onOff==1 )
- value = HerculesMK2.ledOn;
- else if (onOff=="off" || onOff==0 )
- value = HerculesMK2.ledOff;
- else return;
- //if (HerculesMK2.debug) print ("HerculesMK2.setLed: Setting " + led + " led " + onOff);
- //if (HerculesMK2.debug) print ("HerculesMK2.setLed: midi.sendShortMsg(0xB0," + HerculesMK2.leds[led].toString(16) + "," + value + ")");
- midi.sendShortMsg(0xB0,HerculesMK2.leds[led],value);
- //HerculesMK2.controls.outputs[HerculesMK2.leds[led]].isOn = onOff=="on" ? true : false;
- HerculesMK2.controls.outputs[HerculesMK2.leds[led]].isOn = value;
- };
- ////
- //HerculesMK2.blinkStart = function (LED) {
- // HerculesMK2.timers[0] = engine.beginTimer(1000, "HerculesMK2.blinkLed("+LED+")",false);
- // return;
- //}
- //
- //HerculesMK2.blinkStop = function (LED) {
- // engine.stopTimer(HerculesMK2.blinkEnabled);
- // HerculesMK2.setLed(LED, "on");
- // return;
- //}
- //
- //HerculesMK2.blinkLed = function (LED) {
- // print (HerculesMK2.controls.outputs[HerculesMK2.leds[LED]].isOn);
- // //if (HerculesMK2.controls.outputs[HerculesMK2.leds[LED]].isOn == "on") HerculesMK2.setLed(LED, "off");
- // //else HerculesMK2.setLed(LED, "on");
- // return;
- //}
- // pause function for delay in script
- HerculesMK2.pauseScript = function(ms) {
- startDate = new Date();
- currentDate = null;
- while(currentDate-startDate < ms) currentDate = new Date();
- };
- // increment function to set a value
- HerculesMK2.increment = function(group, control, value, min,max,step) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.increment (" + group +", "+ control +", "+value +", "+status +")" );
- currentValue = engine.getValue(group, control);
- increment = (max-min)/step;
- increment = (value <= 0x3F) ? increment : increment * -1;
- newValue = currentValue + increment;
- newValue = newValue > max ? max : newValue < min ? min : newValue;
- if (newValue != currentValue)
- engine.setValue(group, control, newValue);
- print (group + " " + control + " set to " + ((newValue/max)*100) + "%");
- //if (HerculesMK2.debug) print ("Current value of "+group+" " + control + " is :" + currentValue + ", min: " + min + ", max:" + max + ", step:" + step + ", increment: " + increment );
- //if (HerculesMK2.debug) print ("HerculesMK2.pitch: value= " + newValue);
- return;
- };
- //cue function
- HerculesMK2.cue = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.cue (" + group +", "+ control +", "+value +", "+status +")" );
- group = HerculesMK2.getGroup(control);
- if ((engine.getValue(group, "duration") == 0) && (value))
- {
- print("No song on " + group);
- return;
- }
- if (value) // button pressed
- {
- engine.setValue(group,"cue_default",1);
- HerculesMK2.setLed(group + " cue", 1);
- }
- else
- {
- engine.setValue(group,"cue_default",0);
- }
- };
- // play function
- HerculesMK2.play = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.play (" + group +", "+ control +", "+value +", "+status +")" );
- if (value) // only when button is pressed, no action on release
- {
- group = HerculesMK2.getGroup(control);
- if (engine.getValue(group, "duration") == 0)
- {
- print("No song on " + group);
- return;
- }
- playvalue = !engine.getValue(group,"play");
- engine.setValue(group,"play", playvalue);
- HerculesMK2.controls.inputs[control].isPlaying = playvalue;
- // cue off, when simply playing
- HerculesMK2.setLed(group + " cue", "off");
- // play blink LED active, when song is paused
- //HerculesMK2.setLed(group + " play blink", !playvalue);
- // play LED active, when song is playing
- HerculesMK2.setLed(group + " play", playvalue);
- }
- };
- // pfl toggle function
- HerculesMK2.pfl = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.pfl (" + group +", "+ control +", "+value +", "+status +")" );
- if (value) // only when button is pressed, no action on release
- {
- switch (control) {
- case 0x23: // Headphones Split
- case 0x24: // Headphones Mix
- engine.setValue("[Channel1]", "pfl", 1);
- engine.setValue("[Channel2]", "pfl", 1);
- print("HerculesMk2.pfl: Mix/Split");
- break;
- case 0x21: // Headphones Deck A
- engine.setValue("[Channel1]", "pfl", 1);
- engine.setValue("[Channel2]", "pfl", 0);
- print("HerculesMk2.pfl: Deck A");
- break;
- case 0x22: // Headphones Deck B
- engine.setValue("[Channel1]", "pfl", 0);
- engine.setValue("[Channel2]", "pfl", 1);
- print("HerculesMk2.pfl: Deck B");
- break;
- }
- }
- };
- // reset bpm (master tempo)
- HerculesMK2.resetPitch = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.resetpitch (" + group +", "+ control +", "+value +", "+status +")" );
- if (value) // only when button is pressed, no action on release
- {
- group = HerculesMK2.getGroup(control);
- engine.setValue(group,"rate",0);
- HerculesMK2.setLed(group + " master tempo", "on");
- print ("Resetting pitch on" + group);
- }
- };
- HerculesMK2.loadSelectedTrack = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.loadSelectedTrack (" + group +", "+ control +", "+value +", "+status +")" );
- if (value) // only when button is pressed, no action on release
- {
- group = HerculesMK2.getGroup(control);
- engine.setValue(group, "LoadSelectedTrack", 1);
- HerculesMK2.setLed(group + " cue", 1);
- //HerculesMK2.setLed(group + " play blink", 1);
- HerculesMK2.resetPitch (group, control, value, status);
- print ("Track loaded on group " + group);
- }
- };
- // button group changing / button functions
- HerculesMK2.buttons123 = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.buttons123 (" + group +", "+ control +", "+value +", "+status +")" );
- group = HerculesMK2.getGroup(control);
- if (value) // Button pressed.
- HerculesMK2.controls.inputs[control].isDown = true;
- else //Button released.
- HerculesMK2.controls.inputs[control].isDown = false;
- mode = HerculesMK2.getControl("inputs", group, "fx select").mode;
- mode = HerculesMK2.buttons123Modes[mode];
- switch (mode)
- {
- case "kill": // Kill mode
- if (value)
- { // Button pressed.
- switch (HerculesMK2.controls.inputs[control].name)
- {
- case "fx 1":
- filter = "filterLowKill";
- break;
- case "fx 2":
- filter = "filterMidKill";
- break;
- case "fx 3":
- filter = "filterHighKill";
- break;
- }
- filtervalue = !engine.getValue(group, filter);
- engine.setValue(group, filter, filtervalue);
- print (group + " "+ filter + " set to "+ filtervalue);
- }
- break; // End kill mode
- case "fx": // Fx mode
- // because buttons also used together with pitch, we need to map these settings to button release without pitch beeing touched
- if (!value) // Button released.
- {
- // if button was used with pitch
- if (HerculesMK2.controls.inputs[control].used)
- {
- HerculesMK2.controls.inputs[control].used = false;
- return;
- }
- else
- {
- switch (HerculesMK2.controls.inputs[control].name)
- {
- case "fx 1":
- case "fx 2":
- case "fx 3":
- filter = "flanger";
- break;
- }
- filtervalue = !engine.getValue(group, filter);
- engine.setValue(group, filter, filtervalue);
- print (group + " "+ filter + " set to "+ filtervalue);
- }
- }
- break; // End fx mode
- case "cue": // Cue mode
- switch (HerculesMK2.controls.inputs[control].name)
- {
- case "fx 1":
- cue = "hotcue_1_set";
- break;
- case "fx 2":
- cue = "hotcue_1_activate";
- break;
- case "fx 3":
- cue = "hotcue_1_clear";
- break;
- }
- if (value) engine.setValue(group, cue, 1); //button pressed
- else engine.setValue(group, cue, 0); //button released
- print (group + " "+ cue + " set");
- break; // End cue mode
- case "loop": // loop mode
- switch (HerculesMK2.controls.inputs[control].name)
- {
- case "fx 1":
- loop = "loop_in";
- break;
- case "fx 2":
- loop = "loop_out";
- break;
- case "fx 3":
- loop = "reloop_exit";
- break;
- }
- if (value) engine.setValue(group, loop, 1); //button pressed
- else engine.setValue(group, loop, 0); //button released
- print (loop + "set on " + group );
- break; //End loop mode
- default:
- print("HerculesMK2.buttons123: " + mode + " mode unsupported");
- }
- };
- // button group mode change function
- HerculesMK2.buttons123mode = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.buttons123mode (" + group +", "+ control +", "+value +", "+status +")" );
- group = HerculesMK2.getGroup(control);
- if (value) // button pressed
- {
- currentMode = HerculesMK2.controls.inputs[control].mode;
- nextMode = currentMode < HerculesMK2.buttons123Modes.length-1 ? currentMode+1 : 0;
- currentLed = group + " " + HerculesMK2.buttons123Modes[currentMode] + " mode";
- nextLed = group + " " + HerculesMK2.buttons123Modes[nextMode] + " mode";
- sNextMode = HerculesMK2.buttons123Modes[nextMode];
- switch (sNextMode)
- {
- case "kill":
- case "fx":
- case "loop":
- case "cue":
- print("HerculesMK2.buttons123mode: Switching to " + sNextMode + " mode");
- break;
- default:
- print("HerculesMK2.buttons123mode: " + sNextMode + " mode unsupported");
- break;
- }
- // Only turn on/off leds for non-zero modes as 0 is kill mode which has no corresponding LED. i.e. all LEDs off for kill mode.
- if (currentMode) HerculesMK2.setLed(currentLed, "off");
- // Seems that if midi messages are sent too quickly, leds don't behave as expected. A pause rectifies this.
- HerculesMK2.pauseScript(10);
- if (nextMode) HerculesMK2.setLed(nextLed, "on");
- HerculesMK2.controls.inputs[control].mode = nextMode;
- }
- };
- // pitch function, also the special button + pitch combos
- HerculesMK2.pitch = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.pitch (" + group +", "+ control +", "+value +", "+status +")" );
- // 7F > 40: CCW Slow > Fast - 127 > 64
- // 01 > 3F: CW Slow > Fast - 0 > 63
- group = HerculesMK2.getGroup(control);
- pitchControl = HerculesMK2.getControl("inputs", group, "pitch");
- done = false;
- currentMode = HerculesMK2.getControl("inputs", group, "fx select").mode;
- currentMode = HerculesMK2.buttons123Modes[currentMode];
- joystick = HerculesMK2.joystickValue;
- // FX mode: buttons + Pitch: effect parameters
- if (currentMode == "fx")
- {
- if (HerculesMK2.getControl("inputs", group, "fx 1").isDown)
- {
- HerculesMK2.increment("[Flanger]", "lfoDelay", value, 50,10000,30);
- HerculesMK2.getControl("inputs", group, "fx 1").used = true;
- done = true;
- }
- if (HerculesMK2.getControl("inputs", group, "fx 2").isDown)
- {
- HerculesMK2.increment("[Flanger]", "lfoDepth", value, 0,1,30);
- HerculesMK2.getControl("inputs", group, "fx 2").used = true;
- done = true;
- }
- if (HerculesMK2.getControl("inputs", group, "fx 3").isDown)
- {
- HerculesMK2.increment("[Flanger]", "lfoPeriod", value, 50000, 2000000,30);
- HerculesMK2.getControl("inputs", group, "fx 3").used = true;
- done = true;
- }
- }
- // Cue mode: buttons + Pitch: headphone and channel gain parameters
- switch (joystick)
- {
- case "top":
- HerculesMK2.increment("[Master]", "headVolume", value,0,5,30);
- done = true;
- break;
- case "bottom":
- HerculesMK2.increment("[Master]", "headMix", value, -1,1,30);
- done = true;
- break;
- case "left":
- HerculesMK2.increment("[Channel1]", "pregain", value, 0,4,30);
- done = true;
- break;
- case "right":
- HerculesMK2.increment("[Channel2]", "pregain", value, 0,4,30);
- done = true;
- break;
- }
- // if buttons were used, exit, don't adjust pitch
- if (done) return;
- //no button was pressed, do normal pitch
- else
- {
- increment = 0.00125;
- increment = (value <= 0x3F) ? increment : increment * -1;
- //if (HerculesMK2.debug) print ("HerculesMK2.pitch: value=" + value);
- newrate = engine.getValue(group, "rate") + increment;
- engine.setValue(group, "rate", newrate);
- print ("newrate:" + newrate);
- //a bit of a range is reasonable
- if ((newrate < 0.005) && (newrate > -0.005)) HerculesMK2.setLed(group + " master tempo", "on");
- else HerculesMK2.setLed(group + " master tempo", "off");
- }
- };
- HerculesMK2.jog_wheel = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.jog_wheel (" + group +", "+ control +", "+value +", "+status +")" );
- // 7F > 40: CCW Slow > Fast - 127 > 64
- // 01 > 3F: CW Slow > Fast - 0 > 63
- group = HerculesMK2.getGroup(control);
- if (HerculesMK2.controls.outputs[HerculesMK2.leds[group + " cue"]].isOn == true)
- HerculesMK2.setLed(group + " cue", "off");
- jogValue = value >=0x40 ? value - 0x80 : value; // -64 to +63, - = CCW, + = CW
- // do some scratching
- if (HerculesMK2.scratchMode)
- {
- //if (HerculesMK2.debug) print("Do scratching value:" + value + " jogValue: " + jogValue );
- engine.setValue(group,"scratch", (engine.getValue(group,"scratch") + (jogValue/64)).toFixed(2));
- }
- // do pitch adjustment
- else
- {
- newValue = jogValue;
- //if (HerculesMK2.debug) print("do pitching adjust " + jogValue + " new Value: " + newValue);
- engine.setValue(group,"jog", newValue);
- }
- };
- // needed function to scratch only, not to redefine "vinyl feel" :)
- HerculesMK2.wheelDecay = function (value) {
- currentDate = new Date().getTime();
- if (currentDate > HerculesMK2.decayLast + HerculesMK2.decayInterval)
- {
- HerculesMK2.decayLast = currentDate;
- //if (HerculesMK2.debug) print(" new playposition: " + value + " decayLast: "+ HerculesMK2.decayLast);
- // do some scratching
- if (HerculesMK2.scratchMode)
- {
- //if (HerculesMK2.debug) print("Scratch deck1: " + engine.getValue("[Channel1]","scratch") + " deck2: "+ engine.getValue("[Channel2]","scratch"));
- jog1DecayRate = HerculesMK2.decayRate * (engine.getValue("[Channel1]","play") ? 1 : 5);
- jog1 = engine.getValue("[Channel1]","scratch");
- if (jog1 != 0)
- {
- if (Math.abs(jog1) > jog1DecayRate)
- engine.setValue("[Channel1]","scratch", (jog1 / jog1DecayRate).toFixed(2));
- else
- engine.setValue("[Channel1]","scratch", 0);
- }
- jog2DecayRate = HerculesMK2.decayRate * (engine.getValue("[Channel2]","play") ? 1 : 5);
- jog2 = engine.getValue("[Channel2]","scratch");
- if (jog2 != 0)
- {
- if (Math.abs(jog2) > jog2DecayRate)
- engine.setValue("[Channel2]","scratch", (jog2 / jog2DecayRate).toFixed(2));
- else
- engine.setValue("[Channel2]","scratch", 0);
- }
- }
- }
- };
- HerculesMK2.joystick = function (group, control, value, status) {
- //if (HerculesMK2.debug) print ("[Debug] HerculesMK2.playlist (" + group +", "+ control +", "+value +", "+status +")" );
- switch (control)
- {
- case 0x39:
- switch (value)
- {
- case 0x05:
- joystick = "top";
- break;
- case 0x7F:
- joystick = "bottom";
- break;
- default:
- joystick = false;
- }
- break;
- case 0x38:
- switch (value)
- {
- case 0x00:
- joystick = "left";
- break;
- case 0x7F:
- joystick = "right";
- break;
- default:
- joystick = false;
- }
- break;
- default:
- joystick = false;
- break;
- }
- HerculesMK2.joystickValue = joystick;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement