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-Control-MP3-scripts.js
< prev
next >
Wrap
Text File
|
2010-12-04
|
22KB
|
686 lines
function HerculesMp3 () {}
//wheel sensitivity is changing between different versions of Mixxx.
//Change this accordingly.
jog_sens = 1;
//Warning! setting enable_beats to true, will enable Autobeat lights to flash near a beat.
//Unfortunately I had to use a buffer to avoid sending signal to the controller too close each other.
//If you enable this feature, leds could not properly work.
//In the future, a function midi.sendShortMsgBuffered() will be implemented in Mixxx code and I will try to fix this.
//Until there, I recommend to not change this setting.
//If you do not know what you are doing, do not change any variable under this comment.
HerculesMp3.buttons123Modes = ["kill", "fx", "cue", "loop"];
HerculesMp3.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" },
0x16: { "channel": 1, "name": "master tempo", "type": "button" },
0x1A: { "channel": 2, "name": "master tempo", "type": "button" },
0x34: { "channel": 1, "name": "pitch", "type": "pot", "mode": 0 },
0x35: { "channel": 2, "name": "pitch", "type": "pot", "mode": 0 },
0x36: { "channel": 1, "name": "wheel", "type": "pot" },
0x37: { "channel": 2, "name": "wheel", "type": "pot" },
0x0B: { "channel": 1, "name": "prevtrack", "type": "button" },
0x0C: { "channel": 1, "name": "nexttrack", "type": "button" },
0x05: { "channel": 2, "name": "prevtrack", "type": "button" },
0x06: { "channel": 2, "name": "nexttrack", "type": "button" }
},
"outputs": {
0x0F: { "channel": 1, "name": "fx mode", "type": "led" , "status": 0x00 , "isblinking": false },
0x10: { "channel": 2, "name": "fx mode", "type": "led" , "status": 0x00 , "isblinking": false },
0x0E: { "channel": 1, "name": "cue mode", "type": "led" , "status": 0x00 },
0x11: { "channel": 2, "name": "cue mode", "type": "led" , "status": 0x00 },
0x0D: { "channel": 1, "name": "loop mode", "type": "led" , "status": 0x00 },
0x12: { "channel": 2, "name": "loop mode", "type": "led" , "status": 0x00 },
0x16: { "channel": 1, "name": "master tempo", "type": "led" , "status": 0x00 },
0x1A: { "channel": 2, "name": "master tempo", "type": "led" , "status": 0x00 },
0x0A: { "channel": 1, "name": "auto beat", "type": "led" , "status": 0x00 , "beatlen": 0 },
0x04: { "channel": 2, "name": "auto beat", "type": "led" , "status": 0x00 , "beatlen": 0 },
0x09: { "channel": 1, "name": "cue_set", "type": "led" , "status": 0x00 },
0x03: { "channel": 2, "name": "cue_set", "type": "led" , "status": 0x00 },
0x00: { "channel": 1, "name": "play blink", "type": "led" , "status": 0x00 },
0x05: { "channel": 2, "name": "play blink", "type": "led" , "status": 0x00 },
0x08: { "channel": 1, "name": "play", "type": "led" , "status": 0x00 },
0x02: { "channel": 2, "name": "play", "type": "led" , "status": 0x00 },
0x7E: { "channel": 1, "name": "pfl", "type": "led" , "status": 0x00 },
0x7D: { "channel": 2, "name": "pfl", "type": "led" , "status": 0x00 }
}
};
//Init controller
HerculesMp3.init = function (id) { // called when the device is opened & set up
// variables and arrays
led_lock = false;
enable_beats = false;
ledmsg = 0x00;
loopc = [];
timerloopID = [];
is_hold_loop=[];
reloopon = [];
is_hold_hotcue = [];
timerhotcueID = [];
loop_control=[];
Deck = [];
scratch = [];
led_array = [];
scratch_timer_on = [];
scratch_timer = [];
returnblink = [];
blinktimer = [];
bshot = [];
VLset = [];
for(decks=1; decks<=2; decks++){
Deck[decks] = "[Channel"+decks+"]";
loopc[decks] = 0;
VLset[decks] = false;
timerloopID[decks] = 0;
is_hold_loop[decks] = true;
reloopon[decks] = false;
scratch[decks] = false;
VLset[decks] = false;
scratch_timer_on[decks]=false;
}
// Messages to the console cannot be sent too close ( < 10ms)
// So that in other scripts a pause function is used
// afaik it is not allowed.
// a timer and a buffer will rectify this.
// Setting it to 20ms instead of 11ms as this first is the lowest value accepted for a timer.
engine.beginTimer(20, "HerculesMp3.ledhelper()");
// Be the leds!
HerculesMp3.leds(true);
engine.beginTimer(500, "HerculesMp3.leds(false)",true);
// Connect leds here and not in xml. This is to avoid an annoying bug (maybe) in controller drivers.
engine.connectControl("[Channel1]", "pfl", "HerculesMp3.pfl_left");
engine.connectControl("[Channel2]", "pfl", "HerculesMp3.pfl_right");
engine.connectControl("[Channel1]", "play", "HerculesMp3.play_left");
engine.connectControl("[Channel2]", "play", "HerculesMp3.play_right");
engine.connectControl("[Channel1]", "cue_default", "HerculesMp3.cue_left");
engine.connectControl("[Channel2]", "cue_default", "HerculesMp3.cue_right");
//engine.connectControl("[Channel1]", "keylock", "HerculesMp3.master_tempoA");
//engine.connectControl("[Channel2]", "keylock", "HerculesMp3.master_tempoB");
print ("HerculesMp3 id: \""+id+"\" initialized.");
};
//Shutdown the controller.
HerculesMp3.shutdown = function (id) {
HerculesMp3.leds(false);
print ("HerculesMp3 id: \""+id+"\" shut down.");
};
//Messages to the console cannot be sent too close ( < 10ms)
HerculesMp3.ledhelper = function () {
// What does this function do? It is just an apostrophe between the words "I'll-do".
if(typeof led_array == "undefined"){
led_array = [];
}
if (led_array.length > 0){
var nowled = led_array[0];
var nowstatus = HerculesMp3.controls.outputs[nowled].status;
led_array.shift();
midi.sendShortMsg(0xB0,nowled,nowstatus);
//clear buffer if there are too messages
}
// beat leds
if(enable_beats){
var beatA = HerculesMp3.controls.outputs[0x0A].beatlen;
var beatB = HerculesMp3.controls.outputs[0x04].beatlen;
if(beatA) HerculesMp3.bblinkA(beatA);
if(beatB) HerculesMp3.bblinkB(beatB);
}
};
HerculesMp3.leds = function (onoff) {
for (control in HerculesMp3.controls.outputs) {
if (HerculesMp3.controls.outputs[control].type == 'led') {
HerculesMp3.led(control,onoff);
}
}
};
HerculesMp3.ledblink = function (control,onoff){
if(onoff) {
actual_status = HerculesMp3.controls.outputs[control].status;
blinktimer[control] = engine.beginTimer(300,"HerculesMp3.ledblinkhelper("+control+")");
HerculesMp3.controls.outputs[control].isblinking = true;
}
else
{
if (HerculesMp3.controls.outputs[control].isblinking) {
HerculesMp3.controls.outputs[control].isblinking = false;
engine.stopTimer(blinktimer[control]);
HerculesMp3.led(control,actual_status);
}
}
};
HerculesMp3.ledblinkhelper = function (control){
var ledval = true;
if (HerculesMp3.controls.outputs[control].status)
{
ledval = false;
}
HerculesMp3.led(control,ledval);
};
HerculesMp3.pfl_left = function(value) {
HerculesMp3.led(0x7E, value);
};
HerculesMp3.pfl_right = function(value) {
HerculesMp3.led(0x7D, value);
};
HerculesMp3.play_left = function(value) {
HerculesMp3.led(0x08, value);
};
HerculesMp3.play_right = function(value) {
HerculesMp3.led(0x02, value);
};
HerculesMp3.cue_left = function(value) {
HerculesMp3.led(0x09, value);
};
HerculesMp3.cue_right = function (value) {
HerculesMp3.led(0x03, value);
};
HerculesMp3.master_tempoA = function (value){
HerculesMp3.led(0x16, value);
};
HerculesMp3.master_tempoB = function (value){
HerculesMp3.led(0x1A, value);
};
HerculesMp3.led = function (control, isOn) {
ledmsg = 0x00;
if (isOn){
ledmsg = 0x7F;
//Clear buffer when there are too messages
if(led_array.length > 10) {
led_array = [];
}
}
if(HerculesMp3.controls.outputs[control].status != ledmsg) {
led_array.push(control);
HerculesMp3.controls.outputs[control].status = ledmsg;
}
};
//loop control
HerculesMp3.loophold = function (deck) {
is_hold_loop[deck] = true;
if(engine.getValue("[Channel"+deck+"]","loop_enabled"))
{
//problem with skins
engine.setValue("[Channel"+deck+"]","reloop_exit",1);
engine.setValue("[Channel"+deck+"]","reloop_exit",0);
}
else {
engine.setValue("[Channel"+deck+"]","reloop_exit",0);
}
engine.setValue("[Channel"+deck+"]", "loop_in", 0);
engine.setValue("[Channel"+deck+"]", "loop_start_position",-1);
engine.setValue("[Channel"+deck+"]", "loop_out", 0);
engine.setValue("[Channel"+deck+"]", "loop_end_position",-1);
loopc[deck] = 0;
};
HerculesMp3.loop = function (deck, control, value) {
if(value) {
is_hold_loop[deck] = false;
timerloopID[deck] = engine.beginTimer(700,"HerculesMp3.loophold("+deck+")",true);
}
else {
engine.stopTimer(timerloopID[deck]);
if(!is_hold_loop[deck]) {
loopc[deck]++;
if(loopc[deck]==1)engine.setValue("[Channel"+deck+"]", "loop_in", 1);
if(loopc[deck]==2)engine.setValue("[Channel"+deck+"]", "loop_out", 1);
if(loopc[deck]>2) {
engine.setValue("[Channel"+deck+"]", "reloop_exit", 1);
loopc[deck]=2;
}
}
}
};
//hotcue control
HerculesMp3.fxbutton = function (fxnumber) {
switch(fxnumber)
{
case "fx 1":
return "hotcue_1_";
break;
case "fx 2" :
return "hotcue_2_";
break;
case "fx 3" :
return "hotcue_3_";
break;
}
};
HerculesMp3.hotcue = function (deck, control, value) {
hotcue_string = HerculesMp3.fxbutton(HerculesMp3.controls.inputs[control].name);
if(value){
is_hold_hotcue[control] = false;
timerhotcueID[control] = engine.beginTimer(500,"HerculesMp3.hchold("+deck+","+control+","+"\""+hotcue_string+"\")",true);
}
else {
engine.stopTimer(timerhotcueID[control]);
if(!is_hold_hotcue[control]){
if(!engine.getValue("[Channel"+deck+"]",hotcue_string+"enabled")) {engine.setValue("[Channel"+deck+"]",hotcue_string+"activate",1);}
else{engine.setValue("[Channel"+deck+"]",hotcue_string+"goto",1);}
}
}
};
HerculesMp3.hchold = function (deck,control,hotcuestr){
is_hold_hotcue[control]=true;
engine.setValue("[Channel"+deck+"]",hotcuestr+"clear",1);
};
//Cycle between kill,cue,loop,fx
HerculesMp3.mode = function (group, control, value, status) {
var n = HerculesMp3.controls.inputs[control].channel;
var group = Deck[n];
// took from other Hercules scripts
if (value) { // Only do stuff when pushed, not released.
currentMode = HerculesMp3.controls.inputs[control].mode;
nextMode = currentMode < HerculesMp3.buttons123Modes.length-1 ? currentMode+1 : 0;
HerculesMp3.controls.inputs[control].mode = nextMode;
sNextMode = HerculesMp3.buttons123Modes[nextMode];
sCurrentMode = HerculesMp3.buttons123Modes[currentMode];
for ( fxcontrol in HerculesMp3.controls.outputs){
if(HerculesMp3.controls.outputs[fxcontrol].channel == n &&
HerculesMp3.controls.outputs[fxcontrol].name == sCurrentMode+" mode")
{
currentLed = fxcontrol;
}
if(HerculesMp3.controls.outputs[fxcontrol].channel == n &&
HerculesMp3.controls.outputs[fxcontrol].name == sNextMode+" mode")
{
nextLed = fxcontrol;
}
}
switch (sNextMode) {
case "kill":
HerculesMp3.led(currentLed, false);
break;
case "fx":
returnblink[n] = false;
if(HerculesMp3.controls.outputs[nextLed].isblinking){
HerculesMp3.ledblink(nextLed, false);
returnblink[n] = true;
}
HerculesMp3.led(nextLed, true);
//print("HerculesMp3.buttons123mode: Switching to " + sNextMode + " mode");
break;
case "cue":
if(returnblink[n]){
HerculesMp3.ledblink(currentLed, true);
}
HerculesMp3.led(currentLed, false);
HerculesMp3.led(nextLed, true);
//print("HerculesMp3.buttons123mode: Switching to " + sNextMode + " mode");
break;
case "loop":
HerculesMp3.led(currentLed, false);
HerculesMp3.led(nextLed, true);
//print("HerculesMp3.buttons123mode: " + sNextMode + " mode");
break;
}
}
};
//fx buttons
HerculesMp3.fx = function (group, control, value, status) {
var n = HerculesMp3.controls.inputs[control].channel;
var fxdeck = n==1 ? 0x07 : 0x01;
var currentMode = HerculesMp3.controls.inputs[fxdeck].mode;
switch (HerculesMp3.buttons123Modes[currentMode]){
case "kill" :
if (value){
HerculesMp3.controls.inputs[control].used = true;
}
else { HerculesMp3.controls.inputs[control].used = false;
}
break;
case "loop" :
HerculesMp3.loop(n, control, value);
break;
case "cue" :
HerculesMp3.hotcue(n, control, value);
break;
case "fx" :
if (HerculesMp3.controls.inputs[control].name == "fx 1"){
if(value)
{
scratch[n]=!scratch[n];
HerculesMp3.controls.outputs[nextLed].isblinking = scratch[n];
returnblink[n] = scratch[n];
}
}
if (HerculesMp3.controls.inputs[control].name == "fx 2"){
if(value){bpm.tapButton(n);}
}
if (HerculesMp3.controls.inputs[control].name == "fx 3"){
if(value){
enable_beats = !enable_beats;
if(enable_beats){
engine.connectControl("[Channel1]", "playposition", "HerculesMp3.playpositionA");
engine.connectControl("[Channel1]","file_bpm","HerculesMp3.bpconnectA");
engine.connectControl("[Channel2]", "playposition", "HerculesMp3.playpositionB");
engine.connectControl("[Channel2]","file_bpm","HerculesMp3.bpconnectB");
}
else
{
engine.connectControl("[Channel1]", "playposition", "HerculesMp3.playpositionA",true);
engine.connectControl("[Channel1]","file_bpm","HerculesMp3.bpconnectA",true);
engine.connectControl("[Channel2]", "playposition", "HerculesMp3.playpositionB",true);
engine.connectControl("[Channel2]","file_bpm","HerculesMp3.bpconnectB",true);
}
}
}
break;
}
};
HerculesMp3.pitchpot = function (group, control, value, status) {
var n = HerculesMp3.controls.inputs[control].channel;
var fxdeck = n ==1 ? 0x07 : 0x01;
var currentMode = HerculesMp3.controls.inputs[fxdeck].mode;
var name = "none";
if (currentMode == 0){
for ( fxcontrol in HerculesMp3.controls.inputs){
if(HerculesMp3.controls.inputs[fxcontrol].channel == n && HerculesMp3.controls.inputs[fxcontrol].used)
{
name = HerculesMp3.controls.inputs[fxcontrol].name;
}
}
}
if (name == "fx 1"){
chan = Deck[n];
action = "pregain";
min = -4;
max = 4;
}
else if (name == "fx 2"){
chan = "[Master]";
action="headVolume";
min=0;
max=5;
}
else if (name == "fx 3"){
chan = "[Master]";
action="headMix";
min=-1;
max=1;
}
else {
chan = Deck[n];
action = "rate";
min = -1;
max = 1;
}
if(value){
var increment = (max-min)/50;
increment = (value <= 0x3F) ? increment : increment * -1;
var newValue = engine.getValue(chan,action) + increment;
newValue = newValue > max ? max : newValue < min ? min : newValue;
engine.setValue(chan,action,newValue);
}
};
HerculesMp3.jog_wheel = function (group, control, value, status) {
var n = HerculesMp3.controls.inputs[control].channel;
if(scratch[n]){
if(value){
if (scratch_timer_on[n])
{
engine.stopTimer(scratch_timer[n]);
scratch_timer_on[n] = false;
}
if (!engine.getValue(Deck[n],"scratch2_enable")){
engine.scratchEnable(n, 128, 33+1/3, 1.0/8*(0.500), (1.0/8)*(0.500)/32);
}
else {
var newValue=(value-0x40);
engine.scratchTick(n,-newValue);
}
}
if(engine.getValue(Deck[n],"scratch2_enable"))
{
//when not moved for 200 msecs, probably we are not touching the wheel anymore
scratch_timer[n] = engine.beginTimer(200,"HerculesMp3.jog_wheelhelper("+n+")",true);
scratch_timer_on[n] = true;
}
}
else {
if(value){
if (!engine.getValue(Deck[n],"play")) {
var jogValue = value >=0x40 ? value - 0x80 : value;
jogValue = jogValue*jog_sens;
engine.setValue(Deck[n],"jog", jogValue);
}
}
}
};
HerculesMp3.jog_wheelhelper = function(n) {
engine.scratchDisable(n);
scratch_timer_on[n] = false;
}
HerculesMp3.joystick = function (group, control, value, status) {
if(!value)
engine.setValue("[Playlist]","SelectPrevTrack", 1);
if(value == 0x7F)
engine.setValue("[Playlist]","SelectNextTrack",1);
};
HerculesMp3.loadSelectedTrack = function (group, control, value, status) {
if (value) { // Only do stuff when pushed, not released.
var deck = HerculesMp3.controls.inputs[control].channel;
engine.setValue(Deck[deck] , "LoadSelectedTrack", 1);
}
};
//This is called when bpm is calculated.
//Reusing one function for both decks caused a strange behavior and I am too lazy to fix it.
HerculesMp3.bpconnectA = function (valueA) {
if(valueA){
HerculesMp3.controls.outputs[0x0A].beatlen = 6000/valueA;
}
else {
HerculesMp3.controls.outputs[0x0A].beatlen=0;
}
};
HerculesMp3.bpconnectB = function (valueB) {
if(valueB){
HerculesMp3.controls.outputs[0x04].beatlen = 6000/valueB;
}
else {
HerculesMp3.controls.outputs[0x04].beatlen=0;
}
};
//These are for beat blink.
HerculesMp3.bblinkA = function (csecA) {
var actposA = engine.getValue(Deck[1], "duration")*engine.getValue(Deck[1], "playposition")*100;
if(engine.getValue(Deck[1],"play")){
if(actposA) {
if( (actposA-csecA/6)<bshot[1]*csecA && actposA>((bshot[1]-1)*csecA) ) {
if(!HerculesMp3.controls.outputs[0x0A].status)
{HerculesMp3.led(0x0A, true);
}
}
if((actposA+csecA/3)>(bshot[1]-1)*csecA && (actposA+csecA/6)<bshot[1]*csecA) {
if(HerculesMp3.controls.outputs[0x0A].status) HerculesMp3.led(0x0A, false);
}
}
}
else
{
if(HerculesMp3.controls.outputs[0x0A].status)
{
HerculesMp3.led(0x0A, false);
}
}
};
HerculesMp3.bblinkB = function (csecB) {
var actposB = engine.getValue(Deck[2], "duration")*engine.getValue(Deck[2], "playposition")*100;
if(engine.getValue(Deck[2],"play")){
if(actposB) {
if( (actposB-csecB/6)<bshot[2]*csecB && actposB>((bshot[2]-1)*csecB) ) {
if(!HerculesMp3.controls.outputs[0x04].status)
{HerculesMp3.led(0x04, true);
}
}
else {
if((actposB+csecB/3)>(bshot[2]-1)*csecB && (actposB+csecB/6)<bshot[2]*csecB) {
if(HerculesMp3.controls.outputs[0x04].status) HerculesMp3.led(0x04, false);
}
}
}
}
else
{
if(HerculesMp3.controls.outputs[0x04].status)
{
HerculesMp3.led(0x04, false);
}
}
};
//Find out where the next beat is.
HerculesMp3.playpositionA = function (value) {
actposA = engine.getValue(Deck[1], "duration")*value*100;
csecA = HerculesMp3.controls.outputs[0x0A].beatlen;
if(csecA) bshot[1] = Math.ceil(actposA/csecA);
};
HerculesMp3.playpositionB = function (value) {
actposB = engine.getValue(Deck[2], "duration")*value*100;
csecB = HerculesMp3.controls.outputs[0x04].beatlen;
if(csecB) bshot[2] = Math.ceil(actposB/csecB);
};