//-----------------------------------------------------------------------------
//------------ Copyright (c)2003-2016 Xylio. All Rights Reserved. -------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller 'Hercules Universal DJ'
//-----------------------------------------------------------------------------
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 "Hercules Universal DJ";
}
//-----------------------------------------------------------------------------
// 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 getSupportedMidiDeviceVID(osId)
{
	return 0x06F8;
}
//-----------------------------------------------------------------------------
function getSupportedMidiDevicePID(osId)
{
	return 0xB11A;
}
//-----------------------------------------------------------------------------
// 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 "00014E020012";
	// F0 7E 00 06 02 00 01 4E 02 00 02 00 01 00 00 00 F7 -- Hercules DJ Console MK2 complete sysex
	// F0 7E 00 06 02 00 01 4E 01 00 03 00 01 00 00 00 F7 -- Hercules DJ Control MP3 complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 04 00 01 00 00 00 F7 -- Hercules DJ Console RMX complete sysex
	// F0 7E 00 06 02 00 01 4E 01 00 05 00 01 00 00 00 F7 -- Hercules DJ Control Steel complete sysex
	// F0 7E 00 06 02 00 01 4E 01 00 07 00 01 00 00 00 F7 -- Hercules DJ Control MP3e2 complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 08 00 01 00 00 00 F7 -- Hercules DJ Console MK4 complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 0B 00 01 00 00 00 F7 -- Hercules DJ Control Air complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 0C 00 01 00 00 00 F7 -- Hercules DJ Control Instinct complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 10 00 01 00 00 00 F7 -- Hercules DJ Control Air+ complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 0A 00 01 00 00 00 F7 -- Hercules DJ4Set complete sysex
	// F0 7E 00 06 02 00 01 4E 02 00 09 00 01 00 00 00 F7 -- Hercules DJ Console 4-Mx
	// F0 7E 7F 06 02 00 01 4E 02 00 16 00 01 00 00 00 F7 -- Hercules DJ Control Compact
	// F0 7E 7F 06 02 00 01 4E 02 00 12 00 01 00 00 00 F7 -- Hercules Universal DJ
}
//-----------------------------------------------------------------------------
// 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 "DJHERCULESMIX Universal DJ";
}
//-----------------------------------------------------------------------------
function getSupportedMidiDeviceNameForOutput(osId)
{
	return "DJHERCULESMIX Universal DJ";
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// some variables necessary only for this particular script
var jogWheelsInScratchMode=0;
var cutoffValue=[63,63,63,63];
var shiftMode=[0,0,0,0];
//-----------------------------------------------------------------------------
// value is 0x7F for left (-1); 0x01 for right(+1);
function trimEncoderValue(value, increment, initialValue)
{
	var outValue = 0;
	var outIncrement = 0;
	if(value>0x40) // left (decrease)
		outIncrement = increment * (value - 0x80);
	else // left (increase)
		outIncrement = increment * (value);
	outValue = initialValue + outIncrement;
	if(outValue<0) outValue = 0;
	if(outValue>0x7F) outValue = 0x7F;
	return outValue;
}
//-----------------------------------------------------------------------------
// 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 Hercules Universal DJ ['+uniqueId+']');// this outputs a string to DebugView app on Win
	// setting audio (the actual routing is done automatically for this controller so
	// we don't need to manually set "RoutingOutHeadphones", "RoutingOutDeckA", etc
	if(setAudioDevice("DJHERCULESMIX Universal DJ|||Hercules Universal DJ|||Universal DJ|||Speakers (DJHERCULESMIX Universal DJ)"))
	{
		//debug('AudioDevice was set OK');
		setSetting('AudioDevice2', "NO AUDIO");
		/*
		<pref name="AudioDevice" value="Aggregate Device" type="3" />
		<pref name="AudioDevice2" value="NO AUDIO" type="3" />
		<pref name="DisableCrossfaderAndVolumes" value="0" type="1" />
		<pref name="RoutingInDeckA" value="1" type="1" />
		<pref name="RoutingInDeckB" value="1" type="1" />
		<pref name="RoutingInDeckC" value="0" type="1" />
		<pref name="RoutingInDeckD" value="0" type="1" />
		<pref name="RoutingInMicrophone" value="2" type="1" />
		<pref name="RoutingOutDeckA" value="1" type="1" />
		<pref name="RoutingOutDeckB" value="1" type="1" />
		<pref name="RoutingOutDeckC" value="1" type="1" />
		<pref name="RoutingOutDeckD" value="1" type="1" />
		<pref name="RoutingOutHeadphones" value="0" type="1" />
		<pref name="RoutingOutSamplerMic" value="1" type="1" />
		*/
	}else
	{
		//debug('AudioDevice not set (we are not allow to set it or the device either does not exist or it has a different name)');
	}
	//sendMidi(uniqueId, status, channel, data1, data2);
	sendMidi(uniqueId,0x90,0,0x59,(jogWheelsInScratchMode ? 0x7F : 0x00));// scratch mode
	//------------------------------------
	callSendAllNotifications(uniqueId, true);// send all notifications to the controller (so that we don't have to manually init all leds/lcd screens)
	// update all analog controls (eg. fader/knob positions)
	sendMidi(uniqueId,0xB0,0,0x7F,0x7F);
}
//-----------------------------------------------------------------------------
// 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 ['+uniqueId+']');
	// set leds off
	sendMidi(uniqueId,0x90,0,0x59,0x00);// scratch mode
	for(var i=0; i<2; i++)
	{
		var dbValue = -90.0;// float dB
		setVUmeter(uniqueId, i, dbValue);
	}
	//------------------------------------
	callSendAllNotifications(uniqueId, false);// send all notifications to the controller (so that we don't have to manually de-init all leds/lcd screens)
}
//-----------------------------------------------------------------------------
// 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)
{
	var messageNotProcessed=false;
	switch(status)
	{
	//-----------------------------------------------
	// controllers: sliders, knobs, jog-wheels, encoders ('moving' things)
	case 0xB0:
		switch(data1)
		{
		// global
		case 0x41: call('setCrossfader', data2); break;
		case 0x36: // move track
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			call('lbMoveCursor', val1);
			break;//library curser up down

		// per deck
		// deck A
		case 0x01: call('setDeckPitch', 0, data2); break;
		case 0x3D: call('setDeckEqLow', 0, data2); break;
		case 0x3C: call('setDeckEqMid', 0, data2); break;
		case 0x3B: call('setDeckEqHigh', 0, data2); break;
		case 0x39: call('setDeckVolume', 0, data2); break;
		case 0x52:
		{
			cutoffValue[0] = trimEncoderValue(data2, 2, cutoffValue[0]);
			call('setDeckCutoff', 0, cutoffValue[0]);
			break;
		}
		case 0x30:
		case 0x32: // params: (deck, increment, total positions per complete revolution)
		{
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			if(shiftMode[0]) // if Shift is pressed
			{
				call('searchDeckJW', 0, val1, 512);
			}else
			{
				if(jogWheelsInScratchMode)
					call('scratchDeckJW', 0, val1, 512);
				else
					call('moveDeckJogWheel', 0, val1, 512);
			}
			break;
		}

		// deck B
		case 0x02: call('setDeckPitch', 1, data2); break;
		case 0x40: call('setDeckEqLow', 1, data2); break;
		case 0x3F: call('setDeckEqMid', 1, data2); break;
		case 0x3E: call('setDeckEqHigh', 1, data2); break;
		case 0x3A: call('setDeckVolume', 1, data2); break;
		case 0x5A:
		{
			cutoffValue[1] = trimEncoderValue(data2, 2, cutoffValue[1]);
			call('setDeckCutoff', 1, cutoffValue[1]);
			break;
		}
		case 0x31:
		case 0x33: // params: (deck, increment, total positions per complete revolution)
		{
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			if(shiftMode[1]) // if Shift is pressed
			{
				call('searchDeckJW', 1, val1, 512);
			}else
			{
				if(jogWheelsInScratchMode)
					call('scratchDeckJW', 1, val1, 512);
				else
					call('moveDeckJogWheel', 1, val1, 512);
			}
			break;
		}

		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	case 0x80:
	case 0x90:
		switch(data1)
		{
		// global
		case 0x57: call('mixNext', data2); break;
		case 0x58: call('record', data2); break;
		case 0x59:
			if(data2>0x3F)
			{
				jogWheelsInScratchMode = (jogWheelsInScratchMode+1) % 2;
				sendMidi(uniqueId,0x90,0,0x59,(jogWheelsInScratchMode ? 0x7F : 0x00));
				break;
			}
		// headphone volume -/+
		case 0x5A: // inc headphones volume
		case 0x5B: // dec headphones volume
			if(data2>0x3F)
			{
				var monValue = getValue('monitorGain');
				if(data1==0x5B) monValue -= 1;else monValue += 1;
				if(monValue<-40) monValue = -40;
				if(monValue>0) monValue = 0;
				// we need to convert from -40..0dB to 0..127 (MIDI)
				call('setMonitorGain', Math.round((monValue+40)*3.175));
				//call('setMonitorVolume', Math.round((monValue+40)*3.175));
			}
			break;
		case 0x5C: if(data2>0x3F) call('lbToggleSelect', data2); break;

		// decks

		//Pads - Cue
		case 0x11: call('deckCuePos1', channel, data2); break;
		case 0x12: call('deckCuePos2', channel, data2); break;
		case 0x13: call('deckCuePos3', channel, data2); break;
		case 0x14: call('deckCuePos4', channel, data2); break;
		case 0x15: call('deckCuePos5', channel, data2); break;
		case 0x16: call('deckCuePos6', channel, data2); break;
		case 0x17: call('deckCuePos7', channel, data2); break;
		case 0x18: call('deckCuePos8', channel, data2); break;
		// with Shift (not mapped: 0x19..0x20)

		//Pads - FX:
		case 0x01: call('deckFxFlanger', channel, data2); break;
		case 0x02: call('deckFxEcho', channel, data2); break;
		case 0x03: call('deckFxBeatwaw', channel, data2); break;
		case 0x04: call('deckFxReverb', channel, data2); break;
		case 0x05: call('deckFxPan', channel, data2); break;
		case 0x06: call('deckFxDelay', channel, data2); break;
		case 0x07: call('deckBrake', channel, data2); break;
		case 0x08: call('deckReverse', channel, data2); break;
		// with Shift (not mapped: 0x09..0x10)

		//Pads - Sample
		case 0x21: call('sampler1', data2); break;
		case 0x22: call('sampler2', data2); break;
		case 0x23: call('sampler3', data2); break;
		case 0x24: call('sampler4', data2); break;
		case 0x25: call('sampler5', data2); break;
		case 0x26: call('sampler6', data2); break;
		case 0x27: call('sampler7', data2); break;
		case 0x28: call('sampler8', data2); break;
		// with Shift (not mapped: 0x29..0x30)

		//Pads - Loop:
		case 0x31: call('deckLoop1_16', channel, data2); break;
		case 0x32: call('deckLoop1_8', channel, data2); break;
		case 0x33: call('deckLoop1_4', channel, data2); break;
		case 0x34: call('deckLoop1_2', channel, data2); break;
		case 0x35: call('deckLoop1', channel, data2); break;
		case 0x36: call('deckLoop2', channel, data2); break;
		case 0x37: call('deckLoop4', channel, data2); break;
		case 0x38: call('deckLoop8', channel, data2); break;
		// with Shift
		case 0x39: call('deckLoopInEnd', channel, data2); break;
		case 0x3A: call('deckLoopExitOrReloop', channel, data2); break;
		case 0x3B: call('deckLoopLess', channel, data2); break;
		case 0x3C: call('deckLoopMore', channel, data2); break;
		case 0x3D: call('deckLoopPrev', channel, data2); break;
		case 0x3E: call('deckLoopNext', channel, data2); break;
		case 0x3F: call('deckLoopMode', channel, data2); break;
		case 0x40: call('deckLoopMode', channel, data2); break;

		// shift mode on/off (while it's kept pressed)
		case 0x44: shiftMode[channel] = data2; break;

		case 0x41: call('deckPlayPause', channel, data2); break;
		case 0x42: call('deckCue', channel, data2); break;
		case 0x43: call('deckSync', channel, data2); break;
		// with Shift
		case 0x49: call('deckReverse', channel, data2); break;
		case 0x4A: call('deckCuePlay', channel, data2); break;
		case 0x4B: call('deckMatch', channel, data2); break;

		case 0x51: if(data2>0x3F) call('deckLBLoad', channel, data2); break;
		case 0x52: call('holdDeckJogWheel', channel, data2); break;
		case 0x53: call('deckMonitor', 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);
	if(deck>=2) return;
	var nameLen = name.length;

	if(name=='record') 		sendMidi(uniqueId,0x90,deck,0x58,(param1 ? 0x7F : 0x00));
	if(name=='monitor') 	sendMidi(uniqueId,0x90,deck,0x53,(param1 ? 0x7F : 0x00));

	if(name=='play') 		sendMidi(uniqueId,0x90,deck,0x41,(param1 ? 0x7F : 0x00));
	if(name=='cue') 		sendMidi(uniqueId,0x90,deck,0x42,(param1 ? 0x7F : 0x00));
	if(name=='onbeat') 		sendMidi(uniqueId,0x90,deck,0x43,(param1 ? 0x7F : 0x00));
	// with Shift
	if(name=='reverse') 	sendMidi(uniqueId,0x90,deck,0x49,(param1 ? 0x7F : 0x00));

	//Pads - Cue
	if(name=='cuepos1') 	sendMidi(uniqueId,0x90,deck,0x11,(param1 ? 0x7F : 0x00));
	if(name=='cuepos2') 	sendMidi(uniqueId,0x90,deck,0x12,(param1 ? 0x7F : 0x00));
	if(name=='cuepos3') 	sendMidi(uniqueId,0x90,deck,0x13,(param1 ? 0x7F : 0x00));
	if(name=='cuepos4') 	sendMidi(uniqueId,0x90,deck,0x14,(param1 ? 0x7F : 0x00));
	if(name=='cuepos5') 	sendMidi(uniqueId,0x90,deck,0x15,(param1 ? 0x7F : 0x00));
	if(name=='cuepos6') 	sendMidi(uniqueId,0x90,deck,0x16,(param1 ? 0x7F : 0x00));
	if(name=='cuepos7') 	sendMidi(uniqueId,0x90,deck,0x17,(param1 ? 0x7F : 0x00));
	if(name=='cuepos8') 	sendMidi(uniqueId,0x90,deck,0x18,(param1 ? 0x7F : 0x00));
	// with Shift (not mapped: 0x19..0x20)

	//Pads - FX:
	if(name=='fxFlanger') 	sendMidi(uniqueId,0x90,deck,0x01,(param1 ? 0x7F : 0x00));
	if(name=='fxEcho') 		sendMidi(uniqueId,0x90,deck,0x02,(param1 ? 0x7F : 0x00));
	if(name=='fxBeatwaw') 	sendMidi(uniqueId,0x90,deck,0x03,(param1 ? 0x7F : 0x00));
	if(name=='fxReverb') 	sendMidi(uniqueId,0x90,deck,0x04,(param1 ? 0x7F : 0x00));
	if(name=='fxPan') 		sendMidi(uniqueId,0x90,deck,0x05,(param1 ? 0x7F : 0x00));
	if(name=='fxDelay') 	sendMidi(uniqueId,0x90,deck,0x06,(param1 ? 0x7F : 0x00));
	if(name=='brake') 		sendMidi(uniqueId,0x90,deck,0x07,(param1 ? 0x7F : 0x00));
	if(name=='reverse') 	sendMidi(uniqueId,0x90,deck,0x08,(param1 ? 0x7F : 0x00));
	// with Shift (not mapped: 0x09..0x10)

	//Pads - Sample
	if(nameLen==13)
	{
		var name1 = name.substr(0, nameLen-1);
		if(name1=='samplerBlink')
		{
			// we need to control the leds from both decks at the same time
			if(name=='samplerBlink1')
			{
				sendMidi(uniqueId,0x90,0,0x21,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x21,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink2')
			{
				sendMidi(uniqueId,0x90,0,0x22,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x22,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink3')
			{
				sendMidi(uniqueId,0x90,0,0x23,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x23,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink4')
			{
				sendMidi(uniqueId,0x90,0,0x24,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x24,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink5')
			{
				sendMidi(uniqueId,0x90,0,0x25,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x25,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink6')
			{
				sendMidi(uniqueId,0x90,0,0x26,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x26,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink7')
			{
				sendMidi(uniqueId,0x90,0,0x27,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x27,(param1 ? 0x7F : 0x00));
			}
			if(name=='samplerBlink8')
			{
				sendMidi(uniqueId,0x90,0,0x28,(param1 ? 0x7F : 0x00));
				sendMidi(uniqueId,0x90,1,0x28,(param1 ? 0x7F : 0x00));
			}
		}
	}
	// with Shift (not mapped: 0x29..0x30)

	//Pads - Loop:
	if(name=='loopSize')
	{
		var loopSize = getValue('loopSize', deck);
		sendMidi(uniqueId,0x90,deck,0x31,(loopSize==4   ? 0x7F : 0x00));// loop 1/16
		sendMidi(uniqueId,0x90,deck,0x32,(loopSize==8   ? 0x7F : 0x00));// loop 1/8
		sendMidi(uniqueId,0x90,deck,0x33,(loopSize==16  ? 0x7F : 0x00));// loop 1/4
		sendMidi(uniqueId,0x90,deck,0x34,(loopSize==32  ? 0x7F : 0x00));// loop 1/2
		sendMidi(uniqueId,0x90,deck,0x35,(loopSize==64  ? 0x7F : 0x00));// loop 1
		sendMidi(uniqueId,0x90,deck,0x36,(loopSize==128 ? 0x7F : 0x00));// loop 2
		sendMidi(uniqueId,0x90,deck,0x37,(loopSize==256 ? 0x7F : 0x00));// loop 4
		sendMidi(uniqueId,0x90,deck,0x38,(loopSize==512 ? 0x7F : 0x00));// loop 8
	}
	// with Shift (0x39..0x40)
	if(name=='loopBlink')
	{
		sendMidi(uniqueId,0x90,deck,0x39,(param1 ? 0x7F : 0x00));// deckLoopInEnd
		sendMidi(uniqueId,0x90,deck,0x3A,(param1 ? 0x7F : 0x00));// deckLoopExitOrReloop
	}
	if(name=='loopMode')
	{
		// deck A
		sendMidi(uniqueId,0x90,0,0x3F,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,0,0x40,(param1 ? 0x7F : 0x00));
		// deck B
		sendMidi(uniqueId,0x90,1,0x3F,(param1 ? 0x7F : 0x00));
		sendMidi(uniqueId,0x90,1,0x40,(param1 ? 0x7F : 0x00));
	}
}
//-----------------------------------------------------------------------------
function setVUmeter(uniqueId, ch, dbValue)
{
	var vuCurrent = 1;// temp
	if(dbValue>-36) vuCurrent = 2;
	if(dbValue>-24) vuCurrent = 3;
	if(dbValue>-18) vuCurrent = 4;
	if(dbValue>-14) vuCurrent = 5;
	if(dbValue>-10) vuCurrent = 6;
	if(dbValue>-8)  vuCurrent = 7;
	if(dbValue>-6)  vuCurrent = 8;
	if(dbValue>-3)  vuCurrent = 9;
	// control all leds at the same time with one MIDI command
	sendMidi(uniqueId, 0x90, ch, 0x69, vuCurrent);
}
//-----------------------------------------------------------------------------
// 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+']');
	// VU-meters
	for(var i=0; i<2; i++)
	{
		var dbValue = getValue('vumeterDeck', i);// float dB
		setVUmeter(uniqueId, i, dbValue);
	}
}
//-----------------------------------------------------------------------------
