//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2011. All Rights Reserved. -----------------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller ' Pioneer DDJ SX
// Date: 2015 9	 25
// Author: 
//----------------------------------------------------------------------------- 
function getLanguageVersion()
{
	return 1;// do not modify this, this should be 1 for all scripts
}
//----------------------------------------------------------------------------- 
function getFileVersion()
{
	return 1;// update this as needed
}
//----------------------------------------------------------------------------- 
// return a user friendly name for the controller supported
function getControllerUserFriendlyName()
{
	return "PioneerDDJSX";
}
//----------------------------------------------------------------------------- 
// return the communication type that the controller supports 
// this can be either 'midi' or 'hid' (please return only one of them in case the controller supports both)
function getControllerType()
{
	return 'midi';
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// preferred way to identify the controller (using the USB device VID and PID -- vendor and product id)
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; -1 unknown
function getSupportedHidDeviceVID(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
function getSupportedHidDevicePID(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
// this is NOT the preferred way to identify the controller but you should use
// it if the controller does not support standard USB VID and PID identification
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; -1 unknown
function getSupportedHidDeviceName(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// preferred way to identify the controller (if it supports MIDI SysEx)
// return false if the controller does not support this kind of identification
function getSupportedMidiSysExIdString(osId)
{
	// sysex response to 'F0 7E 7F 06 01 F7' (identification request sysex)
	// please note that the response contains 5 bytes in hex format containing
	// the Manufacturer ID (3 bytes) and Model Number (2 bytes)
	// ATTN: the returned value should omit the standard 'F0 7E 00 06 02' message start
	//if(osId==1) return false;
	
	//return "00207908";
	// full string: 00  F0 7E 7F 06 02 00 20 79  08 same as SR :(
	//return false;
}
//----------------------------------------------------------------------------- 
// this is NOT the preferred way to identify the controller but you should use
// it if the controller does not support standard MIDI SysEx identification
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; -1 unknown
function getSupportedMidiDeviceNameForInput(osId)
{
	return "PIONEER DDJ-SX2";// !!! 
	//return false;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	//return "PIONEER DDJ-SX";// !!! MAKE SURE THIS IS INDEED OK !!!
	return false;
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// some variables necessary only for this particular script
var jogWheelsInScratchMode	=[0,0,0,0];
var jogWheelsWasDeckPlaying	=[0,0,0,0];
var shiftButton				=[0,0,0,0];
var deckMode				=[0,0,0,0]; //0=hot cue 1=roll 2=slicer 3=sampler

var samplerBlinkLedStatus		=[0,0,0,0,0,0,0,0];// 2 decks leds, each with 4 samplers // 0 means off; 1 means on; 2 means blink on; 3 means blink off;
var samplerBlinkState = [0,0,0,0,0,0,0,0];
//----------------------------------------------------------------------------- 
// this is called when the controller is initialized and the control is passed to this script
// use this to initialize any variables you might need, the controller' leds, etc
// uniqueId is a unique integer between 0..15 that is guaranteed not to change for 
// a certain opened controller -- please note that there can be many controllers
// of the same type in use at the same time ! Use uniqueId to identify between them
function controllerInit(uniqueId)
{
	//debug('controllerInit PioneerDDJSX ['+uniqueId+']');// this outputs a string to DebugView app on Win
	callSendAllNotifications(uniqueId, true);
	
	//sendMidi(uniqueId,0x90,0x0B,0x09,0x7F); //dj app connected
	
	for(var i=0; i<4; i++)
	{
		sendMidi(uniqueId,0x90,0x0B,i,0x7F); //load buttons
		sendMidi(uniqueId,0x90,i,0x1B,0x7F); //set mode to hot cue (default)	
		
		
		call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	}
}
//----------------------------------------------------------------------------- 
// called just before the controller will be deinitialized and the control will go away from the script
// use to power off any powered leds, etc
function controllerDeinit(uniqueId)
{
	debug('controllerDeinit PioneerDDJSX ['+uniqueId+']');
	callSendAllNotifications(uniqueId, false);
	
	sendMidi(uniqueId,0x90,0x0B,0x09,0x00); //dj app not connected
	
	for(var i=0; i<4; i++)
	{		
		sendMidi(uniqueId,0x90,0x0B,i,0x00); //load buttons
		sendMidi(uniqueId,0x90,i,0x1B,0x7F); // set mode to hot cue

		call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	}
}
//----------------------------------------------------------------------------- 
// this is your main target function to implement the controller -- this is called 
// for each and every MIDI message that comes from the controller itself
// return true if the message was processed by the script and false to let it 
// pass thru the software (eg. so it can be assigned by the user using the LEARN function)
function messageReceived(uniqueId,status,channel,data1,data2)
{
	//debug('messageReceived ['+uniqueId+'] - status:'+status+' channel:'+channel+' data1:'+data1+' data2:'+data2);
	var messageNotProcessed=false;
	switch(status)
	{
	//-----------------------------------------------
	// controllers: sliders, knobs, jog-wheels, encoders ('moving' things)
	case 0xB0:
		switch(data1)
		{
		// global
		case 0x40: if(channel==6) {
					var val1 = (data2>0x40 ? data2-0x80 : data2);
					}
					call('lbMoveCursor', val1);
					break; //library curser up down		
		case 0x03: if(channel == 6) call('setSamplerMasterVolume', data2); else call('setDeckPos', channel, data2); break; // sampler volume control
		case 0x1F: call('setCrossfader', data2); break; //crossfader
		case 0x01: call('setCFCurve', data2); break; // crossfader curve
		

		// decks
		case 0x13: call('setDeckVolume', channel, data2); break; //volume slider
		case 0x00: call('setDeckPitch', channel, 0x7F-data2); break; //pitch slider
		case 0x04: if(channel<4) call('setDeckGain', channel, data2);else call('deckFxEchoDW', channel-4, data2); break; // deck gain /  FX Phaser DW 
		case 0x07: call('setDeckEqHigh', channel, data2); break; // eq high
		case 0x0B: call('setDeckEqMid', channel, data2); break; // eq mid
		case 0x0F: call('setDeckEqLow', channel, data2); break; // eq low
		//case 0x03: call('setDeckPos', channel, data2); break; // needle drop
		
		case 0x17: if(channel==6) call('setDeckCutoff', 0, data2); break; // Hp filter deck 1
		case 0x18: if(channel==6) call('setDeckCutoff', 1, data2); break; // Hp filter deck 2	
		case 0x19: if(channel==6) call('setDeckCutoff', 2, data2); break; // Hp filter deck 3
		case 0x1A: if(channel==6) call('setDeckCutoff', 3, data2); break; // Hp filter deck 4	
		
		
		
		case 0x21: // params: (deck, increment, total positions per complete revolution) 
			if(channel<4)
			{
				var val1 = data2-0x40;
				call('moveDeckJogWheel', channel, val1, 2048);
			}
			break;
		
		case 0x22: // 
			if(channel<4)
			{
				var val1 = data2-0x40;
				call('scratchDeckJW', channel, val1, 2048);
			}
			break;	
			
		case 0x23: // vinyl button off params: (deck, increment, total positions per complete revolution) 
			if(channel<4)
			{
				var val1 = data2-0x40;
				call('moveDeckJogWheel', channel, val1, 2048);
			} break;
			
		case 0x02: call('deckFxFlangerDW', channel-4, data2); break; // deck FX Flanger DW
		case 0x06: call('deckFxBeatwawDW', channel-4, data2); break; // deck FX Beatwaw DW
		

		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	case 0x80:
	case 0x90:
		//if(status==0x90) data2 = 0x7F;
		//if(status==0x80) data2 = 0;
		switch(data1)
		{
		// global
		
		//case 0x00: if((status==0x90)&&(data2>0x3F)) call('lbToggleSelect', data2); break;
		//case 0x59: if(data2>0x3F) call('lbBrowserSelect', data2); break;
		//case 0x5A: if(data2>0x3F) call('lbListSelect', data2); break;
		case 0x41: if(data2>0x3F) call('lbListSelect', data2); break;
		case 0x65: if(data2>0x3F) call('lbBrowserSelect', data2); break;
		case 0x78: call('showNextPanel', data2); break; // show panel next (penal select button)
		case 0x79: call('showPrevPanel', data2); break; // show panel prev (shift + panel select)
		
		case 0x76: shiftButton[channel] = data2; break; //shift button per deck
		
		// decks
		//mode select
		case 0x1B: deckMode[channel]==0;
					sendMidi(uniqueId,0x90,channel,0x1B,0x7F); break;  //hot cue mode button
		
		case 0x1E: deckMode[channel]==1;
					sendMidi(uniqueId,0x90,channel,0x1E,0x7F); break;   //roll mode button
		
		case 0x20: 
			if(channel==1){
				deckMode[channel]==2;
				sendMidi(uniqueId,0x90,channel,0x20,0x7F);			
			}
			
			
			break; //slicer button
		
		case 0x22: 
				if(channel == 1){
					deckMode[channel]==3;
					sendMidi(uniqueId,0x90,channel,0x22,0x7F); 
				}
					
					break;   //sampler mode button
		
		//case 0x36:
			//debug('0x36 Pressed!' + channel);
			
			//break;
		
		case 0x40: //scratch mode button
			break;
		case 0x46: 
			if(channel==6){
				if(data2){
					call('deckLBLoad', 0, data2); 
					sendMidi(uniqueId,0x90,0x0B,0x00,0x7F); 
				}
				
			}
				
			break; //load deck 1
		
		case 0x47: if(channel==6) 
					{
						if(data2){
							call('deckLBLoad', 1, data2); 
							sendMidi(uniqueId,0x90,0x0B,0x01,0x7F);
						}
						
					}else
					{
					 call('deckFxFlanger', channel-4, data2);
					} break; //load deck 2 / deck flanger
				
		case 0x48: if(channel==6) 
					{
						if(data2){
							call('deckLBLoad', 2, data2); 
							sendMidi(uniqueId,0x90,0x0B,0x02,0x7F);
						}
						
					}else
					{
					 call('deckFxEcho', channel-4, data2);
					} break; //load deck 3 //deck phaser
					 
		case 0x49: if(channel==6) 
					{
						if(data2){
							call('deckLBLoad', 3, data2); 
							sendMidi(uniqueId,0x90,0x0B,0x03,0x7F);
						}
						
					}else if(channel>3)
					{
						call('deckFxBeatwaw', channel-4, data2);
					}  else{
					debug('Slot Pressed');
					}break; //load deck 4 // beatwaw
		
		case 0x4A: call('deckTapBpm', channel-4, data2); debug('TapBPM'); break;//2015-09-23
		
		case 0x58: call('deckSync', channel, data2); break; //sync
		case 0x5C: call('deckMatch', channel, data2); break; //sync
		case 0x38: call('deckReverse', channel, data2); break; //reverse (censor buton)
		case 0x15: call('deckBrake', channel, data2); break; //break (shift + Censor button)
		case 0x79: call('deckSkipBeatNext', channel, data2); break; //beat skip (grid adj button)
		case 0x64: call('deckSkipBarNext', channel, data2); break; // skip bar (shift + Grid adj)
		case 0x65: call('deckSkipBarPrev', channel, data2); break; // skip bar (shift + grid clear)
		
		// pad controls hot cuee mode
		case 0x00: if(channel>6) call('deckCuePos1', channel-7, data2); break; //Cue 1	
		case 0x01: if(channel>6) call('deckCuePos2', channel-7, data2); break; //cue2	
		case 0x02: if(channel>6) call('deckCuePos3', channel-7, data2); break; //cue3
		case 0x03: if(channel>6) call('deckCuePos4', channel-7, data2); break; //cue4
		case 0x04: if(channel>6) call('deckCuePos5', channel-7, data2); break; //cue5
		case 0x05: if(channel>6) call('deckCuePos6', channel-7, data2); break; //cue6
		case 0x06: if(channel>6) call('deckCuePos7', channel-7, data2); break; //cue7
		case 0x07: if(channel>6) call('deckCuePos8', channel-7, data2); break; //cue8
		
		//pad controls roll mode
		
		case 0x10:
			if(channel > 6)call('deckLoopPoint1', channel-7, data2); else call('deckLoopInEnd', channel, data2);
			break;
		case 0x11:
			if(channel > 6)call('deckLoopPoint2', channel-7, data2); else { if(!getValue('looping', channel)) call('deckLoopInEnd', channel, data2);else call('deckLoopExit', channel, data2); }
			break;
		case 0x12:
			if(channel > 6)call('deckLoopPoint3', channel-7, data2); else call('deckLoopLess', channel, data2);
			break;
		case 0x13:
			if(channel > 6)call('deckLoopPoint4', channel-7, data2); else call('deckLoopMore', channel, data2);
			break;
		case 0x14:
			if(channel > 6)call('deckLoopPoint5', channel-7, data2); else { if(!getValue('looping', channel)) call('deckLoop4', channel, data2);else call('deckLoopExit', channel, data2); };
			break;
		
		/*	
		case 0x15:
		break;
		case 0x16:
		break;
		case 0x17:
		break;
		
		
		//pad controls slicer mode
		
		case 0x20:
		case 0x21:
		case 0x22:
		case 0x23:
		case 0x24:
		case 0x25:
		case 0x26:
		case 0x27:
		
		*/
		
	 //change to if(channel>6)	//pad controls sampler mode
		case 0x30: if(channel>6) call('samplerPlay', 1); break; //sampler play 1
		case 0x31: if(channel>6) call('samplerPlay', 2); break; //sampler play 2
		case 0x32: if(channel>6) call('samplerPlay', 3); break; //sampler play 3
		case 0x33: if(channel>6) call('samplerPlay', 4); break; //sampler play 4
		case 0x34: if(channel>6) call('samplerPlay', 5); break; //sampler play 5
		case 0x35: if(channel>6) call('samplerPlay', 6); break; //sampler play 6
		case 0x36: if(channel>6){ call('samplerPlay', 7); } else call('holdDeckJogWheel', channel, data2); break; //sampler play 7
		case 0x37: if(channel>6) call('samplerPlay', 8); break; //sampler play 1
		
		//shift + pad controls hot cue mode
		case 0x08: if(channel>6) call('deckCuePos1Clear', channel-7, data2); break; //Cue 1 clear
		case 0x09: if(channel>6) call('deckCuePos2Clear', channel-7, data2); break; //cue2 clear
		case 0x0A: if(channel>6) call('deckCuePos3Clear', channel-7, data2);else call('deckSkipBeatPrev', channel, data2); break; //cue3 clear
		case 0x0B: if(channel>6) call('deckCuePos4Clear', channel-7, data2);else call('deckPlayPause', channel, data2); break; // play pause //cue4 clear
		case 0x0C: if(channel>6) call('deckCuePos5Clear', channel-7, data2);else call('deckCue', channel, data2); break; // cue // cue5 clear
		case 0x0D: if(channel>6) call('deckCuePos6Clear', channel-7, data2); break; //cue6 clear
		case 0x0E: if(channel>6) call('deckCuePos7Clear', channel-7, data2); break; //cue7 clear
		case 0x0F: if(channel>6) call('deckCuePos8Clear', channel-7, data2); break; //cue8 clear
	
	
		
		case 0x1A: call('deckKeyLock', channel, data2); break; //key lock
		
		case 0x18:
			if(data2)if(channel>6) call('deckLoopPos1', channel-7, 0x00); break; //Cue 1 clear
		break;
		
		case 0x60: if(data2>0x3F)
					{ 
					debug('Tollen Test');
					debug('messageReceived ['+uniqueId+'] - status:'+status+' channel:'+channel+' data1:'+data1+' data2:'+data2);
					var currentPitchRange = getValue('pitchRange');
					currentPitchRange = currentPitchRange + 1; if(currentPitchRange>6) currentPitchRange = 1;
					call('setPitchRange', currentPitchRange);
					} 
					break;
		case 0x54: call('deckMonitor', channel, data2); break; //pfl
		
		//case 0x10: call('deckLoopInEnd', channel, data2); break; //loop in / end decks 1-4					   
		//case 0x11: if(!getValue('looping', channel)) call('deckLoopInEnd', channel, data2);else call('deckLoopExit', channel, data2); break; //loop out or exit
		//case 0x14: if(!getValue('looping', channel)) call('deckLoop4', channel, data2);else call('deckLoopExit', channel, data2); break; //auto 4 beat loop / end decks 1-4				   
		//case 0x12: call('deckLoopLess', channel, data2); break; //loop less  decks 1-4
		//case 0x13: call('deckLoopMore', channel, data2); break; //loop more decks 1-4
		case 0x4D: call('deckLoopReloop', channel, data2); break; // reloop  / shift + loop out	
		
		case 0x61:
			call('deckLoopPrev', channel, data2);
			break;
		case 0x62:
			call('deckLoopNext', channel, data2);
			break;
		
		case 0x3A: jogWheelsInScratchMode[channel] = data2; break;

		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	default: messageNotProcessed = true;
	}
	if(messageNotProcessed) debug('messageReceived ['+uniqueId+'] - status:'+status+' channel:'+channel+' data1:'+data1+' data2:'+data2);
	return !messageNotProcessed;
}
//----------------------------------------------------------------------------- 
// this is called by the software whenever something important changes (eg. play status, song changed, etc)
// depending on the notification type it may refer to a global event (deck is -1) or a specific deck (deck >= 0)
// and can contain any/all of the parameters: param 1 is an integer, param 2 is a float, param 3 is a string
function notificationReceived(uniqueId,name,deck,param1,param2,param3)
{
	//debug('notif ['+uniqueId+'] name='+name + ' deck='+deck + ' p1(int)='+param1 + ' p2(float)='+param2 + ' p3(str)='+param3);
	var nameLen = name.length;
	if(nameLen==8)
	{
		var name1 = name.substr(0, nameLen-1);
		if(name1=='sampler')
			{
				//debug('SAMPLER SAMPLER SAMPLER SAMPLER SAMPLER');
				//debug('notif ['+uniqueId+'] name='+name + ' deck='+deck + ' p1(int)='+param1 + ' p2(float)='+param2 + ' p3(str)='+param3);
				var samplerIdx = parseInt(name.charAt(nameLen-1))-1;		
				if(!param1) 
				{
					samplerBlinkLedStatus[samplerIdx] = 0;
					if(name=='sampler1'){ 
					sendMidi(uniqueId,0x90,7,0x30,0x00);
					sendMidi(uniqueId,0x90,8,0x30,0x00);
					sendMidi(uniqueId,0x90,9,0x30,0x00);
					sendMidi(uniqueId,0x90,10,0x30,0x00);
					}
					if(name=='sampler2'){ 
					sendMidi(uniqueId,0x90,7,0x31,0x00);
					sendMidi(uniqueId,0x90,8,0x31,0x00);
					sendMidi(uniqueId,0x90,9,0x31,0x00);
					sendMidi(uniqueId,0x90,10,0x31,0x00);
					}
					if(name=='sampler3'){ 
					sendMidi(uniqueId,0x90,7,0x32,0x00);
					sendMidi(uniqueId,0x90,8,0x32,0x00);
					sendMidi(uniqueId,0x90,9,0x32,0x00);
					sendMidi(uniqueId,0x90,10,0x32,0x00);
					}
					if(name=='sampler4'){ 
					sendMidi(uniqueId,0x90,7,0x33,0x00);
					sendMidi(uniqueId,0x90,8,0x33,0x00);
					sendMidi(uniqueId,0x90,9,0x33,0x00);
					sendMidi(uniqueId,0x90,10,0x33,0x00);
					}
					if(name=='sampler5'){ 
					sendMidi(uniqueId,0x90,7,0x34,0x00);
					sendMidi(uniqueId,0x90,8,0x34,0x00);
					sendMidi(uniqueId,0x90,9,0x34,0x00);
					sendMidi(uniqueId,0x90,10,0x34,0x00);
					}
					if(name=='sampler6'){ 
					sendMidi(uniqueId,0x90,7,0x35,0x00);
					sendMidi(uniqueId,0x90,8,0x35,0x00);
					sendMidi(uniqueId,0x90,9,0x35,0x00);
					sendMidi(uniqueId,0x90,10,0x35,0x00);
					}
					if(name=='sampler7'){ 
					sendMidi(uniqueId,0x90,7,0x36,0x00);
					sendMidi(uniqueId,0x90,8,0x36,0x00);
					sendMidi(uniqueId,0x90,9,0x36,0x00);
					sendMidi(uniqueId,0x90,10,0x36,0x00);
					}
					if(name=='sampler8'){ 
					sendMidi(uniqueId,0x90,7,0x37,0x00);
					sendMidi(uniqueId,0x90,8,0x37,0x00);
					sendMidi(uniqueId,0x90,9,0x37,0x00);
					sendMidi(uniqueId,0x90,10,0x37,0x00);
					}
					// instead of Math.floor(19/4), parseInt(19/4) = 4 can also be used
				}else
				{
					if(name=='sampler1'){ 
						sendMidi(uniqueId,0x90,7,0x30,0x7F);
						sendMidi(uniqueId,0x90,8,0x30,0x7F);
						sendMidi(uniqueId,0x90,9,0x30,0x7F);
						sendMidi(uniqueId,0x90,10,0x30,0x7F);
					
					}
					if(name=='sampler2'){ 
						sendMidi(uniqueId,0x90,7,0x31,0x7F);
						sendMidi(uniqueId,0x90,8,0x31,0x7F);
						sendMidi(uniqueId,0x90,9,0x31,0x7F);
						sendMidi(uniqueId,0x90,10,0x31,0x7F);
					
					}
					if(name=='sampler3'){ 
						sendMidi(uniqueId,0x90,7,0x32,0x7F);
						sendMidi(uniqueId,0x90,8,0x32,0x7F);
						sendMidi(uniqueId,0x90,9,0x32,0x7F);
						sendMidi(uniqueId,0x90,10,0x32,0x7F);
					
					}
					if(name=='sampler4'){ 
						sendMidi(uniqueId,0x90,7,0x33,0x7F);
						sendMidi(uniqueId,0x90,8,0x33,0x7F);
						sendMidi(uniqueId,0x90,9,0x33,0x7F);
						sendMidi(uniqueId,0x90,10,0x33,0x7F);
					
					}
					if(name=='sampler5'){ 
						sendMidi(uniqueId,0x90,7,0x34,0x7F);
						sendMidi(uniqueId,0x90,8,0x34,0x7F);
						sendMidi(uniqueId,0x90,9,0x34,0x7F);
						sendMidi(uniqueId,0x90,10,0x34,0x7F);
					
					}
					if(name=='sampler6'){ 
						sendMidi(uniqueId,0x90,7,0x35,0x7F);
						sendMidi(uniqueId,0x90,8,0x35,0x7F);
						sendMidi(uniqueId,0x90,9,0x35,0x7F);
						sendMidi(uniqueId,0x90,10,0x35,0x7F);
					
					}
					if(name=='sampler7'){ 
						sendMidi(uniqueId,0x90,7,0x36,0x7F);
						sendMidi(uniqueId,0x90,8,0x36,0x7F);
						sendMidi(uniqueId,0x90,9,0x36,0x7F);
						sendMidi(uniqueId,0x90,10,0x36,0x7F);
					
					}
					if(name=='sampler8'){ 
						sendMidi(uniqueId,0x90,7,0x37,0x7F);
						sendMidi(uniqueId,0x90,8,0x37,0x7F);
						sendMidi(uniqueId,0x90,9,0x37,0x7F);
						sendMidi(uniqueId,0x90,10,0x37,0x7F);
					
					}
					if(param2>0) samplerBlinkLedStatus[samplerIdx] = 2;else samplerBlinkLedStatus[samplerIdx] = 1;
				}
				//debug('Blink Status: '+(samplerBlinkLedStatus[samplerIdx]).toString());
			}
	}
	
	if(deck<4)
	{
		if(name=='cue') 		 
		{
			sendMidi(uniqueId,0x90,deck,0x0C,(param1 ? 0x7F : 0x00)); // cue
			//sendMidi(uniqueId,0x90,0x0B,0x10+deck,(param1 ? 0x7F : 0x00)); //cue jog-wheel
		}
		
		if(name=='play')
		{
			sendMidi(uniqueId,0x90,deck,0x0B,(param1 ? 0x7F : 0x00)); //play button
			sendMidi(uniqueId,0x90,0x0B,0x0C+deck,(param1 ? 0x7F : 0x00)); //play jog-wheel
		}
		
//  <led note="0x0C" name="LED_JOG_PLAY_PAUSE" default="PLAY_PAUSE" channel="11" deck="1" />
//  <led note="0x0D" name="LED_JOG_PLAY_PAUSE" default="PLAY_PAUSE" channel="11" deck="2" />
//  <led note="0x0E" name="LED_JOG_PLAY_PAUSE" default="PLAY_PAUSE" channel="11" deck="3" />
//  <led note="0x0F" name="LED_JOG_PLAY_PAUSE" default="PLAY_PAUSE" channel="11" deck="4" />

		
		if(name=='monitor') 	 sendMidi(uniqueId,0x90,deck,0x54,(param1 ? 0x7F : 0x00)); //pfl
		if(name=='keyLock') 	 sendMidi(uniqueId,0x90,deck,0x1A,(param1 ? 0x7F : 0x00)); //key lock
		if(name=='onbeat') 	 	 sendMidi(uniqueId,0x90,deck,0x58,(param1 ? 0x7F : 0x00)); //sync
		if(name=='reverse') 	 sendMidi(uniqueId,0x90,deck,0x38,(param1 ? 0x7F : 0x00)); //reverse (sensor LED)
		if(name=='brake') 	 	 sendMidi(uniqueId,0x90,deck,0x38,(param1 ? 0x7F : 0x00)); //break (censor led)
		
		if(name=='cuepos1') {	 
		sendMidi(uniqueId,0x90,deck+7,0x00,(param1 ? 0x7F : 0x00)); 		
		sendMidi(uniqueId,0x90,deck+7,0x08,(param1 ? 0x28 : 0x00)); //+ shift 0x28 = red
		}//cue 1
		if(name=='cuepos2'){ 	 
			sendMidi(uniqueId,0x90,deck+7,0x01,(param1 ? 0x7F : 0x00)); //cue 2
			sendMidi(uniqueId,0x90,deck+7,0x09,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos3'){ 	
			sendMidi(uniqueId,0x90,deck+7,0x02,(param1 ? 0x7F : 0x00)); //cue 3
			sendMidi(uniqueId,0x90,deck+7,0x0A,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos4'){ 	 
			sendMidi(uniqueId,0x90,deck+7,0x03,(param1 ? 0x7F : 0x00)); //cue 4
			sendMidi(uniqueId,0x90,deck+7,0x0B,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos5'){ 	 
			sendMidi(uniqueId,0x90,deck+7,0x04,(param1 ? 0x7F : 0x00)); //cue 5
			sendMidi(uniqueId,0x90,deck+7,0x0C,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos6'){ 	 
			sendMidi(uniqueId,0x90,deck+7,0x05,(param1 ? 0x7F : 0x00)); //cue 6
			sendMidi(uniqueId,0x90,deck+7,0x0D,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos7'){ 	 
			sendMidi(uniqueId,0x90,deck+7,0x06,(param1 ? 0x7F : 0x00)); //cue 7
			sendMidi(uniqueId,0x90,deck+7,0x0E,(param1 ? 0x28 : 0x00));
		}
		if(name=='cuepos8') {	 		
			sendMidi(uniqueId,0x90,deck+7,0x07,(param1 ? 0x7F : 0x00)); //cue 8
			sendMidi(uniqueId,0x90,deck+7,0x0F,(param1 ? 0x28 : 0x00));
		}
		if(name=='fxFlanger') 	 sendMidi(uniqueId,0x90,deck+4,0x47,(param1 ? 0x7F : 0x00)); //deck FX flanger
		if(name=='fxEcho') 	 sendMidi(uniqueId,0x90,deck+4,0x48,(param1 ? 0x7F : 0x00)); //deck FX Phaser
		if(name=='fxBeatwaw') 	 sendMidi(uniqueId,0x90,deck+4,0x49,(param1 ? 0x7F : 0x00)); //deck FX Beatwaw 
		
		if(name=='loopIn') 	 	 sendMidi(uniqueId,0x90,deck,0x10,(param1 ? 0x7F : 0x00)); //loop in
		if(name=='looping') 	 
				{
					sendMidi(uniqueId,0x90,deck,0x10,(param1 ? 0x7F : 0x00));// loop in led
					sendMidi(uniqueId,0x90,deck,0x11,(param1 ? 0x7F : 0x00));//loop out led
					sendMidi(uniqueId,0x90,deck,0x14,(param1 ? 0x7F : 0x00));//loop out led
				}


	}
}
//----------------------------------------------------------------------------- 
function getMIDIValueForVU(vu_val)
{
	// translating VU-meter signal from decibels (dB) to 0..127 MIDI range
	var val = 0;
	var step = 12.7;
	if(vu_val>-44) val =  1 * step;
	if(vu_val>-36) val =  2 * step;
	if(vu_val>-28) val =  3 * step;
	if(vu_val>-20) val =  4 * step;
	if(vu_val>-16) val =  5 * step;
	if(vu_val>-12) val =  6 * step;
	if(vu_val> -8) val =  7 * step;
	if(vu_val> -4) val =  8 * step;
	if(vu_val> -2) val =  9 * step;
	if(vu_val> -1) val = 10 * step;
	return Math.floor(val);
}
//----------------------------------------------------------------------------- 
// this is called from time to time by the software (several times per second)
// (it is guaranteed that 'timerTick' will get executed ALWAYS right after notificationReceived)
function timerTick(uniqueId)
{
	//debug('timerTick ['+uniqueId+']');
	
	for(var i=0; i<4; i++)
	{
		var vuDeck = getValue('vumeterDeck', i);// float dB
		sendMidi(uniqueId,0xB0,i,0x02,getMIDIValueForVU(vuDeck));	
		if (getValue('looppos1',i) > -1){
			sendMidi(uniqueId,0x90,i+7,0x10,0x7F);	
		} else{
			sendMidi(uniqueId,0x90,i+7,0x10,0x00);	
		}
		if (getValue('looppos2',i) > -1){
			sendMidi(uniqueId,0x90,i+7,0x11,0x7F);	
		} else{
			sendMidi(uniqueId,0x90,i+7,0x11,0x00);	
		}
		
		if (getValue('looppos3',i) > -1){
			sendMidi(uniqueId,0x90,i+7,0x12,0x7F);	
		} else{
			sendMidi(uniqueId,0x90,i+7,0x12,0x00);	
		}
		if (getValue('looppos4',i) > -1){
			sendMidi(uniqueId,0x90,i+7,0x13,0x7F);	
		} else{
			sendMidi(uniqueId,0x90,i+7,0x13,0x00);	
		}
		if (getValue('looppos5',i) > -1){
			sendMidi(uniqueId,0x90,i+7,0x15,0x7F);	
		} else{
			sendMidi(uniqueId,0x90,i+7,0x15,0x00);	
		}
	
	}
	
	for(var i = 0; i<8; i++){
		switch(i){
			case 0:
			if(samplerBlinkLedStatus[i] == 2){				
				sendMidi(uniqueId,0x90,7,0x30,(samplerBlinkState[i] ? 0x00:0x7F));
				sendMidi(uniqueId,0x90,8,0x30,(samplerBlinkState[i] ? 0x00:0x7F));
				sendMidi(uniqueId,0x90,9,0x30,(samplerBlinkState[i] ? 0x00:0x7F));
				sendMidi(uniqueId,0x90,10,0x30,(samplerBlinkState[i] ? 0x00:0x7F));
				samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
				//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
			} else {
				sendMidi(uniqueId,0x90,0,0x30,0x7F);
			}
			break;
			case 1:
				if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x31,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x31,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x31,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x31,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,0,0x31,0x7F);
				}
			break;
			case 2:
				if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x32,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x32,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x32,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x32,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,0,0x32,0x7F);
				}
			break;
			case 3:
			if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x33,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x33,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x33,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x33,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,7,0x33,0x7F);
				}
			break;
			case 4:
			if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x34,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x34,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x34,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x34,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,7,0x34,0x7F);
				}
			break;
			case 5:
			if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x35,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x35,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x35,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x35,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,1,0x35,0x7F);
				}
			break;
			case 6:
			if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x36,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x36,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x36,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x36,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,7,0x36,0x7F);
				}
			break;
			case 7:
			if(samplerBlinkLedStatus[i] == 2){				
					sendMidi(uniqueId,0x90,7,0x37,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,8,0x37,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,9,0x37,(samplerBlinkState[i] ? 0x00:0x7F));
					sendMidi(uniqueId,0x90,10,0x37,(samplerBlinkState[i] ? 0x00:0x7F));
					samplerBlinkState[i] ? samplerBlinkState[i]=0:samplerBlinkState[i]=1;
					//debug('BLINKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
				} else {
					sendMidi(uniqueId,0x90,7,0x37,0x7F);
				}
			break;
		}
	}
}
//----------------------------------------------------------------------------- 
