//-----------------------------------------------------------------------------
//-------- 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 "CMD Studio";
}
//----------------------------------------------------------------------------- 
// 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 0x1397;
	//return false;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDevicePID(osId)
{	
	return 0x00C6;	
	//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 "00 20 32 01 00 01 F7";
	
	//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 "Studio 4a";
	return false;
	
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	//return "Studio 4a";
	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]];

var delIsPressed = [0,0,0,0];
var fxledoffset = false;

//----------------------------------------------------------------------------- 
// 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 s=0x00;s<=0xEF;s++){
	//	for(var x=0;x<=15;x++){
	//		for(var i=0; i<=127; i++)
	//		{
	//			sendMidi(uniqueId,s,x,i,0x3F);
				//call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	//			debug(s.toString()+': '+x.toString()+' / '+i.toString() );
	//		}
	//	}
	//call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	//}
	
	
		//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)
{
	
	callSendAllNotifications(uniqueId, false);
	
	sendMidi(uniqueId,0xB0,0x01,0x7E,48);
	sendMidi(uniqueId,0xB0,0x01,0x7F,48);
	
	
}
//----------------------------------------------------------------------------- 
// 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 0xE0:
			//tempo slider
			call('setDeckPitch', channel, data2); break; //pitch slider
			break;
		case 0xB0:
			switch(data1)
			{
			// global
			
			//-----------------------------------------------
			case 0x01: //browse knob
				var val1 = (data2>0x40 ? 1 : -1);					
				call('lbMoveCursor', val1);
				break;
			case 0x10: //fx1 wet/dry 1/3
				call('deckFxFlangerDW', channel, data2); 
				break;
			case 0x11: //fx2 wet/dry 1/3
				call('deckFxEchoDW', channel, data2); 
				break;
			case 0x12: //fx3 wet/dry 1/3
				call('deckFxBeatwawDW', channel, data2);
				break;
			case 0x13: //fx4 wet/dry 1/3
				call('deckFxReverbDW', channel, data2);
				break;
			case 0x1A: //jog-wheel 1/3
				if(jogWheelsInScratchMode[channel]){
					var val1 = data2-0x40;
					//call('scratchDeckJW', channel, val1, 2048);
					call('scratchDeckJW', channel, val1, 200);
				
				} else {
					var val1 = data2-0x40;
					call('moveDeckJogWheel', channel, val1, 2048);
				}
				
				break;
			case 0x2F: //main
				break;				
			case 0x30: //fx1 wet/dry 2/4
				call('deckFxFlangerDW', channel, data2); 
				break;
			case 0x31: //fx2 wet/dry 2/4
				call('deckFxEchoDW', channel, data2); 
				break;
			case 0x32: //fx3 wet/dry 2/4
				call('deckFxBeatwawDW', channel, data2);
				break;
			case 0x33: //fx4 wet/dry 2/4
				call('deckFxReverbDW', channel, data2);
				break;
			case 0x3A: //jog-wheel deck 2/4
				if(jogWheelsInScratchMode[channel]){
					var val1 = data2-0x40;
					//call('scratchDeckJW', channel, val1, 2048);
					call('scratchDeckJW', channel, val1, 200);
				
				} else {
					var val1 = data2-0x40;
					call('moveDeckJogWheel', channel, val1, 2048);
				}
				break;
			case 0x60: //eq high 1/3
				call('setDeckEqHigh', channel, data2);
				break;
			case 0x61: //eq mid 1/3
				call('setDeckEqMid', channel, data2);
				break;
			case 0x62: //eq low 1/3
				call('setDeckEqLow', channel, data2);
				break;
			case 0x63: //eq high 2/4
				call('setDeckEqHigh', channel, data2);
				break;
			case 0x64: //eq mid 2/4
				call('setDeckEqMid', channel, data2);
				break;
			case 0x65: //eq low 2/4
				call('setDeckEqLow', channel, data2);
				break;
			case 0x70: //master volume 1/3
				call('setDeckVolume', channel, data2);
				break;
			case 0x71: //master volume 2/4
				call('setDeckVolume', channel, data2);
				break;
			case 0x72: //cross-fader
				call('setCrossfader', data2);
				break;
			case 0x7A: // Monitor Mix
				call('setCuePgmMix', data2);
				break;
			case 0x7B: // Monitor Volume
				call('setMonitorGain', data2);
				break;
			
			default: messageNotProcessed = true;
			}
			break;
	//buttons - things pressed.
		case 0x80:
		case 0x90:
			switch(data1){
				case 0x01: //Enter deck 1/3
					if(data2>0x3F){
						call('lbToggleSelect', data2);						
					}
					
					break;
				case 0x02: //left arrow deck 1/3
					if(data2>0x3F){
						call('lbBrowserSelect', data2);						
					}
					
					break;
				case 0x03: //right arrow deck 1/3
					
					if(data2>0x3F){
						call('lbListSelect', data2);
					}
					
					break;
				case 0x10: //fx1
					break;
				case 0x11: //fx2
					break;
				case 0x12: //fx3
					break;
				case 0x13: //fx4
					break;
				case 0x16: //scratch deck 1/3
					if(data2){
						jogWheelsInScratchMode[channel] = jogWheelsInScratchMode[channel] ? 0x00:0x7F;						
					}					
					break;
				case 0x17:
					call('deckLoopLess', channel, data2)
					break;
				case 0x18:
					call('deckLoopMore', channel, data2)
					break;
				case 0x1A: //jog-press 1/3
					if(jogWheelsInScratchMode[channel]){						
						call('holdDeckJogWheel', channel, data2);
					}
					break;
				case 0x1B: //Lock deck 1/3
					call('deckKeyLock', channel, data2);
					break;	
				case 0x19: //On/Off deck 1/3
					call('deckLoop4', channel, data2);
					break;
				case 0x20: //bend down
					call('deckBendDown', channel, data2)
					break;
				case 0x21: //bend up
					call('deckBendUp', channel-1, data2)
					break;
				case 0x22: //cuepoint 1
					if(delIsPressed[channel]){
					call('deckCuePos1Clear', channel, data2);
					} else {
					call('deckCuePos1', channel, data2);
					}
					
					break;
				case 0x23: //cuepoint 2
					if(delIsPressed[channel]){
					call('deckCuePos2Clear', channel, data2);
					} else {
					call('deckCuePos2', channel, data2);
					}
					
					break;
				case 0x24: //cuepoint 3
					if(delIsPressed[channel]){
					call('deckCuePos3Clear', channel, data2);
					} else {
					call('deckCuePos3', channel, data2);
					}
					
					break;
				case 0x25: //cuepoint 4
					if(delIsPressed[channel]){
					call('deckCuePos4Clear', channel, data2);
					} else {
					call('deckCuePos4', channel, data2);
					}
					
					break;
				case 0x26: //cuepoint 5
					if(delIsPressed[channel]){
					call('deckCuePos5Clear', channel, data2);
					} else {
					call('deckCuePos5', channel, data2);
					}
					
					break;
				case 0x27: //cuepoint 6
					if(delIsPressed[channel]){
					call('deckCuePos6Clear', channel, data2);
					} else {
					call('deckCuePos6', channel, data2);
					}
					
					break;
				case 0x28: //cuepoint 7
					if(delIsPressed[channel]){
					call('deckCuePos7Clear', channel, data2);
					} else {
					call('deckCuePos7', channel, data2);
					}
					
					break;
				case 0x29: //cuepoint 8
					if(delIsPressed[channel]){
					call('deckCuePos8Clear', channel, data2);
					} else {
					call('deckCuePos8', channel, data2);
					}
					
					break;
				case 0X2A: //del deck 1/3
					delIsPressed[channel] = data2;
					break;
				case 0x2B: //cue
					call('deckCue', channel, data2);
					break;
				case 0x2C: //play/pause
					call('deckPlayPause', channel, data2);
					//sendMidi(uniqueId,status,channel,data1,0x02);
					//debug('['+status.toString()+']['+channel.toString()+']['+data1.toString()+']['+data2.toString()+']');
					
					//debug('Play/Paused for channel:' + channel.toString());
					break;
				case 0x2D: //sync
					call('deckSync', channel, data2);
					break;
				case 0x30: //fx1 deck 2/4
					break;
				case 0x31: //fx2 deck 2/4
					break;
				case 0x32: //fx3 deck 2/4
					break;
				case 0x33: //fx4 deck 2/4
					break;
				case 0x36: //scratch deck 2/4
					if(data2){
						jogWheelsInScratchMode[channel] = jogWheelsInScratchMode[channel] ? 0x00:0x7F;
					}
					break;
				
				case 0x37:
					call('deckLoopMore', channel, data2)
					break;
				case 0x38:
					call('deckLoopLess', channel, data2)
					break;
				
				case 0x39: // On/Off deck 2/4
					call('deckLoop4', channel, data2);
					break;
				case 0x3A: // Jog-Press 2/4
					if(jogWheelsInScratchMode[channel]){						
						call('holdDeckJogWheel', channel, data2);
					}
					break;
				case 0x3B: //Lock deck 2/4
					call('deckKeyLock', channel, data2);
					break;
				case 0x40: //bend-down deck 2/4
					call('deckBendDown', channel, data2)
					break;
				case 0x41: //bendup deck 2/4
					call('deckBendUp', channel, data2)
					break;
				case 0x42: //cuepoint 1 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos1Clear', channel, data2);
					} else {
					call('deckCuePos1', channel, data2);
					}
					
					break;
				case 0x43: //cuepoint 2 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos2Clear', channel, data2);
					} else {
					call('deckCuePos2', channel, data2);
					}
					
					break;
				case 0x44: //cuepoint 3 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos3Clear', channel, data2);
					} else {
					call('deckCuePos3', channel, data2);
					}
					
					break;
				case 0x45: //cuepoint 4 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos4Clear', channel, data2);
					} else {
					call('deckCuePos4', channel, data2);
					}
					
					break;
				case 0x46: //cuepoint 5 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos5Clear', channel, data2);
					} else {
					call('deckCuePos5', channel, data2);
					}
					
					break;
				case 0x47: //cuepoint 6 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos6Clear', channel, data2);
					} else {
					call('deckCuePos6', channel, data2);
					}
					
					break;
				case 0x48: //cuepoint 7 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos7Clear', channel, data2);
					} else {
					call('deckCuePos7', channel, data2);
					}
					
					break;
				case 0x49: //cuepoint 8 deck 2/4
					if(delIsPressed[channel]){
					call('deckCuePos8Clear', channel, data2);
					} else {
					call('deckCuePos8', channel, data2);
					}
					
					break;
				case 0x4A: //del deck 2/4
					delIsPressed[channel] = data2;
					break;
				case 0x4B: //Cue deck 2/4
					call('deckCue', channel, data2);
					break;
				case 0x4C: //Play/Pause deck 2/4
					call('deckPlayPause', channel, data2);
					break;
				case 0x4D: //Sync deck 2/4
					call('deckSync', channel, data2);
					break;
				case 0x50: //load deck 1/3
					if(data2) call('deckLBLoad', channel, data2); 
					break;
				case 0x51: //load deck 2/4
					if(data2) call('deckLBLoad', channel, data2); 
					break;
				case 0x52: //fx assign 1 deck 1/3
					break;
				case 0x53: //fx assign 2 deck 1/3			
					break;
				case 0x54: //fx assign 1 deck 2/4
					break;
				case 0x55: //fx assign 2 deck 2/4
					break;
				case 0x60: //kill high 1/3
					call('deckEqHighKill', channel, data2);
					break;
				case 0x61: //kill mid 1/3
					call('deckEqMidKill', channel, data2);
					break;
				case 0x62: //kill low 1/3
					call('deckEqLowKill', channel, data2);
					debug('killLowEQ');
					break;
				case 0x63: //kill high 2/4
					call('deckEqHighKill', channel, data2);
					break;
				case 0x64: //kill mid 2/4
					call('deckEqMidKill', channel, data2);
					break;
				case 0x65: //kill low 2/4
					call('deckEqLowKill', channel, data2);
					break;
				case 0x6A: //phones 1/3
					call('deckMonitor', channel, data2);
					break;
				case 0x6B: //phones 2/4
					call('deckMonitor', channel, data2);
					break;
					
				
				
					
				
				
				
			}
			
			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(name=='cue') 		 
	{
	    sendMidi(uniqueId,0x90,deck,0x2B,(param1 ?  0x01  : 0x00))
		sendMidi(uniqueId,0x90,deck,0x4B,(param1 ?  0x01  : 0x00))
			
	}
	
	if(name=='play')
	{
		sendMidi(uniqueId,0x90,deck,0x2C,(param1 ?  0x01  : 0x00)); //play button
		sendMidi(uniqueId,0x90,deck,0x4C,(param1 ?  0x01  : 0x00)); //play button
		
	}
	
	if(name=='monitor'){
		sendMidi(uniqueId,0x90,deck,0x6A,(param1 ? 0x01 : 0x00));
		sendMidi(uniqueId,0x90,deck,0x6B,(param1 ? 0x01 : 0x00));
	}	//pfl
	
	
	
	if(name=='keyLock'){
		sendMidi(uniqueId,0x90,deck,0x1B,(param1 ? 0x01 : 0x00)); 
		sendMidi(uniqueId,0x90,deck,0x3B,(param1 ? 0x01 : 0x00)); 
	}//key lock
	
	
	if(name=='onbeat') {
	sendMidi(uniqueId,0x90,deck,0x2D,(param1 ? 0x01 : 0x00)); //sync
	sendMidi(uniqueId,0x90,deck,0x4D,(param1 ? 0x01 : 0x00)); //sync
	}
	
	if(name=='cuepos1') {	 
		sendMidi(uniqueId,0x90,deck,0x22,(param1 ? 0x01 : 0x00)); 		
		sendMidi(uniqueId,0x90,deck,0x42,(param1 ? 0x01 : 0x00)); //+ shift 0x28 = red
	}//cue 1
	if(name=='cuepos2'){ 	 
		sendMidi(uniqueId,0x90,deck,0x23,(param1 ? 0x01 : 0x00)); //cue 2
		sendMidi(uniqueId,0x90,deck,0x43,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos3'){ 	
		sendMidi(uniqueId,0x90,deck,0x24,(param1 ? 0x01 : 0x00)); //cue 3
		sendMidi(uniqueId,0x90,deck,0x44,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos4'){ 	 
		sendMidi(uniqueId,0x90,deck,0x25,(param1 ? 0x01 : 0x00)); //cue 4
		sendMidi(uniqueId,0x90,deck,0x45,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos5'){ 	 
		sendMidi(uniqueId,0x90,deck,0x26,(param1 ? 0x01 : 0x00)); //cue 5
		sendMidi(uniqueId,0x90,deck,0x46,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos6'){ 	 
		sendMidi(uniqueId,0x90,deck,0x27,(param1 ? 0x01 : 0x00)); //cue 6
		sendMidi(uniqueId,0x90,deck,0x47,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos7'){ 	 
		sendMidi(uniqueId,0x90,deck,0x28,(param1 ? 0x01 : 0x00)); //cue 7
		sendMidi(uniqueId,0x90,deck,0x48,(param1 ? 0x01 : 0x00));
	}
	if(name=='cuepos8') {	 		
		sendMidi(uniqueId,0x90,deck,0x29,(param1 ? 0x01 : 0x00)); //cue 8
		sendMidi(uniqueId,0x90,deck,0x49,(param1 ? 0x01 : 0x00));
	}
	
	if(name=='looping') 	 
	{
		sendMidi(uniqueId,0x90,deck,0x19,(param1 ? 0x02 : 0x00));// loop in led
		sendMidi(uniqueId,0x90,deck,0x39,(param1 ? 0x02 : 0x00));//loop out led
		
		sendMidi(uniqueId,0x90,deck,0x17,(param1 ? 0x01 : 0x00));// loop in led
		sendMidi(uniqueId,0x90,deck,0x37,(param1 ? 0x01 : 0x00));//loop out led
		
		sendMidi(uniqueId,0x90,deck,0x18,(param1 ? 0x01 : 0x00));// loop in led
		sendMidi(uniqueId,0x90,deck,0x38,(param1 ? 0x01 : 0x00));//loop out led
	}
	
	if(deck == 0x01 || deck == 0x03){
		fxledoffset = true;//offset 20
	} else {
		fxledoffset = false;//offset 0
	}
	
	
		
	if(name=='fxFlanger') 	 sendMidi(uniqueId,0x90,deck,(fxledoffset ? 0x30 : 0x10),(param1 ? 0x01 : 0x00)); //deck FX flanger
	if(name=='fxEcho') 	     sendMidi(uniqueId,0x90,deck,(fxledoffset ? 0x31 : 0x11),(param1 ? 0x01 : 0x00)); //deck FX echo
	if(name=='fxBeatwaw') 	 sendMidi(uniqueId,0x90,deck,(fxledoffset ? 0x32 : 0x12),(param1 ? 0x01 : 0x00)); //deck FX Beatwaw 
	if(name=='fxReverb') 	 sendMidi(uniqueId,0x90,deck,(fxledoffset ? 0x33 : 0x13),(param1 ? 0x01 : 0x00)); //deck FX reverb
		

		
		
		
		
		
	
	
}
//----------------------------------------------------------------------------- 
function getMIDIValueForVU(vu_val)
{
	// translating VU-meter signal from decibels (dB) to 0..127 MIDI range
	var val = 0;
	//var step = 3.6;

	if(vu_val>-58) val =  48;
	if(vu_val>-54) val =  49;
	if(vu_val>-40) val =  50;
	if(vu_val>-36) val =  51;
	if(vu_val>-32) val =  52;
	if(vu_val>-28) val =  53;
	if(vu_val> -24) val =  54;
	if(vu_val> -20) val =  55;
	if(vu_val> -16) val =  56;
	if(vu_val> -14) val =  57;
	if(vu_val> -10) val =  58;
	if(vu_val> -8) val =  59;
	if(vu_val> -4) val =  60;
	if(vu_val> -0) val =  61;
	if(vu_val> 2) val =  62;
	if(vu_val> 4) val =  63;
	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)
{
	var vuDeckL = getValue('vumeterMasterL');// float dB left deck
	var vuDeckR = getValue('vumeterMasterR');// float dB right deck
	
	sendMidi(uniqueId,0xB0,0x01,0x7E,getMIDIValueForVU(vuDeckL));
	sendMidi(uniqueId,0xB0,0x01,0x7F,getMIDIValueForVU(vuDeckR));
	
	
	
}
//----------------------------------------------------------------------------- 