//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2011. All Rights Reserved. -----------------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller ' Pioneer DDJ SB-2
// Date: 2016 01 06
// 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 "SLATE Audio";
}
//----------------------------------------------------------------------------- 
// 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 (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 getSupportedMidiDeviceVID(osId)
{	
	return 0x23C7;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDevicePID(osId)
{	
	return 0x0467;	
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// 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 "0001000A00000000F7 ";
	
}
//----------------------------------------------------------------------------- 
// 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 "SLATE4 Audio";// !!! 
	
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	return "SLATE4 Audio"
	//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];
var shiftPressed = 0;
var bankFxIsOn 				= [[0,0,0], [0,0,0], [0,0,0], [0,0,0]];
var fxLevel                 = [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<2; 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++)
	{		
	
		var channel = i;
		if(i == 2)
			channel = 4;
		if(i == 3)
			channel = 5;
			
		sendMidi(uniqueId,0x90,channel,0x36,0x00);		
		sendMidi(uniqueId,0x90,channel,0x38,0x00);
		sendMidi(uniqueId,0x90,channel,0x3C,0x00);
		sendMidi(uniqueId,0x90,channel,0x3E,0x00);
		//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 deck = channel;
	if(channel == 4)
		deck = 2;
	if(channel == 5)
		deck = 3;
	
	var messageNotProcessed=false;
	switch(status)
	{
	//-----------------------------------------------
	// controllers: sliders, knobs, jog-wheels, encoders ('moving' things)
	case 0xB0:
		switch(data1)
		{		
		// global
		case 0x01://done
			call('setDeckPitch', deck, 0x7F-data2);
			break;
		case 0x02:break;
		case 0x03://done
			fxLevel[deck] = data2;
			
			if(bankFxIsOn[deck][0])
				call('deckFxEchoDW', deck, fxLevel[deck]);
			
			if(bankFxIsOn[deck][1])
				call('deckFxFlangerDW', deck, fxLevel[deck]); 
			
			if(bankFxIsOn[deck][2])
				call('deckFxBeatwawDW', deck, fxLevel[deck]);
				
			break;
		case 0x04: //done
			if(jogWheelsInScratchMode[deck]){
				var val1 = data2-0x40;
				
				call('scratchDeckJW', deck, val1, 150);
			
			} else {
				var val1 = data2-0x40;
				call('moveDeckJogWheel', deck, val1, 150);
			}
			break;
		case 0x05: //done
			//wetdry fx 2
			switch(channel){
				case 0:
				case 1:
					break;
				case 3:
					call('setDeckEqMid', 0, data2);
					break;
			}
			break;
		case 0x06: //done
			//wetdry fx 3
			switch(channel){
				case 0:
				case 1:
					break;
				case 3:
					call('setDeckEqMid', 1, data2);
					break;
			}
			break;
		case 0x07: //done
		//wetdry fx 2
			switch(channel){
				case 0:
				case 1:
					break;
				case 3:
					call('setDeckEqMid', 2, data2);
					break;
			}
		break;
		case 0x08: //done
		//wetdry fx 2
			switch(channel){
				case 0:
				case 1:
					break;
				case 3:
					call('setDeckEqMid', 3, data2);
					break;
			}
		break;
		case 0x09: //done
			call('setDeckEqHigh', 0, data2);
			break;
		case 0x0A: //done
			call('setDeckEqHigh', 1, data2);
			break;
		case 0x0B: //done
			call('setDeckEqHigh', 2, data2);
			break;
		case 0x0C: //done
			call('setDeckEqHigh', 3, data2);
			break;
		case 0x0D: //done
			call('setDeckEqLow', 0, data2);
			break;
		case 0x0E: //done	
			call('setDeckEqLow', 1, data2);
			break;
		case 0x0F: //done
			call('setDeckEqLow', 2, data2);
			break;
		case 0x10: //done
			call('setDeckEqLow', 3, data2);
			break;
		case 0x11: //done
			call('setDeckCutoff', 0, data2);
			break;
		case 0x12: //done
			call('setDeckCutoff', 1, data2);
			break;
		case 0x13: //done
			call('setDeckCutoff', 2, data2);
			break;
		case 0x14: //done
			call('setDeckCutoff', 3, data2);
			break;
		case 0x15: //done
			call('setDeckVolume', 0, data2);
			break;
		case 0x16: //done
			call('setDeckVolume', 1, data2);
			break;
		case 0x17: //done
			call('setDeckVolume', 2, data2);
			break;
		case 0x18: //done
			call('setDeckVolume', 3, data2);
			break;
		case 0x19:
			call('setCrossfader', data2);
			break;
		case 0x1A:
			call('setCuePgmMix', data2);
			break;
		case 0x1B:
			call('setMasterGain', data2);
			break;
		case 0x1C:break;
		case 0x1D:break;
		case 0x1E:
			var val1 = (data2>0x40 ? 1 : -1);
			call('lbMoveCursor', val1);			
			break;
		case 0x1F:break;
		case 0x20:break;
		case 0x20:break;
		case 0x21:break;
		case 0x22:break;
		case 0x23:break;
		case 0x24:break;
		case 0x25:break;
		case 0x26:break;
		case 0x27:break;
		case 0x28:break;
		case 0x29:break;
		case 0x2A:break;
		case 0x2B:break;
		case 0x2C:break;
		case 0x2D:break;
		case 0x2E:break;
		case 0x2F:break;
		case 0x30:break;
		case 0x31:break;
		case 0x32:break;
		case 0x33:break;
		case 0x34:break;
		case 0x35:break;
		case 0x36:break;
		case 0x37:break;
		case 0x38:break;
		case 0x39:break;
		case 0x3A:break;
		case 0x3B:break;
		case 0x3C:break;
		case 0x3D:break;
		case 0x3E:break;
		case 0x3F:break;
		case 0x40:break;
		case 0x41:break;
		case 0x42:break;
		case 0x43:break;
		case 0x44:break;
		case 0x45:break;
		case 0x46:break;
		case 0x47:break;
		case 0x48:break;
		case 0x49:break;
		case 0x4A:break;
		case 0x4B:break;
		case 0x4C:break;
		case 0x4D:break;
		case 0x4E:break;
		case 0x4F:break;
		case 0x50:break;
		case 0x51:break;
		case 0x52:break;
		case 0x53:break;
		case 0x54:break;
		case 0x55:break;
		case 0x56:break;
		case 0x57:break;
		case 0x58:break;
		case 0x59:break;
		case 0x5A:break;
		case 0x5B:break;
		case 0x5C:break;
		case 0x5D:break;
		case 0x5E:break;
		case 0x5F:break;
		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	case 0x80:
	case 0x90:		
		switch(data1)
		{
		case 0x01: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					if(data2)
						call('deckPlayPause', deck, data2);
					break;
				case 3:
					if(data2)
						call('deckLBLoad', 0, data2); 
					break;
			}
		break;
		case 0x02: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					//if(data2)
						call('deckCue', deck, data2);
					break;
				case 3:
					//if(data2)
						call('deckLBLoad', 1, data2); 
					break;
			}
		break;
		case 0x03:
			switch(channel){
				case 3:
					call('deckLBLoad', 2, data2);
					break;
				default:
				call('deckSync', deck, data2);
			}
			
		break;
		case 0x04: //done
			switch(channel){
				case 3:
					call('deckLBLoad', 3, data2);
					break;
				default:
				call('deckKeyLock', deck, data2);
			}
			
				
			break;
		case 0x05: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
				if(data2){
					var currentPitchRange = getValue('pitchRange');
					currentPitchRange = currentPitchRange + 1; if(currentPitchRange>6) currentPitchRange = 1;
						call('setPitchRange', currentPitchRange);
					}						
					break;
				case 3:
					if(data2)					
						call('deckMonitor', 0, data2);
					break;
			}	
			break;
		case 0x06: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					//if(data2){
						if(shiftPressed){
							call('deckCuePos1Clear', deck, data2);
						} else {							
							call('deckCuePos1', deck, data2);	
						}
					//}
					break;
				case 3:
					if(data2)					
						call('deckMonitor', 1, data2);
					break;
			}	
			break;
		case 0x07: //done
			switch(channel){
				case 3:
					if(data2)					
						call('deckMonitor', 2, data2);
					break;
				default:
					if(data2){
						call('deckLoopInEnd', deck, data2);
					}
			}
			break;
		case 0x08: //done
			switch(channel){
				case 3:
					if(data2)					
						call('deckMonitor', 3, data2);
					break;
				default:
					if(data2)
						call('deckLoop1_8', deck, data2);
			}
			break;
		case 0x09: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					//if(data2){
						if(shiftPressed){
							call('deckCuePos2Clear', deck, data2);
						} else {							
							call('deckCuePos2', deck, data2);	
						}
					//}
					break;
				case 3:
					if(data2)
						call('lbToggleSelect', data2);
					break;
			}
			break;
		case 0x0A: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					if(data2)
						call('deckLoopInEnd', deck, data2);
					break;
				case 3:
					//BackButton
					break;
			}
			break;
		case 0x0B: //done
			if(data2)
				call('deckLoop1_4', deck, data2);
			break;
		case 0x0C: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos3Clear', deck, data2);
				} else {							
					call('deckCuePos3', deck, data2);	
				}
			//}
			break;
		case 0x0D: //done
			switch(channel){
				case 0:
				case 1:
				case 4:
				case 5:
					if(data2)
						call('deckLoopExit', deck, data2);
					break;
				case 3:
					shiftPressed = data2;
					break;
			}			
			break;
		case 0x0E: //done
			if(data2)
				call('deckLoop1_2', deck, data2);
			break;
		case 0x0F: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos4Clear', deck, data2);
				} else {							
					call('deckCuePos4', deck, data2);	
				}
			//}
			break;
		case 0x10: //done
			if(data2)
				call('deckLoopLess', deck, data2);
				
			break;
		case 0x11: //done
			if(data2)
				call('deckLoop1', deck, data2);
			break;
		case 0x12: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos5Clear', deck, data2);
				} else {							
					call('deckCuePos5', deck, data2);	
				}
			//}
			break;
		case 0x13:break;
		case 0x14: //done
			if(data2)
				call('deckLoop2', deck, data2);
			break;
		case 0x15: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos6Clear', deck, data2);
				} else {							
					call('deckCuePos6', deck, data2);	
				}
			//}
			break;
		case 0x16:break;
		case 0x17: //done
			if(data2)
				call('deckLoop4', deck, data2);
			break;
		case 0x18: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos7Clear', deck, data2);
				} else {							
					call('deckCuePos7', deck, data2);	
				}
			//}
			break;
		case 0x19:break;
		case 0x1A: //done
			if(data2)
				call('deckLoop8', deck, data2);
			break;
		case 0x1B: //done
			//if(data2){
				if(shiftPressed){
					call('deckCuePos8Clear', deck, data2);
				} else {							
					call('deckCuePos8', deck, data2);	
				}
			//}
		break;
		case 0x1C:break;
		case 0x1D: //done
			if(data2)
				call('deckLoop16', deck, data2);
			break;
		case 0x1E:
			if(data2)
				call('samplerPlay', 1);
			break;
		case 0x1F:break;
		case 0x20: //done
				call('deckLoopPoint1', deck, data2);
			break;		
		case 0x21:
			if(data2)
				call('samplerPlay', 2);
			break;
		case 0x22:break;
		case 0x23: //done
				call('deckLoopPoint2', deck, data2);
			break;
		case 0x24:
			if(data2)
				call('samplerPlay', 3);
			break;
		case 0x25:break;
		case 0x26: //done
				call('deckLoopPoint3', deck, data2);
			break;
		case 0x27:
			if(data2)
				call('samplerPlay', 4);
			break;
		case 0x28:break;
		case 0x29: //done
				call('deckLoopPoint4', deck, data2);
			break;
		case 0x2A:
			if(data2)
				call('samplerPlay', 5);
			break;
		case 0x2B:break;
		case 0x2C: //done
				call('deckLoopPoint5', deck, data2);
			break;
		case 0x2D:
			if(data2)
				call('samplerPlay', 6);
			break;
		case 0x2E:break;
		case 0x2F:break;
		case 0x30:
			if(data2)
				call('samplerPlay', 7);
			break;
		case 0x31:break;
		case 0x32:break;
		case 0x33:
			if(data2)
				call('samplerPlay', 8);
			break;
		case 0x34:break;
		case 0x35:break;
		case 0x36: //done
			if(data2){
				bankFxIsOn[deck][0] = (bankFxIsOn[deck][0] ? 0x00 : 0x7F);
				sendMidi(uniqueId,0x90,channel,0x36,bankFxIsOn[deck][0]);
				if(bankFxIsOn[deck][0]){
					call('deckFxEchoDW', deck, fxLevel[deck]);				
				} else {
					call('deckFxEchoDW', deck, 0x00);
				}				
			}
		break;
		case 0x37:break;
		case 0x38: //done
		//debug('Vinyl Button Pressed');
			if(data2){
				jogWheelsInScratchMode[deck] = (jogWheelsInScratchMode[deck] == 0x00 ? 0x7F : 0x00);
				sendMidi(uniqueId,0x90,channel,0x38,jogWheelsInScratchMode[deck]);
			}
		break;
		case 0x39: //done
			if(jogWheelsInScratchMode[deck])
				call('holdDeckJogWheel', deck, data2);
			
			//debug('Jog wheel Moving');
			break;
		case 0x3A:break;
		case 0x3B:break;
		case 0x3C: //done
			if(data2){
				bankFxIsOn[deck][1] = (bankFxIsOn[deck][1] ? 0x00 : 0x7F);
				sendMidi(uniqueId,0x90,channel,0x3C,bankFxIsOn[deck][1]);
				
				if(bankFxIsOn[deck][1]){
					call('deckFxFlangerDW', deck, fxLevel[deck]);
				} else {
					call('deckFxFlangerDW', deck, 0x00);
				}
			}
			break;
		case 0x3D:break;
		case 0x3E: //done
			if(data2){
				bankFxIsOn[deck][2] = (bankFxIsOn[deck][2] ? 0x00 : 0x7F);
				sendMidi(uniqueId,0x90,channel,0x3E,bankFxIsOn[deck][2]);
				
				if(bankFxIsOn[deck][2]){
					call('deckFxBeatwawDW', deck, fxLevel[deck]);
				} else {
					call('deckFxBeatwawDW', deck, 0x00);
				}
			}
			break;
		case 0x3F:break;
		case 0x40:break;
		case 0x41:
			if(data2)
				call('deckBrake', deck, data2);
			break;
		case 0x42:break;
		case 0x43:break;
		case 0x44:break;
		case 0x45:break;
		case 0x46:break;
		case 0x47:break;
		case 0x48:break;
		case 0x49:break;
		case 0x4A:break;
		case 0x4B:break;
		case 0x4C:break;
		case 0x4D:break;
		case 0x4E:break;
		case 0x4F:break;
		case 0x50:break;
		case 0x51:break;
		case 0x52:break;
		case 0x53:break;
		case 0x54:
			call('deckMatch', deck, data2);
		break;
		case 0x55:break;
		case 0x56:break;
		case 0x57:break;
		case 0x58:break;
		case 0x59:break;
		case 0x5A:break;
		case 0x5B:break;
		case 0x5C:break;
		case 0x5D:break;
		case 0x5E:break;
		case 0x5F: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;
	var channel = deck;
	if(deck == 2)
		channel = 4;
	if(deck == 3)
		channel = 5;

	if(name=='looppos1'){		
		sendMidi(uniqueId,0x90,channel,0x20,(param1 == -1 ? 0x00 : 0x7F));				
	}
	if(name=='looppos2'){		
		sendMidi(uniqueId,0x90,channel,0x23,(param1 == -1 ? 0x00 : 0x7F));				
	}
	if(name=='looppos3'){		
		sendMidi(uniqueId,0x90,channel,0x26,(param1 == -1 ? 0x00 : 0x7F));				
	}
	if(name=='looppos4'){		
		sendMidi(uniqueId,0x90,channel,0x29,(param1 == -1 ? 0x00 : 0x7F));				
	}
	if(name=='looppos5'){		
		sendMidi(uniqueId,0x90,channel,0x2C,(param1 == -1 ? 0x00 : 0x7F));				
	}
	
	if(nameLen==8)
	{
		var name1 = name.substr(0, nameLen-1);
		
		if(name1=='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,0,0x1E,0x00);
						sendMidi(uniqueId,0x90,1,0x1E,0x00);
						sendMidi(uniqueId,0x90,4,0x1E,0x00);
						sendMidi(uniqueId,0x90,5,0x1E,0x00);
					}
					if(name=='sampler2'){ 
						sendMidi(uniqueId,0x90,0,0x21,0x00);
						sendMidi(uniqueId,0x90,1,0x21,0x00);
						sendMidi(uniqueId,0x90,4,0x21,0x00);
						sendMidi(uniqueId,0x90,5,0x21,0x00);
						
					}
					if(name=='sampler3'){ 
						sendMidi(uniqueId,0x90,0,0x24,0x00);
						sendMidi(uniqueId,0x90,1,0x24,0x00);
						sendMidi(uniqueId,0x90,4,0x24,0x00);
						sendMidi(uniqueId,0x90,5,0x24,0x00);
						
					}
					if(name=='sampler4'){ 
						sendMidi(uniqueId,0x90,0,0x27,0x00);
						sendMidi(uniqueId,0x90,1,0x27,0x00);
						sendMidi(uniqueId,0x90,4,0x27,0x00);
						sendMidi(uniqueId,0x90,5,0x27,0x00);
						
					}
					if(name=='sampler5'){
						sendMidi(uniqueId,0x90,0,0x2A,0x00);
						sendMidi(uniqueId,0x90,1,0x2A,0x00);
						sendMidi(uniqueId,0x90,4,0x2A,0x00);
						sendMidi(uniqueId,0x90,5,0x2A,0x00);
					}
					if(name=='sampler6'){
						sendMidi(uniqueId,0x90,0,0x2D,0x00);
						sendMidi(uniqueId,0x90,1,0x2D,0x00);
						sendMidi(uniqueId,0x90,4,0x2D,0x00);
						sendMidi(uniqueId,0x90,5,0x2D,0x00);
					}
					if(name=='sampler7'){ 
						sendMidi(uniqueId,0x90,0,0x30,0x00);
						sendMidi(uniqueId,0x90,1,0x30,0x00);
						sendMidi(uniqueId,0x90,4,0x30,0x00);
						sendMidi(uniqueId,0x90,5,0x30,0x00);
					}
					if(name=='sampler8'){
						sendMidi(uniqueId,0x90,0,0x33,0x00);
						sendMidi(uniqueId,0x90,1,0x33,0x00);
						sendMidi(uniqueId,0x90,4,0x33,0x00);
						sendMidi(uniqueId,0x90,5,0x33,0x00);
					}				
				}else
				{
					if(name=='sampler1'){ 
						sendMidi(uniqueId,0x90,0,0x1E,0x7F);
						sendMidi(uniqueId,0x90,1,0x1E,0x7F);
						sendMidi(uniqueId,0x90,4,0x1E,0x7F);
						sendMidi(uniqueId,0x90,5,0x1E,0x7F);
					}
					if(name=='sampler2'){ 
						sendMidi(uniqueId,0x90,0,0x21,0x7F);
						sendMidi(uniqueId,0x90,1,0x21,0x7F);
						sendMidi(uniqueId,0x90,4,0x21,0x7F);
						sendMidi(uniqueId,0x90,5,0x21,0x7F);
					}
					if(name=='sampler3'){ 
						sendMidi(uniqueId,0x90,0,0x24,0x7F);
						sendMidi(uniqueId,0x90,1,0x24,0x7F);
						sendMidi(uniqueId,0x90,4,0x24,0x7F);
						sendMidi(uniqueId,0x90,5,0x24,0x7F);
					}
					if(name=='sampler4'){ 
						sendMidi(uniqueId,0x90,0,0x27,0x7F);
						sendMidi(uniqueId,0x90,1,0x27,0x7F);
						sendMidi(uniqueId,0x90,4,0x27,0x7F);
						sendMidi(uniqueId,0x90,5,0x27,0x7F);
					}
					if(name=='sampler5'){
						sendMidi(uniqueId,0x90,0,0x2A,0x7F);
						sendMidi(uniqueId,0x90,1,0x2A,0x7F);
						sendMidi(uniqueId,0x90,4,0x2A,0x7F);
						sendMidi(uniqueId,0x90,5,0x2A,0x7F);
					}
					if(name=='sampler6'){
						sendMidi(uniqueId,0x90,0,0x2D,0x7F);
						sendMidi(uniqueId,0x90,1,0x2D,0x7F);
						sendMidi(uniqueId,0x90,4,0x2D,0x7F);
						sendMidi(uniqueId,0x90,5,0x2D,0x7F);
					}
					if(name=='sampler7'){
						sendMidi(uniqueId,0x90,0,0x30,0x7F);
						sendMidi(uniqueId,0x90,1,0x30,0x7F);
						sendMidi(uniqueId,0x90,4,0x30,0x7F);
						sendMidi(uniqueId,0x90,5,0x30,0x7F);
					}
					if(name=='sampler8'){
						sendMidi(uniqueId,0x90,0,0x33,0x7F);
						sendMidi(uniqueId,0x90,1,0x33,0x7F);
						sendMidi(uniqueId,0x90,4,0x33,0x7F);
						sendMidi(uniqueId,0x90,5,0x33,0x7F);
					}
					if(param2>0) samplerBlinkLedStatus[samplerIdx] = 2;else samplerBlinkLedStatus[samplerIdx] = 1;
				}				
			}
	}
	
	if(deck<4)
	{
		if(name=='cue') 		 
		{
			sendMidi(uniqueId,0x90,channel,0x02,(param1 ? 0x7F : 0x00)); // cue			
		}
		
		if(name=='play')
		{
			sendMidi(uniqueId,0x90,channel,0X01,(param1 ? 0x7F : 0x00)); //play button			
		}
		
		if(name=='monitor') 	 sendMidi(uniqueId,0x90,0X03,deck + 0x05,(param1 ? 0x7F : 0x00)); //pfl
		if(name=='keyLock') 	 sendMidi(uniqueId,0x90,channel,0x04,(param1 ? 0x7F : 0x00)); //key lock
		if(name=='onbeat') 	 	 sendMidi(uniqueId,0x90,channel,0x03,(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,channel,0x06,(param1 ? 0x7F : 0x00));			
		}//cue 1
		if(name=='cuepos2'){ 	 
			sendMidi(uniqueId,0x90,channel,0x09,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos3'){ 	
			sendMidi(uniqueId,0x90,channel,0x0C,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos4'){ 	 
			sendMidi(uniqueId,0x90,channel,0x0F,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos5'){ 	 
			sendMidi(uniqueId,0x90,channel,0x12,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos6'){ 	 
			sendMidi(uniqueId,0x90,channel,0x15,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos7'){ 	 
			sendMidi(uniqueId,0x90,channel,0x18,(param1 ? 0x7F : 0x00));
		}
		if(name=='cuepos8') {	 		
			sendMidi(uniqueId,0x90,channel,0x1B,(param1 ? 0x7F : 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,channel,0x07,(param1 ? 0x7F : 0x00)); //loop in
		if(name=='looping') 	 
				{
					sendMidi(uniqueId,0x90,channel,0x07,(param1 ? 0x7F : 0x00));// loop in led
					sendMidi(uniqueId,0x90,channel,0x0A,(param1 ? 0x7F : 0x00));//loop out led
					samplerBlinkLedStatus[deck] = (samplerBlinkLedStatus[deck] == 0x00 ? 0x7F : 0x00);
					if(param1){
						
						//samplerBlinkState[deck] = samplerBlinkState[deck] ? 0x00 : 0x7F;
					} else {
						samplerBlinkLedStatus[deck] = 0x00;
					}
					//debug('Blink State: ' + samplerBlinkLedStatus[deck].toString());
					sendMidi(uniqueId,0x90,channel,0x0D,samplerBlinkLedStatus[deck]);//loop out led ???
				}
		if(name=='loopSize'){
			sendMidi(uniqueId,0x90,channel,0x08,0x00);
			sendMidi(uniqueId,0x90,channel,0x0B,0x00);
			sendMidi(uniqueId,0x90,channel,0x0E,0x00);
			sendMidi(uniqueId,0x90,channel,0x11,0x00);
			sendMidi(uniqueId,0x90,channel,0x14,0x00);
			sendMidi(uniqueId,0x90,channel,0x17,0x00);
			sendMidi(uniqueId,0x90,channel,0x1A,0x00);
			sendMidi(uniqueId,0x90,channel,0x1D,0x00);
			switch(param1){
				case 8:
					sendMidi(uniqueId,0x90,channel,0x08,0x7F);
					break;
				case 16:
					sendMidi(uniqueId,0x90,channel,0x0B,0x7F);
					break;
				case 32:
					sendMidi(uniqueId,0x90,channel,0x0E,0x7F);
					break;
				case 64:
					sendMidi(uniqueId,0x90,deck,0x11,0x7F);
					break;
				case 128:
					sendMidi(uniqueId,0x90,channel,0x14,0x7F);	
					break;
				case 256:
					sendMidi(uniqueId,0x90,channel,0x17,0x7F);
					break;
				case 512:
					sendMidi(uniqueId,0x90,channel,0x1A,0x7F);
					break;
				case 1024:
					sendMidi(uniqueId,0x90,channel,0x1D,0x7F);
					break;
				default:
					sendMidi(uniqueId,0x90,channel,0x08,0x00);
					sendMidi(uniqueId,0x90,channel,0x0B,0x00);
					sendMidi(uniqueId,0x90,channel,0x0E,0x00);
					sendMidi(uniqueId,0x90,channel,0x11,0x00);
					sendMidi(uniqueId,0x90,channel,0x14,0x00);
					sendMidi(uniqueId,0x90,channel,0x17,0x00);
					sendMidi(uniqueId,0x90,channel,0x1A,0x00);
					sendMidi(uniqueId,0x90,channel,0x1D,0x00);
					break;
			}
		}


	}
}
//----------------------------------------------------------------------------- 
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(samplerBlinkLedStatus[i]){
			//samplerBlinkState[i] = samplerBlinkState[i] ? 0x00 : 0x7F;
			//debug('Blink State: ' + samplerBlinkState[i].toString());
			//sendMidi(uniqueId,0x90,i+7,0x22,samplerBlinkState[i]);//loop out led ???
		//}
	//}
	
}
//----------------------------------------------------------------------------- 
