home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Aplikacje_64-bitowe / Mixxx / mixxx-1.9.0-win64.exe / midi / Hercules-DJ-Console-Mk2-scripts.js < prev    next >
Text File  |  2011-02-04  |  18KB  |  485 lines

  1. function HerculesMk2 () {}
  2.  
  3. HerculesMk2.ledOn = 0x7F;
  4. HerculesMk2.ledOff = 0x00;
  5.  
  6. HerculesMk2.debug = false;
  7. HerculesMk2.scratchMode = false;
  8. HerculesMk2.decayLast = new Date().getTime();
  9. HerculesMk2.decayInterval = 300;
  10. HerculesMk2.decayRate = 1.5;
  11.  
  12. HerculesMk2.buttons123Modes = ["kill", "fx", "cue", "loop"];
  13. HerculesMk2.buttons123used = {"[Channel1]": false, "[Channel1]": false};
  14.  
  15. // TODO HerculesMk2 controls should be divided into groups, then signals 
  16. // should directed to each group without thinking about specific controls 
  17. // to allow for easy rebinding.
  18.  
  19. HerculesMk2.cueLastDate1 = {"[Channel1]": 0, "[Channel2]" : 0};
  20. HerculesMk2.cueLastDate2 = {"[Channel1]": 0, "[Channel2]" : 0};
  21. HerculesMk2.cueLastDate3 = {"[Channel1]": 0, "[Channel2]" : 0};
  22. HerculesMk2.cueLongTime = 500;
  23.  
  24. HerculesMk2.controls = {
  25.     "inputs": {
  26.     0x09: { "channel": 1, "name": "cue", "type": "button" },
  27.     0x03: { "channel": 2, "name": "cue", "type": "button" },
  28.     0x08: { "channel": 1, "name": "play", "type": "button" },
  29.     0x02: { "channel": 2, "name": "play", "type": "button" },
  30.     0x07: { "channel": 1, "name": "fx select", "type": "button", 
  31.         "mode": 0 },
  32.     0x01: { "channel": 2, "name": "fx select", "type": "button", 
  33.         "mode": 0 },
  34.     0x0F: { "channel": 1, "name": "fx 1", "type": "button", "used": false },
  35.     0x10: { "channel": 2, "name": "fx 1", "type": "button", "used": false },
  36.     0x0E: { "channel": 1, "name": "fx 2", "type": "button", "used": false },
  37.     0x11: { "channel": 2, "name": "fx 2", "type": "button", "used": false },
  38.     0x0D: { "channel": 1, "name": "fx 3", "type": "button", "used": false },
  39.     0x12: { "channel": 2, "name": "fx 3", "type": "button", "used": false },
  40.     0x1B: { "channel": 1, "name": "mouse", "type": "button" },
  41.     0x1C: { "channel": 2, "name": "mouse", "type": "button" },
  42.     0x34: { "channel": 1, "name": "pitch", "type": "pot" },
  43.     0x35: { "channel": 2, "name": "pitch", "type": "pot" },
  44.     0x36: { "channel": 1, "name": "wheel", "type": "pot" },
  45.     0x37: { "channel": 2, "name": "wheel", "type": "pot" }
  46.     },
  47.     "outputs": {
  48.     0x0F: { "channel": 1, "name": "fx mode", "type": "led" },
  49.     0x10: { "channel": 2, "name": "fx mode", "type": "led" },
  50.     0x0E: { "channel": 1, "name": "cue mode", "type": "led" },
  51.     0x11: { "channel": 2, "name": "cue mode", "type": "led" },
  52.     0x0D: { "channel": 1, "name": "loop mode", "type": "led" },
  53.     0x12: { "channel": 2, "name": "loop mode", "type": "led" },
  54.     0x16: { "channel": 1, "name": "master tempo", "type": "led" },
  55.     0x1A: { "channel": 2, "name": "master tempo", "type": "led" },
  56.     0x0A: { "channel": 1, "name": "auto beat", "type": "led" },
  57.     0x04: { "channel": 2, "name": "auto beat", "type": "led" },
  58.     0x09: { "channel": 1, "name": "cue", "type": "led" },
  59.     0x03: { "channel": 2, "name": "cue", "type": "led" },
  60.     0x00: { "channel": 1, "name": "play blink", "type": "led" },
  61.     0x05: { "channel": 2, "name": "play blink", "type": "led" },
  62.     0x08: { "channel": 1, "name": "play", "type": "led" },
  63.     0x02: { "channel": 2, "name": "play", "type": "led" }
  64.     }
  65. };
  66.  
  67. HerculesMk2.leds = { 
  68. };
  69.  
  70. HerculesMk2.init = function (id) { // called when the device is opened & set up
  71.     HerculesMk2.initializeControls();
  72.     
  73.     engine.connectControl("[Channel1]","playposition","HerculesMk2.wheelDecay");
  74.     engine.connectControl("[Channel2]","playposition","HerculesMk2.wheelDecay");
  75.     
  76.     print ("HerculesMk2 id: \""+id+"\" initialized.");
  77. };
  78.     
  79. HerculesMk2.initializeControls = function () {
  80.     for (control in HerculesMk2.controls.outputs) {
  81.     if (HerculesMk2.controls.outputs[control].type == 'led') {
  82.         key = "[Channel" + HerculesMk2.controls.outputs[control].channel + "] " + HerculesMk2.controls.outputs[control].name;
  83.         HerculesMk2.leds[key] = control;
  84.     }
  85.     }
  86.  
  87.     HerculesMk2.setLeds("on");
  88.     HerculesMk2.setLeds("off");
  89.     
  90.     // Set controls in Mixxx to reflect settings on the device
  91.     midi.sendShortMsg(0xB0,0x7F,0x7F);
  92. };
  93.  
  94. HerculesMk2.shutdown = function (id) {
  95.     HerculesMk2.setLeds("off");
  96. };
  97.  
  98. HerculesMk2.getGroup = function (control){ 
  99.     // Get the "group" that used to be provided in group, this is not reusable 
  100.     // across devices and also breaks remapping of these functions to other 
  101.     // buttons.  
  102.  
  103.     return "[Channel" + HerculesMk2.controls.inputs[control].channel + "]";
  104. };
  105.  
  106. HerculesMk2.getControl = function (io, channel, name) { 
  107.     // Accept channel in form 'N' or '[ChannelN]'
  108.     channel = channel.replace(/\[Channel(\d)\]/, "$1");
  109.  
  110.     for (control in HerculesMk2.controls.inputs) {
  111.     if (HerculesMk2.controls.inputs[control].channel == channel && 
  112.         HerculesMk2.controls.inputs[control].name == name
  113.         ) return HerculesMk2.controls.inputs[control];
  114.     }
  115.  
  116.     print ("HerculesMk2.getControl: Control not found: io=" + io + ": channel=" + channel + ": name=" + name);
  117. };
  118.  
  119. HerculesMk2.setLeds = function (onOff) {
  120.     for (LED in HerculesMk2.leds) {
  121.     HerculesMk2.setLed(LED,onOff);
  122.     // Seems that if midi messages are sent too quickly, leds don't behave
  123.     // as expected. A pause rectifies this.
  124.     HerculesMk2.pauseScript(10);
  125.     }
  126. };
  127.  
  128. HerculesMk2.setLed = function (led, onOff) {
  129.     value = onOff=="on" ?  HerculesMk2.ledOn : HerculesMk2.ledOff;
  130.     if (HerculesMk2.debug) print ("HerculesMk2.setLed: Setting " + led + " led " + onOff);
  131.     if (HerculesMk2.debug) print ("HerculesMk2.setLed: midi.sendShortMsg(0xB0," + HerculesMk2.leds[led].toString(16) + "," + value + ")");
  132.     midi.sendShortMsg(0xB0,HerculesMk2.leds[led],value);
  133.     HerculesMk2.controls.outputs[HerculesMk2.leds[led]].isOn = onOff=="on" ? true : false;
  134. };
  135.  
  136. HerculesMk2.pauseScript = function(ms) {
  137.     startDate = new Date();
  138.     currentDate = null;
  139.  
  140.     while(currentDate-startDate < ms) currentDate = new Date();
  141. };
  142.  
  143. HerculesMk2.pfl = function (group, control, value, status) {
  144.     if (value) { // Act on given mode being selected, not deselected. 
  145.     if (HerculesMk2.debug) print("HerculesMk2.pfl: " + control.toString(16) + " " + value.toString(16));
  146.     switch (control) {
  147.     case 0x23: // Headphones Split
  148.     case 0x24: // Headphones Mix
  149.         if (HerculesMk2.debug) print("HerculesMk2.pfl: Mix/Split");
  150.         engine.setValue("[Channel1]", "pfl", 1);
  151.         engine.setValue("[Channel2]", "pfl", 1);
  152.         break;
  153.     case 0x21: // Headphones Deck A
  154.         if (HerculesMk2.debug) print("HerculesMk2.pfl: Deck A");
  155.         engine.setValue("[Channel1]", "pfl", 1);        
  156.         engine.setValue("[Channel2]", "pfl", 0);
  157.         break;
  158.     case 0x22: // Headphones Deck B
  159.         if (HerculesMk2.debug) print("HerculesMk2.pfl: Deck B");
  160.         engine.setValue("[Channel1]", "pfl", 0);        
  161.         engine.setValue("[Channel2]", "pfl", 1);        
  162.     }
  163.     }
  164. };
  165.  
  166. HerculesMk2.cue = function (group, control, value, status) {
  167.     group = HerculesMk2.getGroup(control);
  168.     
  169.     if ((engine.getValue(group, "duration") == 0) && (value)) { 
  170.     print("No song on " + group);
  171.     return; 
  172.     }
  173.     
  174.     if (value) { // Down
  175.     engine.setValue(group,"cue_default",1);
  176.     HerculesMk2.setLed(group + " cue", "on");
  177.     } else { // Release
  178.     engine.setValue(group,"cue_default",0);
  179.     }
  180. };
  181.  
  182. HerculesMk2.play = function (group, control, value, status) {
  183.     if (value) { // Only do stuff when play is pushed, not released.
  184.     group = HerculesMk2.getGroup(control);
  185.     
  186.     if (engine.getValue(group, "duration") == 0) { 
  187.         print("No song on " + group);
  188.         return; 
  189.     }
  190.     
  191.     engine.setValue(group,"play", !engine.getValue(group,"play"));
  192.     HerculesMk2.setLed(group + " cue", "off");
  193.     }
  194. };
  195.  
  196. HerculesMk2.loadSelectedTrack = function (group, control, value, status) {
  197.     if (value) { // Only do stuff when pushed, not released.
  198.     group = HerculesMk2.getGroup(control);
  199.     engine.setValue(group, "LoadSelectedTrack", 1);
  200.     HerculesMk2.setLed(group + " cue", "on");
  201.     }
  202. };
  203.  
  204. HerculesMk2.buttons123 = function (group, control, value, status) {
  205.     group = HerculesMk2.getGroup(control);
  206.  
  207.     if (value) { // Button pressed.
  208.     HerculesMk2.controls.inputs[control].isDown = true;
  209.     } else { //Button released.
  210.     HerculesMk2.controls.inputs[control].isDown = false;
  211.     }
  212.  
  213.     mode = HerculesMk2.getControl("inputs", group, "fx select").mode;
  214.     mode = HerculesMk2.buttons123Modes[mode];
  215.     
  216.     switch (mode) {
  217.  
  218.     case "kill": // Kill mode
  219.     if (value) { // Button pressed.
  220.         switch (HerculesMk2.controls.inputs[control].name) {
  221.         case "fx 1":
  222.         engine.setValue(group, "filterLowKill", !engine.getValue(group, "filterLowKill"));
  223.         break;
  224.         case "fx 2": 
  225.         engine.setValue(group, "filterMidKill", !engine.getValue(group, "filterMidKill"));
  226.         break;
  227.         case "fx 3":
  228.         engine.setValue(group, "filterHighKill", !engine.getValue(group, "filterHighKill"));
  229.         break;
  230.         } 
  231.     }
  232.     break; // End kill mode
  233.  
  234.     case "fx": // Fx mode
  235.     // Were only turning off the flanger if any of the 123 buttons are
  236.     // released, not pushed. This is so we can have any of the 123 buttons
  237.     // held down, then use the pitch pot to modify the effect settings
  238.     if (!value) { // Button released.
  239.         if (HerculesMk2.controls.inputs[control].used) {
  240.         // Button was used to turn the pitch control into a modifier 
  241.         // for the effect settings, so don't go on and turn the flanger
  242.         // on/off
  243.         HerculesMk2.controls.inputs[control].used = false;
  244.         return;
  245.         }
  246.  
  247.         switch (HerculesMk2.controls.inputs[control].name) {
  248.         case "fx 1":
  249.         case "fx 2":
  250.         case "fx 3":
  251.         engine.setValue(group, "flanger", !engine.getValue(group, "flanger"));
  252.         break;
  253.         } 
  254.     }
  255.     break; // End fx mode
  256.  
  257.     case "cue": 
  258.     if (value){
  259.         switch (HerculesMk2.controls.inputs[control].name) {
  260.             case "fx 1":
  261.             HerculesMk2.cueLastDate1[group] = new Date().getTime();
  262.             break;
  263.             case "fx 2":
  264.             HerculesMk2.cueLastDate2[group] = new Date().getTime();
  265.             break;
  266.             case "fx 3":
  267.             HerculesMk2.cueLastDate3[group] = new Date().getTime();
  268.             break;
  269.         }
  270.     }
  271.     if (!value){
  272.         currentDate = new Date().getTime();
  273.         switch (HerculesMk2.controls.inputs[control].name) {
  274.             case "fx 1":
  275.             if (currentDate - HerculesMk2.cueLastDate1[group] < HerculesMk2.cueLongTime)
  276.                 engine.setValue(group,"hotcue_1_activate",1)
  277.             else
  278.                 engine.setValue(group,"hotcue_1_clear",1)
  279.             break;
  280.             case "fx 2":
  281.             if (currentDate - HerculesMk2.cueLastDate2[group] < HerculesMk2.cueLongTime)
  282.                 engine.setValue(group,"hotcue_2_activate",1)
  283.             else
  284.                 engine.setValue(group,"hotcue_2_clear",1)
  285.             break;
  286.             case "fx 3":
  287.             if (currentDate - HerculesMk2.cueLastDate3[group] < HerculesMk2.cueLongTime)
  288.                 engine.setValue(group,"hotcue_3_activate",1)
  289.             else
  290.                 engine.setValue(group,"hotcue_3_clear",1)
  291.             break;
  292.         }
  293.  
  294.     }
  295.     break;
  296.  
  297.     case "loop":
  298.         if (value) { // Button pressed.
  299.             switch (HerculesMk2.controls.inputs[control].name) {
  300.             case "fx 1": // "fx 1,2,3" should be globally renamed as said before?...
  301.                 // trigger loop in
  302.                 engine.setValue(group,"loop_in", !engine.getValue(group,"start")); // Am I correct?
  303.                 break;
  304.             case "fx 2":
  305.                 // trigger loop out
  306.                 engine.setValue(group,"loop_out", !engine.getValue(group,"end")); // Am I correct?
  307.                 break;
  308.             case "fx 3":
  309.                 // trigger loop exit
  310.                 engine.setValue(group,"reloop_exit", !engine.getValue(group,"loop")); // Am I correct?
  311.                 break;
  312.            }
  313.         }
  314.     break;
  315.  
  316.     default: 
  317.     print("HerculesMk2.buttons123: " + mode + " mode unsupported");
  318.     }
  319. };
  320.  
  321. HerculesMk2.buttons123mode = function (group, control, value, status) {
  322.     group = HerculesMk2.getGroup(control);
  323.     if (value) { // Only do stuff when pushed, not released.
  324.     currentMode = HerculesMk2.controls.inputs[control].mode;
  325.     nextMode = currentMode < HerculesMk2.buttons123Modes.length-1 ? currentMode+1 : 0;
  326.     currentLed = group + " " + HerculesMk2.buttons123Modes[currentMode] + " mode";
  327.     nextLed = group + " " + HerculesMk2.buttons123Modes[nextMode] + " mode";
  328.  
  329.     sNextMode = HerculesMk2.buttons123Modes[nextMode]; 
  330.     switch (sNextMode) {
  331.     case "kill":
  332.     case "fx": 
  333.         print("HerculesMk2.buttons123mode: Switching to " + sNextMode + " mode");
  334.         break;
  335.     case "cue": 
  336.         print("HerculesMk2.buttons123mode: Switching to " + sNextMode + " mode");
  337.         break;
  338.     case "loop":
  339.         print("HerculesMk2.buttons123mode: Switching to " + sNextMode + " mode");
  340.         break;
  341.     default:
  342.         print("HerculesMk2.buttons123mode: Switching to " + sNextMode + " mode");
  343.     }
  344.  
  345.     // Only turn on/off leds for non-zero modes as 0 is kill mode which
  346.     // has no corresponding LED. i.e. all LEDs off for kill mode.
  347.     if (currentMode) HerculesMk2.setLed(currentLed, "off");
  348.     // Seems that if midi messages are sent too quickly, leds don't behave
  349.     // as expected. A pause rectifies this.
  350.     HerculesMk2.pauseScript(10);
  351.     if (nextMode) HerculesMk2.setLed(nextLed, "on");
  352.  
  353.     HerculesMk2.controls.inputs[control].mode = nextMode;
  354.     }
  355. };
  356.  
  357. HerculesMk2.pitch = function (group, control, value, status) {
  358.     //  7F > 40: CCW Slow > Fast - 127 > 64 
  359.     //  01 > 3F: CW Slow > Fast - 0 > 63
  360.  
  361.     group = HerculesMk2.getGroup(control);
  362.     pitchControl = HerculesMk2.getControl("inputs", group, "pitch");
  363.     done = false;
  364.  
  365.     currentMode = HerculesMk2.getControl("inputs", group, "fx select").mode;
  366.     currentMode = HerculesMk2.buttons123Modes[currentMode];
  367.  
  368.     // If in fx mode and one or more of buttons 123 are pressed, use pitch
  369.     // pot to adjust the relevant flanger parameters instead of changing
  370.     // the rate (as is normal operation for the pitch pot)
  371.  
  372.     if (currentMode == "fx") { 
  373.     potStep = 25; // How many clicks round the pot from min to max values
  374.  
  375.     if (HerculesMk2.getControl("inputs", group, "fx 1").isDown) {
  376.         min = 0; max = 1;
  377.         increment = (max-min)/potStep;
  378.         increment = (value <= 0x3F) ? increment : increment * -1;
  379.  
  380.         currentValue = engine.getValue("[Flanger]", "lfoDepth");
  381.         newValue = currentValue + increment;
  382.         newValue = newValue > max ? max : newValue < min ? min : newValue;
  383.         if (HerculesMk2.debug) print ("HerculesMk2.pitch: value= " + newValue);
  384.         if (newValue != currentValue) 
  385.         engine.setValue("[Flanger]", "lfoDepth", newValue);
  386.         
  387.         HerculesMk2.getControl("inputs", group, "fx 1").used = true;
  388.         done = true;
  389.     } 
  390.  
  391.     if (HerculesMk2.getControl("inputs", group, "fx 2").isDown) {
  392.         min = 50; max = 10000;
  393.         increment = (max-min)/potStep;
  394.         increment = (value <= 0x3F) ? increment : increment * -1;
  395.     
  396.         currentValue = engine.getValue("[Flanger]", "lfoDelay");
  397.         newValue = currentValue + increment;
  398.         newValue = newValue > max ? max : newValue < min ? min : newValue;
  399.         if (HerculesMk2.debug) print ("HerculesMk2.pitch: value= " + newValue);
  400.         if (newValue != currentValue) 
  401.         engine.setValue("[Flanger]", "lfoDelay", newValue);
  402.         
  403.         HerculesMk2.getControl("inputs", group, "fx 2").used = true;
  404.         done = true;
  405.     }
  406.     
  407.     if (HerculesMk2.getControl("inputs", group, "fx 3").isDown) {
  408.         min = 50000; max = 2000000
  409.         increment = (max-min)/potStep;
  410.         increment = (value <= 0x3F) ? increment : increment * -1;
  411.  
  412.         currentValue = engine.getValue("[Flanger]", "lfoPeriod");
  413.         newValue = currentValue + increment;
  414.         newValue = newValue > max ? max : newValue < min ? min : newValue;
  415.         if (HerculesMk2.debug) print ("HerculesMk2.pitch: value= " + newValue);
  416.         if (newValue != currentValue) 
  417.         engine.setValue("[Flanger]", "lfoPeriod", newValue);
  418.         
  419.         HerculesMk2.getControl("inputs", group, "fx 3").used = true;
  420.         done = true;
  421.     }
  422.     }
  423.  
  424.     if (done) return;
  425.  
  426.     increment = 0.016;
  427.     increment = (value <= 0x3F) ? increment : increment * -1;
  428.  
  429.     if (HerculesMk2.debug) print ("HerculesMk2.pitch: value=" + value);
  430.     engine.setValue(group, "rate", engine.getValue(group, "rate") + increment);
  431. };
  432.  
  433. HerculesMk2.jog_wheel = function (group, control, value, status) {
  434.     //  7F > 40: CCW Slow > Fast - 127 > 64 
  435.     //  01 > 3F: CW Slow > Fast - 0 > 63
  436.     group = HerculesMk2.getGroup(control);
  437.  
  438.     if (HerculesMk2.controls.outputs[HerculesMk2.leds[group + " cue"]].isOn == true) {
  439.     HerculesMk2.setLed(group + " cue", "off");
  440.     }
  441.     
  442.     jogValue = value >=0x40 ? value - 0x80 : value; // -64 to +63, - = CCW, + = CW
  443.     
  444.     if (HerculesMk2.scratchMode) { // do some scratching
  445.     if (HerculesMk2.debug) print("Do scratching value:" + value + " jogValue: " + jogValue );
  446.     engine.setValue(group,"scratch", (engine.getValue(group,"scratch") + (jogValue/64)).toFixed(2));
  447.     } else { // do pitch adjustment
  448.     newValue = jogValue; 
  449.     if (HerculesMk2.debug) print("do pitching adjust " + jogValue + " new Value: " + newValue);
  450.     engine.setValue(group,"jog", newValue);
  451.     }
  452. };
  453.     
  454. HerculesMk2.wheelDecay = function (value) {    
  455.     currentDate = new Date().getTime();
  456.     
  457.     if (currentDate > HerculesMk2.decayLast + HerculesMk2.decayInterval) {
  458.     HerculesMk2.decayLast = currentDate;
  459.     
  460.     if (HerculesMk2.debug) print(" new playposition: " + value + " decayLast: "+ HerculesMk2.decayLast);
  461.     if (HerculesMk2.scratchMode) { // do some scratching
  462.         if (HerculesMk2.debug) print("Scratch deck1: " + engine.getValue("[Channel1]","scratch") + " deck2: "+ engine.getValue("[Channel2]","scratch"));
  463.         
  464.         jog1DecayRate = HerculesMk2.decayRate * (engine.getValue("[Channel1]","play") ? 1 : 5);
  465.         jog1 = engine.getValue("[Channel1]","scratch"); 
  466.         if (jog1 != 0) {
  467.         if (Math.abs(jog1) > jog1DecayRate) {  
  468.             engine.setValue("[Channel1]","scratch", (jog1 / jog1DecayRate).toFixed(2));
  469.         } else {
  470.             engine.setValue("[Channel1]","scratch", 0);
  471.         }
  472.         }
  473.         jog2DecayRate = HerculesMk2.decayRate * (engine.getValue("[Channel2]","play") ? 1 : 5);
  474.         jog2 = engine.getValue("[Channel2]","scratch"); 
  475.         if (jog2 != 0) {
  476.         if (Math.abs(jog2) > jog2DecayRate) {  
  477.             engine.setValue("[Channel2]","scratch", (jog2 / jog2DecayRate).toFixed(2));
  478.         } else {
  479.             engine.setValue("[Channel2]","scratch", 0);
  480.         }
  481.         }
  482.     }
  483.     }
  484. };
  485.