//-----------------------------------------------------------------------------
//------------ Copyright (c)2003-2018 Xylio. All Rights Reserved. -------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller 'Beyond Music Abma1 Controller'
//-----------------------------------------------------------------------------
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 "Beyond Music Abma1";// JBSystems DJ-kontrol 3?!? (the newer one with XLR audio outs)
}
//-----------------------------------------------------------------------------
// 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 0x25C0;// JBSystems DJ-kontrol 3?!? (the newer one with XLR audio outs)
}
//-----------------------------------------------------------------------------
function getSupportedMidiDevicePID(osId)
{
	return 0x0118;// JBSystems DJ-kontrol 3?!? (the newer one with XLR audio outs)
}
//-----------------------------------------------------------------------------
// 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 "00207B00010001";//Abma1
	// F07E00060200207B00010001010001007F7F7F7F4E333037303831383230303339303320F7 -- full sysex Abma1
	// F07E00060200207B00010004010001007F7F7F7F4E333037303831383230303339303320F7 -- full sysex Abm4
}
//-----------------------------------------------------------------------------
// 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 "ABMA USBAUDIO";
	return false;
}
//-----------------------------------------------------------------------------
function getSupportedMidiDeviceNameForOutput(osId)
{
	return false;
}
//-----------------------------------------------------------------------------
var posLedStrip = [[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0]];
//-----------------------------------------------------------------------------
function setSongPositionLedStrip(uniqueId, deck, pos) // pos is [0..1]
{
	var tmp, threshold=0;
	var startLedId = 0x07; if(deck>0) startLedId = 0x36;
	for(var i=0; i<11; i++)
	{
		// see if this led is to be on or off
		if(pos>threshold) tmp = 0x7F;else tmp = 0;
		// we test with the previous led state so we don't send led midi messages for no reason
		if(tmp != posLedStrip[deck][i])
		{
			// save new led state
			posLedStrip[deck][i] = tmp;
			// change led state
			sendMidi(uniqueId, 0x90, 0, startLedId + i, tmp);
		}
		// increase the threshold
		threshold += 0.0909;
	}
}
//-----------------------------------------------------------------------------
// some variables necessary only for this particular script
var jogWheelsInScratchMode=[0,0,0,0];
var jogWheelsWasDeckPlaying=[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 ABMA ['+uniqueId+']');// this outputs a string to DebugView app on Win

	//deck 1
	sendMidi(uniqueId,0x90,0,0x29,(getValue('cue', 0)? 0x7F : 0x00));// Cue
	sendMidi(uniqueId,0x90,0,0x25,(getValue('play', 0) ? 0x7F : 0x00));// PlayPause
	sendMidi(uniqueId,0x90,0,0x65,(getValue('monitor', 0) ? 0x7F : 0x00));// Monitor
	sendMidi(uniqueId,0x90,0,0x27,0x00);// onbeat
	sendMidi(uniqueId,0x90,0,0x1A,(getValue('cuepos1', 0) ? 0x7F : 0x00));// cue 1
	sendMidi(uniqueId,0x90,0,0x19,(getValue('cuepos2', 0) ? 0x7F : 0x00));// cue 2
	sendMidi(uniqueId,0x90,0,0x18,(getValue('cuepos3', 0) ? 0x7F : 0x00));// cue 3
	sendMidi(uniqueId,0x90,0,0x2C,(getValue('loopIn', 0) ? 0x7F : 0x00));// Loop in
	sendMidi(uniqueId,0x90,0,0x2D,(getValue('looping', 0) ? 0x7F : 0x00));// Loop out
	sendMidi(uniqueId,0x90,0,0x16,0x00);// loop 2
	sendMidi(uniqueId,0x90,0,0x15,0x00);// loop 4
	sendMidi(uniqueId,0x90,0,0x14,0x00);// loop 8
	sendMidi(uniqueId,0x90,0,0x2E,0x00);// scratch
	sendMidi(uniqueId,0xB0,0,0x19,0x7F);// left jog-wheel
	call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush

	//deck 2
	sendMidi(uniqueId,0x90,0,0x58,(getValue('cue', 0)? 0x7F : 0x00));// Cue
	sendMidi(uniqueId,0x90,0,0x54,(getValue('play', 0) ? 0x7F : 0x00));// PlayPause
	sendMidi(uniqueId,0x90,0,0x65,(getValue('monitor', 0) ? 0x7F : 0x00));// Monitor
	sendMidi(uniqueId,0x90,0,0x59,0x00);// onbeat
	sendMidi(uniqueId,0x90,0,0x49,(getValue('cuepos1', 0) ? 0x7F : 0x00));// cue 1
	sendMidi(uniqueId,0x90,0,0x48,(getValue('cuepos2', 0) ? 0x7F : 0x00));// cue 2
	sendMidi(uniqueId,0x90,0,0x47,(getValue('cuepos3', 0) ? 0x7F : 0x00));// cue 3
	sendMidi(uniqueId,0x90,0,0x5B,(getValue('loopIn', 0) ? 0x7F : 0x00));// Loop in
	sendMidi(uniqueId,0x90,0,0x5C,(getValue('looping', 0) ? 0x7F : 0x00));// Loop out
	sendMidi(uniqueId,0x90,0,0x45,0x00);// loop 2
	sendMidi(uniqueId,0x90,0,0x44,0x00);// loop 4
	sendMidi(uniqueId,0x90,0,0x43,0x00);// loop 8
	sendMidi(uniqueId,0x90,0,0x5D,0x00);// scratch
	sendMidi(uniqueId,0xB0,0,0x20, 0x7F); // right jogwheel
	call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush

	for(var i=0; i<2; i++)
	{
		setSongPositionLedStrip(uniqueId, i, 0);
		call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	}
	sendMidi(uniqueId,0xB0,0,0x19,0x00);
}
//-----------------------------------------------------------------------------
// 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 ABMA ['+uniqueId+']');

	sendMidi(uniqueId,0xB0,0,0x19,0x00);
	sendMidi(uniqueId,0xB0,0,0x20,0x00);

	//deck 1
	sendMidi(uniqueId,0x90,0,0x29,0x00);// cue
	sendMidi(uniqueId,0x90,0,0x25,0x00);// play
	sendMidi(uniqueId,0x90,0,0x65,0x00);// monitor
	sendMidi(uniqueId,0x90,0,0x27,0x00);// on beat
	sendMidi(uniqueId,0x90,0,0x1A,0x00);// cue 1
	sendMidi(uniqueId,0x90,0,0x19,0x00);// cue 2
	sendMidi(uniqueId,0x90,0,0x18,0x00);// cue 3
	sendMidi(uniqueId,0x90,0,0x2C,0x00);// loop in
	sendMidi(uniqueId,0x90,0,0x2D,0x00);// loop out
	sendMidi(uniqueId,0x90,0,0x16,0x00);// loop 2
	sendMidi(uniqueId,0x90,0,0x15,0x00);// loop 4
	sendMidi(uniqueId,0x90,0,0x14,0x00);// loop 8
	sendMidi(uniqueId,0x90,0,0x2E,0x00);// scratch
	call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush

	//deck 2
	sendMidi(uniqueId,0x90,0,0x58,0x00);// cue
	sendMidi(uniqueId,0x90,0,0x54,0x00);// play
	sendMidi(uniqueId,0x90,0,0x61,0x00);// monitor
	sendMidi(uniqueId,0x90,0,0x56,0x00);// on beat
	sendMidi(uniqueId,0x90,0,0x49,0x00);// cue 1
	sendMidi(uniqueId,0x90,0,0x48,0x00);// cue 2
	sendMidi(uniqueId,0x90,0,0x47,0x00);// cue 3
	sendMidi(uniqueId,0x90,0,0x5B,0x00);// loop in
	sendMidi(uniqueId,0x90,0,0x5C,0x00);// loop out
	sendMidi(uniqueId,0x90,0,0x45,0x00);// loop 2
	sendMidi(uniqueId,0x90,0,0x44,0x00);// loop 4
	sendMidi(uniqueId,0x90,0,0x43,0x00);// loop 8
	sendMidi(uniqueId,0x90,0,0x5D,0x00);// scratch
	call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush

	for(var i=0; i<2; i++)
	{
		setSongPositionLedStrip(uniqueId, i, 0);
		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)
{
	var messageNotProcessed=false;
	switch(status)
	{
	//-----------------------------------------------
	// controllers: sliders, knobs, jog-wheels, encoders ('moving' things)
	case 0xB0:
		switch(data1)
		{
		// global
			case 0x1A: // move track
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			call('lbMoveCursor', val1);
			break;//library curser up down


		case 0x0A: call('setCrossfader', 0x7F-data2); break; //crossfader
		case 0x20: call('setCuePgmMix', data2); break; // Cue Mix


		// decks

		//deck A
		case 0x08: call('setDeckVolume', 0, data2); break; //volume slider
		case 0x0D: call('setDeckGain', 0, data2); break; //deck gain
		case 0x0B: call('setDeckPitch', 0, data2); break; //pitch slider
		case 0x10: call('setDeckEqHigh', 0, data2); break; // eq high
		case 0x12: call('setDeckEqMid', 0, data2); break; // eq mid
		case 0x14: call('setDeckEqLow', 0, data2); break; // eq low
		case 0x17: call('setDeckPos', 0, data2); break; //filter
		case 0x19: // params: (deck, increment, total positions per complete revolution)
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			if(jogWheelsInScratchMode[0]) call('scratchDeckJW', 0, val1, 330);else call('moveDeckJogWheel', 0, val1, 330);
			break;


		//deck B
		case 0x09: call('setDeckVolume', 1, data2); break; //volume slider
		case 0x0E: call('setDeckGain', 1, data2); break; //deck gain
		case 0x0C: call('setDeckPitch', 1, data2); break; //pitch slider
		case 0x11: call('setDeckEqHigh', 1, data2); break; // eq high
		case 0x13: call('setDeckEqMid', 1, data2); break; // eq mid
		case 0x15: call('setDeckEqLow', 1, data2); break; // eq low
		case 0x16: call('setDeckPos', 1, data2); break; // filter
		case 0x18: // params: (deck, increment, total positions per complete revolution)
			var val1 = (data2>0x40 ? data2-0x80 : data2);
			if(jogWheelsInScratchMode[1]) call('scratchDeckJW', 1, val1, 330);else call('moveDeckJogWheel', 1, val1, 330);
			break;



		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)

	case 0x90:
		//if(status==0x90) data2 = 0x7F;
		//if(status==0x80) data2 = 0;
		switch(data1)
		{
		// global

		case 0x5B: // back
		case 0x4F: if(data2>0x3F) call('lbToggleSelect', data2); break; //list toggle


		// decks

		//deck 1
		case 0x4B: call('deckLBLoad', 0, data2); break; //load deck
		case 0x43: call('deckPlayPause', 0, data2); break; //play pause
		case 0x33: call('deckCuePlay', 0, data2); break; //cue Play
		case 0x3B: call('deckSetCue', 0, data2); break; //set cue
		case 0x40: call('deckSync', 0, data2); break; //sync
		case 0x50: call('deckEqHighKill', 0, data2); break; // eq high kill
		case 0x01: call('deckEqMidKill', 0, data2); break; // eq mid kill
		case 0x53: call('deckEqLowKill', 0, data2); break; // eq low kill
		case 0x73: call('deckCuePos1', 0, data2); break; // Cue 1
		case 0x74: call('deckCuePos2', 0, data2); break; // Cue 2
		case 0x75: call('deckCuePos3', 0, data2); break; // Cue 3
		case 0x79: call('deckBendDown', 0, data2); break; //pitch bend down
		case 0x78: call('deckBendUp', 0, data2); break; //pitch bend up
		case 0x77: call('deckResetPitch', 0, data2); break; // reset pitch
		case 0x6D: call('deckLoop2', 0, data2); break; //loop 2
		case 0x6E: call('deckLoop4', 0, data2); break; //loop 4
		case 0x6F: call('deckLoop8', 0, data2); break; //loop 8
		case 0x72: call('deckLoopLess', 0, data2); break; //loop /2
		case 0x71: call('deckLoopMore', 0, data2); break; //loop x2
		case 0x49: call('deckLoopInEnd', 0, data2); break; //loop in
		case 0x4A: if(!getValue('looping', 0)) call('deckLoopInEnd', 0, data2);else call('deckLoopExit', 0, data2); break; //Loop //loop end or exit
		case 0x70: call('deckLoopReloop', 0, data2); break; //reloop
		case 0x55: call('deckMonitor', 0, data2); break; //deck pfl
		case 0x7B: call('deckFxSel', 0, data2); break; //deck fx select
		case 0x7B: call('deckFxSel', 0, data2); break; //deck fx select
		case 0x7C: call('deckFxOn1', 0, data2); break; //deck fx on /off
		case 0x38: call('deckKeyLock', 0, data2); break; //deck keylock
		case 0x5A: if(data2>0x3F)
						{
						jogWheelsInScratchMode[0] = (jogWheelsInScratchMode[0]+1) % 2; sendMidi(uniqueId,0x90,0,0x2E,(jogWheelsInScratchMode[0] ? 0x7F : 0x00));
						}
						break;
		case 0x04: if(jogWheelsInScratchMode[0]) call('holdDeckJogWheel', 0, data2); break
		//case 0x04: call('holdDeckJogWheel', 0, data2); break;
			//jogWheelsInScratchMode[0] = (jogWheelsInScratchMode[0]+1) % 2; // keep the remainder to toggle between scratch mode "0" or jog bend mode "1"
			//call('holdDeckJogWheel', 0, jogWheelsInScratchMode[0]);
			//break;

		//deck 2
		case 0x34: call('deckLBLoad', 1, data2); break; //load deck
		case 0x4C: call('deckPlayPause', 1, data2); break; //play pause
		case 0x3C: call('deckCuePlay', 1, data2); break; //cue Play
		case 0x44: call('deckSetCue', 1, data2); break; //set cue
		case 0x47: call('deckSync', 1, data2); break; //sync
		case 0x52: call('deckEqHighKill', 1, data2); break; // eq high kill
		case 0x51: call('deckEqMidKill', 1, data2); break; // eq mid kill
		case 0x54: call('deckEqLowKill', 1, data2); break; // eq low kill
		case 0x62: call('deckCuePos1', 1, data2); break; // Cue 1
		case 0x63: call('deckCuePos2', 1, data2); break; // Cue 2
		case 0x64: call('deckCuePos3', 1, data2); break; // Cue 3
		case 0x68: call('deckBendDown', 1, data2); break; //pitch bend down
		case 0x67: call('deckBendUp', 1, data2); break; //pitch bend up
		case 0x66: call('deckResetPitch', 1, data2); break; // reset pitch
		case 0x5C: call('deckLoop2', 1, data2); break; //loop 2
		case 0x5D: call('deckLoop4', 1, data2); break; //loop 4
		case 0x5E: call('deckLoop8', 1, data2); break; //loop 8
		case 0x61: call('deckLoopLess', 1, data2); break; //loop /2
		case 0x60: call('deckLoopMore', 1, data2); break; //loop x2
		case 0x4D: call('deckLoopInEnd', 1, data2); break; //loop in
		case 0x4E: if(!getValue('looping', 1)) call('deckLoopInEnd', 1, data2);else call('deckLoopExit', 1, data2); break; //Loop //loop end or exit
		case 0x5F: call('deckLoopReloop', 1, data2); break; //reloop
		case 0x56: call('deckMonitor', 1, data2); break; //deck pfl
		case 0x6A: call('deckFxSel', 1, data2); break; //deck fx select
		case 0x6B: call('deckFxOn1', 1, data2); break; //deck fx on /off
		case 0x3F: call('deckKeyLock', 1, data2); break; //deck keylock
		case 0x57: if(data2>0x3F)
						{
						jogWheelsInScratchMode[1] = (jogWheelsInScratchMode[1]+1) % 2; sendMidi(uniqueId,0x90,0,0x5D,(jogWheelsInScratchMode[1] ? 0x7F : 0x00));
						}
						break;
		case 0x05: if(jogWheelsInScratchMode[1]) call('holdDeckJogWheel', 1, data2); break
		//case 0x05: call('holdDeckJogWheel', 1, data2); break;
			//jogWheelsInScratchMode[1] = (jogWheelsInScratchMode[1]+1) % 2; // keep the remainder to toggle between scratch mode "0" or jog bend mode "1"
			//call('holdDeckJogWheel', 1, jogWheelsInScratchMode[1]);
			//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')
	{
		sendMidi(uniqueId,0xB0, 0, (deck==0)?0x19:0x20,(param1 ? 0x7F : 0x00));
		// jog-wheels light display (rotate leds)
		if(param1)
		{
			if(getValue('reverse', deck))
				sendMidi(uniqueId,0xB0,1,0x20, 0x7F);// to left
			else
				sendMidi(uniqueId,0xB0,1,0x20, 0x01);// to right
		}else
		{
			sendMidi(uniqueId,0xB0,1,0x20, 0x40);// off
		}
	}
	if(name=='reverse')
	{
		if(getValue('play', deck))
		{
			if(param1)
				sendMidi(uniqueId,0xB0,1,0x20, 0x7F);// to left
			else
				sendMidi(uniqueId,0xB0,1,0x20, 0x01);// to right
		} // inspirat din Pioneer Ergo pentru rotirea LED-urilor de la joguri
	}

	if(deck>=2) return;
	{
			if(name=='cue') 		 sendMidi(uniqueId,0x90,0,(deck==0)?0x29:0x58,(param1 ? 0x7F : 0x00));
			if(name=='play') 		 sendMidi(uniqueId,0x90,0,(deck==0)?0x25:0x54,(param1 ? 0x7F : 0x00));
		{
			if(deck==0)	sendMidi(uniqueId,0xB0, 0, 19,(param1 ? 0x7F : 0x00));
			if(deck==1)	sendMidi(uniqueId,0xB0, 1, 20,(param1 ? 0x7F : 0x00));
		}
			if(name=='monitor') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x65:0x61,(param1 ? 0x7F : 0x00));
			if(name=='onbeat') 		 sendMidi(uniqueId,0x90,0,(deck==0)?0x27:0x56,(param1 ? 0x7F : 0x00));
			if(name=='cuepos1') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x1A:0x49,(param1 ? 0x7F : 0x00));
			if(name=='cuepos2') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x19:0x48,(param1 ? 0x7F : 0x00));
			if(name=='cuepos3') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x18:0x47,(param1 ? 0x7F : 0x00));
			if(name=='loopIn') 	 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x2C:0x5B,(param1 ? 0x7F : 0x00));
			if(name=='looping')
			{
			sendMidi(uniqueId,0x90,0,(deck==0)?0x2D:0x5C,(param1 ? 0x7F : 0x00));// loop in led
			sendMidi(uniqueId,0x90,0,(deck==0)?0x2C:0x5B,(param1 ? 0x7F : 0x00));//loop out led
			}

			if(name=='killHigh') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x62:0x5E,(param1 ? 0x7F : 0x00));
			if(name=='killMid') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x63:0x60,(param1 ? 0x7F : 0x00));
			if(name=='killLow') 	 sendMidi(uniqueId,0x90,0,(deck==0)?0x64:0x5F,(param1 ? 0x7F : 0x00));



		    if(name=='loopSize')
			{

			// calculate the new led to power on
				var l2, l4, l8;
				l2 = l4 = l8 = 0;
				switch(param1)
				{
				case  128: l2 = 0x7F; break; //loop 2
				case  256: l4 = 0x7F; break; //loop 4
				case  512: l8 = 0x7F; break; //loop 8


				}
					if(deck==0)
					{
					sendMidi(uniqueId,0x90,0,0x16,l2); //loop 2
					sendMidi(uniqueId,0x90,0,0x15,l4); //loop 4
					sendMidi(uniqueId,0x90,0,0x14,l8); //loop 8
					}
					if(deck==1)
					{
					sendMidi(uniqueId,0x90,0,0x45,l2); //loop 2
					sendMidi(uniqueId,0x90,0,0x44,l4); //loop 4
					sendMidi(uniqueId,0x90,0,0x43,l8); //loop 8
				}
			}
			// light off the leds
			if((name=='looping')&&(!param1))
			{
				if(deck==0)
				{
				sendMidi(uniqueId,0x90,0,0x16,0); //loop 2
				sendMidi(uniqueId,0x90,0,0x15,0); //loop 4
				sendMidi(uniqueId,0x90,0,0x14,0); //loop 8
				}

				if(deck==1)
				{
				sendMidi(uniqueId,0x90,0,0x45,0); //loop 2
				sendMidi(uniqueId,0x90,0,0x44,0); //loop 4
				sendMidi(uniqueId,0x90,0,0x43,0); //loop 8
				}
			}
	}
}
//-----------------------------------------------------------------------------
// 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 deck=0; deck<2; deck++)
	{
		var timeElapsed = getValue('timeElapsed', deck);// float seconds
		var timeRemain = getValue('timeRemain', deck);// float seconds
		var pos = 0;// pos is [0..1]
		timeRemain += timeElapsed;// total time
		if(timeRemain>0) pos = timeElapsed / timeRemain;
		setSongPositionLedStrip(uniqueId, deck, pos);
	}
}
//-----------------------------------------------------------------------------
