//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2011. All Rights Reserved. -----------------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller ' Pioneer DDJ RR
// Date: 2016 01 06
// Author: Tollen Francisco
//----------------------------------------------------------------------------- 
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 "DDJ-RB";
}
//----------------------------------------------------------------------------- 
// 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 0x2B73;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDevicePID(osId)
{	
	return 0x000D;	
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// 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 "";// !!! 
	
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	
	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];
var bankFxIsOn 				= [[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 PioneerDDJRR ['+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++)
	{		
		//samplers
		sendMidi(uniqueId,0x90,i + 7,0x30,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x31,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x32,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x33,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x34,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x35,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x36,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x37,0x00);
		//not mapped
		sendMidi(uniqueId,0x90,i + 7,0x20,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x21,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x22,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x23,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x24,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x25,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x26,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x27,0x00);
		
		//looppoints
		sendMidi(uniqueId,0x90,i + 7,0x10,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x11,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x12,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x13,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x14,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x15,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x16,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x17,0x00);
		
		//cuepoints
		sendMidi(uniqueId,0x90,i + 7,0x00,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x01,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x02,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x03,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x04,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x05,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x06,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x07,0x00);
		
		sendMidi(uniqueId,0x90,i,0x58,0x00);//sync
		
		sendMidi(uniqueId,0x90,i,0x0B,0x00);//play
		sendMidi(uniqueId,0x90,i,0x0C,0x00);//cue
		
		sendMidi(uniqueId,0x90,i,0x10,0x00);//loop in
		
		sendMidi(uniqueId,0x90,i,0x11,0x00);//loop out
		
		sendMidi(uniqueId,0x90,i,0x54,0x00);//monitor
		
		sendMidi(uniqueId,0x90,i,0x15,0x00);//reverse
		
		
		sendMidi(uniqueId,0xB0,i,0x02,0x00);//volume meters
		
		//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
	}
		sendMidi(uniqueId,0x90,6,0x46,0x00);//load 1
		sendMidi(uniqueId,0x90,6,0x47,0x00);//load 2
		sendMidi(uniqueId,0x90,6,0x48,0x00);//load 3
		sendMidi(uniqueId,0x90,6,0x49,0x00);//load 4
}
//----------------------------------------------------------------------------- 
// 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 PioneerDDJRR ['+uniqueId+']');
	//callSendAllNotifications(uniqueId, false);
	
	//sendMidi(uniqueId,0x90,0x0B,0x09,0x00); //dj app not connected
	
	for(var i=0; i<4; i++)
	{		
		//samplers
		sendMidi(uniqueId,0x90,i + 7,0x30,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x31,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x32,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x33,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x34,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x35,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x36,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x37,0x00);
		//not mapped
		sendMidi(uniqueId,0x90,i + 7,0x20,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x21,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x22,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x23,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x24,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x25,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x26,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x27,0x00);
		
		//looppoints
		sendMidi(uniqueId,0x90,i + 7,0x10,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x11,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x12,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x13,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x14,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x15,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x16,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x17,0x00);
		
		//cuepoints
		sendMidi(uniqueId,0x90,i + 7,0x00,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x01,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x02,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x03,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x04,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x05,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x06,0x00);
		sendMidi(uniqueId,0x90,i + 7,0x07,0x00);
		
		sendMidi(uniqueId,0x90,i,0x58,0x00);//sync
		
		sendMidi(uniqueId,0x90,i,0x0B,0x00);//play
		sendMidi(uniqueId,0x90,i,0x0C,0x00);//cue
		
		sendMidi(uniqueId,0x90,i,0x10,0x00);//loop in
		
		sendMidi(uniqueId,0x90,i,0x11,0x00);//loop out
		
		sendMidi(uniqueId,0x90,i,0x54,0x00);//monitor
		
		sendMidi(uniqueId,0x90,i,0x15,0x00);//reverse
		
		
		sendMidi(uniqueId,0xB0,i,0x02,0x00);//volume meters
		
		//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
	}
		sendMidi(uniqueId,0x90,6,0x46,0x00);//load 1
		sendMidi(uniqueId,0x90,6,0x47,0x00);//load 2
		sendMidi(uniqueId,0x90,6,0x48,0x00);//load 3
		sendMidi(uniqueId,0x90,6,0x49,0x00);//load 4		
}
//----------------------------------------------------------------------------- 
// 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 0x00: //tempo
			if(channel < 4){
				call('setDeckPitch', channel, 0x7F-data2);
			}			
			break;
		case 0x02://echo
			if(channel > 3){				
				call('deckFxEchoDW', channel-4, data2);			
			}			
			break;
		case 0x03:
			//needle drop
			if(channel == 6){			
				call('setSamplerMasterVolume', data2);
			} else {
				call('setDeckPos', channel, data2);
			}			
			break;
		case 0x04: //trim
			if(channel > 3){
				call('deckFxFlangerDW', channel-4, data2);
			} else {
				call('setDeckGain', channel, data2)
			}			
			break;
		case 0x06:
			if(channel > 3){
				call('deckFxReverbDW', channel-4, data2);
			}
			break;
		case 0x07: //high eq
			call('setDeckEqHigh', channel, data2);
			break;
		case 0x08:
			call('setMasterGain', data2);		
			break;
		case 0x09:
			call('setMonitorGain', data2);		 
			break;
		case 0x0B: //mid eq
			call('setDeckEqMid', channel, data2);
			break;
		case 0x0C: //cue mix
			call('setCuePgmMix', data2);
			break;
		case 0x0F: //low eq
			call('setDeckEqLow', channel, data2);
			break;
		case 0x13: //deck volume
			call('setDeckVolume', channel, data2);
			break;
		case 0x17:
			call('setDeckCutoff', 0, data2);
			break;
		case 0x18:
			call('setDeckCutoff', 1, data2);
			break;
		case 0x19:
			call('setDeckCutoff', 2, data2);
			break;
		case 0x1A:
			call('setDeckCutoff', 3, data2);
			break;
		case 0x1F:
			call('setCrossfader', data2);
			break;
		case 0x21:
			var val1 = data2-0x40;
			call('moveDeckJogWheel', channel, val1, 2048);
			break;
		case 0x22:		
			if(channel < 4){				
				var val1 = data2-0x40;
				call('scratchDeckJW', channel, val1, 200);
			}
			break;
		case 0x40:
			if(channel==6) {
				var val1 = (data2>0x40 ? data2-0x80 : data2);
				call('lbMoveCursor', val1);
			}
			break;
		
		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	case 0x80:
	case 0x90:		
		switch(data1)
		{
		// global
		
		case 0x00://cuepoint1
			
			if(channel >= 7){
			
				
					debug('Channel: '+(channel).toString());
					call('deckCuePos1', channel-7, data2);
					
			}
			break;
		case 0x01://cuepoint2
			if(channel >= 7){
					call('deckCuePos2', channel-7, data2);
					
			}
			break;
		case 0x02://cuepoint3
			if(channel >= 7){
					call('deckCuePos3', channel-7, data2);
					
			}
			break;
		case 0x03://cuepoint4
			if(channel >= 7){
					call('deckCuePos4', channel-7, data2);
					
			}
			break;
		case 0x04://cuepoint5
			if(channel >= 7){
					call('deckCuePos5', channel-7, data2);
					
			}
			break;
		case 0x05://cuepoint6
			if(channel >= 7){
					call('deckCuePos6', channel-7, data2);
					
			}
			break;
		case 0x06://cuepoint7
			if(channel >= 7){
					call('deckCuePos7', channel-7, data2);
					
			}
			break;
		case 0x07: //cuepoint8
			if(channel >= 7){
					call('deckCuePos8', channel-7, data2);
					
			}
			break;
			
		case 0x08: //clear cuepoint1
			if(channel >= 7){
					call('deckCuePos1Clear', channel-7, data2);
					
			}
			break;
		case 0x09: //clear cuepoint2
			if(channel >= 7){
					call('deckCuePos2Clear', channel-7, data2);
					
			}
			break;
		case 0x0A: //clear cuepoint3
			if(channel >= 7){
					call('deckCuePos3Clear', channel-7, data2);
					
			}
			break;
		case 0x0B: //clear cuepoint4
			if(channel >= 7){
					call('deckCuePos4Clear', channel-7, data2);
					
			} else {
				call('deckPlayPause', channel, data2); 	
			}
			break;
		case 0x0C: //clear cuepoint5
			if(channel >= 7){
					call('deckCuePos5Clear', channel-7, data2);
					
			} else {
				call('deckCue', channel, data2); 
			}
			break;
		case 0x0D: //clear cuepoint6
			if(channel >= 7){
					call('deckCuePos6Clear', channel-7, data2);
					
			}
			break;
		case 0x0E: //clear cuepoint7
			if(channel >= 7){
					call('deckCuePos7Clear', channel-7, data2);
					
			}
			break;
		case 0x0F: //clear cuepoint8
			if(channel >= 7){
					call('deckCuePos8Clear', channel-7, data2);
					
			}
			break;
		
		
	
		
		case 0x10:
			if(channel >=7){
				//savedloop1
				
				 call('deckLoopPoint1', channel-7, data2);
			} else {
				if(data2)
					call('deckLoopInEnd', channel, data2)
			}
			
			break;
		case 0x11:
			if(channel >=7){
				//savedloop2
				call('deckLoopPoint2', channel-7, data2);
			} else {
				if(data2)
					call('deckLoopInEnd', channel, data2)
			}
			break;
		case 0x12:
			if(channel >=7){
				//savedloop3
				call('deckLoopPoint3', channel-7, data2);
			} else {
				call('deckLoopLess', channel, data2);
			}
			break;
		case 0x13:
			if(channel >=7){
				//savedloop4
				call('deckLoopPoint4', channel-7, data2);
			} else {
				call('deckLoopMore', channel, data2);
			}
			break;
		case 0x14:
			if(channel >=7){
				//savedloop5
				call('deckLoopPoint5', channel-7, data2);
			}
			break;
		
		case 0x15:
			call('deckReverse', channel, data2);
			break;
		case 0x20:
			if(channel > 6){
				call('deckLoop1_16', channel-7, data2);
			}	
			
			break;
		case 0x21:
			if(channel > 6)
				call('deckLoop1_8', channel-7, data2);
			break;
		case 0x22:
			if(channel > 6)
				call('deckLoop1_4', channel-7, data2);
			break;
		case 0x23:
			if(channel > 6)
				call('deckLoop1_2', channel-7, data2);
			break;
		case 0x24:
			if(channel > 6){
				call('deckLoop1', channel-7, data2);
			}
			else
			{
			//move loop left
			call('deckLoopPrev', channel, data2);
			}
			break;
		case 0x25:
			if(channel > 6)
				call('deckLoop2', channel-7, data2);
			break;
		case 0x26:
			if(channel > 6)
				call('deckLoop4', channel-7, data2);
			break;
		case 0x27:
			if(channel > 6)
				call('deckLoop8', channel-7, data2);
			break;
		
		case 0x2C:
			//move loop right
			call('deckLoopNext', channel, data2);
			break;
			
		case 0x1A:
			if(data2)
				call('deckKeyLock', channel, data2);
			break;
		case 0x30: //Sampler 1
			if(channel >= 7 && data2){
					call('samplerPlay', 1);
					
			}
			break;
		case 0x31: //Sampler 2
			if(channel >= 7 && data2){
					call('samplerPlay', 2);
					
			}
			break;
		case 0x32: //Sampler 3
			if(channel >= 7 && data2){
					call('samplerPlay', 3);
					
			}
			break;
		case 0x33: //Sampler 4
			if(channel >= 7 && data2){
					call('samplerPlay', 4);
					
			}
			break;
		case 0x34: //Sampler 5
			if(channel >= 7 && data2){
					call('samplerPlay', 5);
					
			}
			break;
		case 0x35: //Sampler 6
			if(channel >= 7 && data2){
					call('samplerPlay', 6);
					
			}
			break;
		case 0x36: //Sampler 7
			if(channel >= 7 && data2){
					call('samplerPlay', 7);
					
			}
			break;
		case 0x37: //Sampler 8
			if(channel >= 7 && data2){
					call('samplerPlay', 8);
					
			}
			break;
		
		case 0x41: 
			if(data2>0x3F) 
				call('lbToggleSelect', data2);
			break;
		
		case 0x46:
			if(channel == 6){
				if(data2){
					call('deckLBLoad', 0, data2);
				}
				sendMidi(uniqueId,0x90,6,0x46,data2);
			}
				
			break;
		case 0x47:
			if(channel == 6){
				if(data2){
					call('deckLBLoad', 1, data2);
				}
				sendMidi(uniqueId,0x90,6,0x47,data2);
			}
			break;
		case 0x48:
			if(channel == 6){
				if(data2){
					call('deckLBLoad', 2, data2);
				}
				sendMidi(uniqueId,0x90,6,0x48,data2);
			}
			break;
		case 0x49:
			if(channel == 6){
				if(data2){
					call('deckLBLoad', 3, data2);
				}
				sendMidi(uniqueId,0x90,6,0x49,data2);
			}
			break;
		
		case 0x4D:
			if(data2)
				call('deckLoopExit', channel, data2);
			break;
			
		
		case 0x54: //monitor
			call('deckMonitor', channel, data2);
			break;
		
		case 0x58: //sync
			call('deckSync', channel, data2);
			break;

		case 0x61: //loop move back
			call('deckLoopPrev', channel, data2);
			break;
		case 0x62: //loop move forward
			call('deckLoopNext', 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(name=='play')
		{
			debug('name==play');
			sendMidi(uniqueId,0x90,deck,0x0B,(param1 ? 0x7F : 0x00)); //play button
			
	
		}
	if(name=='cue') 		 
		{
			sendMidi(uniqueId,0x90,deck,0x0C,(param1 ? 0x7F : 0x00)); // cue			
		}
	
	if(name=='onbeat') 	 	 sendMidi(uniqueId,0x90,deck,0x58,(param1 ? 0x7F : 0x00)); //sync
	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=='reverse') 	 sendMidi(uniqueId,0x90,deck,0x15,(param1 ? 0x7F : 0x00)); //reverse (sensor LED)
	if(name=='cuepos1') {
		sendMidi(uniqueId,0x90,7+deck,0x00,(param1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x08,(param1 ? 0x7F : 0x00));	
	}//cue 1
	if(name=='cuepos2'){ 	 
		sendMidi(uniqueId,0x90,7+deck,0x01,(param1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x09,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos3'){ 
		sendMidi(uniqueId,0x90,7+deck,0x02,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0A,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos4'){
		sendMidi(uniqueId,0x90,7+deck,0x03,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0B,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos5'){ 	 
		sendMidi(uniqueId,0x90,7+deck,0x04,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0C,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos6'){ 
		sendMidi(uniqueId,0x90,7+deck,0x05,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0D,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos7'){ 
		sendMidi(uniqueId,0x90,7+deck,0x06,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0E,(param1 ? 0x7F : 0x00));	
		
	}
	if(name=='cuepos8') {
		sendMidi(uniqueId,0x90,7+deck,0x07,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,7+deck,0x0D,(param1 ? 0x7F : 0x00));	
		
	}
	
	if(name=='looppos1'){
		sendMidi(uniqueId,0x90,7+deck,0x10,(param1 != -1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x18,(param1 != -1 ? 0x7F : 0x00));	
					
	}
	if(name=='looppos2'){		
		sendMidi(uniqueId,0x90,7+deck,0x11,(param1 != -1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x19,(param1 != -1 ? 0x7F : 0x00));	
	}
	if(name=='looppos3'){	
		sendMidi(uniqueId,0x90,7+deck,0x12,(param1 != -1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x1A,(param1 != -1 ? 0x7F : 0x00));	
					
	}
	if(name=='looppos4'){		
		sendMidi(uniqueId,0x90,7+deck,0x13,(param1 != -1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x1B,(param1 != -1 ? 0x7F : 0x00));	
	}
	if(name=='looppos5'){
		sendMidi(uniqueId,0x90,7+deck,0x14,(param1 != -1 ? 0x7F : 0x00));	
		sendMidi(uniqueId,0x90,7+deck,0x1C,(param1 != -1 ? 0x7F : 0x00));	
	}
	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,0x4D,(param1 ? 0x7F : 0x00));//loop out led		
					sendMidi(uniqueId,0x90,deck,0x12,(param1 ? 0x7F : 0x00));//loop out led	
					sendMidi(uniqueId,0x90,deck,0x13,(param1 ? 0x7F : 0x00));//loop out led						
					sendMidi(uniqueId,0x90,deck,0x24,(param1 ? 0x7F : 0x00));//loop out led	
					sendMidi(uniqueId,0x90,deck,0x2C,(param1 ? 0x7F : 0x00));//loop out led						
					sendMidi(uniqueId,0x90,deck,0x61,(param1 ? 0x7F : 0x00));//loop out led						
					sendMidi(uniqueId,0x90,deck,0x62,(param1 ? 0x7F : 0x00));//loop out led						
				}
	
	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(name=='sampler1'){ 					
					sendMidi(uniqueId,0x90,7,0x30,(param1 ? 0x7F : 0x00));					
					sendMidi(uniqueId,0x90,8,0x30,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x30,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x30,(param1 ? 0x7F : 0x00));					
				}
				if(name=='sampler2'){ 					
					sendMidi(uniqueId,0x90,7,0x31,(param1 ? 0x7F : 0x00));					
					sendMidi(uniqueId,0x90,8,0x31,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x31,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x31,(param1 ? 0x7F : 0x00));	
				}
				if(name=='sampler3'){ 										
					sendMidi(uniqueId,0x90,7,0x32,(param1 ? 0x7F : 0x00));					
					sendMidi(uniqueId,0x90,8,0x32,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x32,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x32,(param1 ? 0x7F : 0x00));	
					
				}
				if(name=='sampler4'){ 					
					sendMidi(uniqueId,0x90,7,0x33,(param1 ? 0x7F : 0x00));					
					sendMidi(uniqueId,0x90,8,0x33,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x33,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x33,(param1 ? 0x7F : 0x00));
				}
				if(name=='sampler5'){
					sendMidi(uniqueId,0x90,7,0x34,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,8,0x34,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x34,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x34,(param1 ? 0x7F : 0x00));
				}
				if(name=='sampler6'){
					sendMidi(uniqueId,0x90,7,0x35,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,8,0x35,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x35,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x35,(param1 ? 0x7F : 0x00));
				}
				if(name=='sampler7'){ 
					sendMidi(uniqueId,0x90,7,0x36,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,8,0x36,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x36,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x36,(param1 ? 0x7F : 0x00));
					
				}
				if(name=='sampler8'){ 
					sendMidi(uniqueId,0x90,7,0x37,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,8,0x37,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,9,0x37,(param1 ? 0x7F : 0x00));
					sendMidi(uniqueId,0x90,10,0x37,(param1 ? 0x7F : 0x00));
					
				}
			}
	}
	
	
}
//----------------------------------------------------------------------------- 
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 ???
		//}
	}
	
}
//----------------------------------------------------------------------------- 
