{***********************************************
Battery 3 - Slot 4 (Echo)
Author: Native Instruments
Written by: Nicki Marinic, Josef Natterer (natterer-script@web.de)
Modified: August 18, 2006
Version: 0.9.12
*************************************************}

on init
	declare const $VDEC_MIN := 7500 {kann man irgendwann loeschen}
	declare const $VDEC_MAX := 8500
	
	declare polyphonic $count
	declare polyphonic $duration {this is the duration of the repeated note}
	declare polyphonic $duration2 
	
	declare %delay_time[128] {the delay time in microseconds}
	
	declare polyphonic $Velocity  {this is the velocity of the repeated note}
	declare polyphonic $Velocitydelta {used for Vel: Last Setting}
	
	declare polyphonic $art_id
	declare polyphonic $Tune2
	declare polyphonic $pressed_id
	declare polyphonic $trigger_time
	
	declare polyphonic $delay_time2
	declare polyphonic $old_time
	
	declare %Repeat_helper[128] {the actual repeat count, from 1 to 20. $Feedback goes from 1 to 100 and is sclaed to 1 - 20}
	
	declare %Tdec[128]
	declare %Vdec[128]
	
	{----- GUI -----}
	
	declare ui_button $OnOff
	set_text($OnOff,"On / Off")
	
	declare ui_knob $Time (10,1000,1)
	set_knob_unit($Time,$KNOB_UNIT_MS)
	set_knob_defval($Time, 500)
	
	declare ui_knob $Feedback (1,100,1)
	set_knob_unit($Feedback,$KNOB_UNIT_PERCENT)
	set_text ($Feedback,"Feedb.")
	set_knob_defval($Feedback, 25)
	
	declare ui_knob $Time_Decay (-100,100,1)
	set_knob_unit($Time_Decay,$KNOB_UNIT_PERCENT)
	set_text ($Time_Decay,"Gravity")
	set_knob_defval($Time_Decay, 0)
	
	declare ui_knob $Tune (-100,100,100)
	set_knob_unit($Tune,$KNOB_UNIT_NONE)
	set_knob_defval($Tune, 0)
	
	
	declare ui_value_edit $Delay_X (1,64,1) {numerator for Delay}
	declare ui_value_edit $Delay_Y (1,64,1) {denominator for Delay}
	
	declare ui_button $Sync

	{-----Init-----}
	declare $a
	
	declare %onoff_store[128]
	declare %time_store[128]
	declare %feedback_store[128]
	declare %Time_decay_store[128]
	declare %Tune_store[128]
	declare %Delay_X_store[128]
	declare %Delay_Y_store[128]
	declare %Sync_store[128]

	$a := 0
	while($a < $NUM_GROUPS)
		%Time_Decay_store[$a] := 0
		%Feedback_store[$a] := 25
		%Time_store[$a] := 500
		%Tune_store[$a] := 0
		%Delay_X_store[$a] := 1
		%Delay_Y_store[$a] := 16
		%delay_time[$a] := %Delay_X_store[$a] * (($DURATION_QUARTER * 4) / %Delay_Y_store[$a])
		%sync_store[$a] := 1 {thus hide Time knob and show xy}
		%onoff_store[$a] := 0
		inc($a)
	end while
	
	move_control ($Time,0,0)
	
	move_control ($Delay_X,1,3)
	move_control ($Delay_Y,1,4)
	
	{----- Layout ------}
	move_control ($Tune,4,3)
	move_control ($Time_Decay, 3,3)
	move_control ($Feedback, 2,3)
	move_control ($Sync,1,2)
	move_control ($Onoff,1,1)
	
	{-----Recall-----}
	make_persistent (%onoff_store)
	make_persistent(%time_store)
	make_persistent(%feedback_store)
	make_persistent(%Time_decay_store)
	make_persistent(%Tune_store)
	make_persistent(%Delay_X_store)
	make_persistent(%Delay_Y_store)
	make_persistent(%Sync_store)

	_read_persistent_var(%onoff_store)
	_read_persistent_var(%time_store)
	_read_persistent_var(%feedback_store)
	_read_persistent_var(%Time_decay_store)
	_read_persistent_var(%Tune_store)
	_read_persistent_var(%Delay_X_store)
	_read_persistent_var(%Delay_Y_store)
	_read_persistent_var(%Sync_store)
	
	$OnOff := %onoff_store[$REF_GROUP_IDX]
	$time := %time_store[$REF_GROUP_IDX]
	$feedback := %feedback_store[$REF_GROUP_IDX]
	$time_decay := %time_decay_store[$REF_GROUP_IDX]
	$tune := %tune_store[$REF_GROUP_IDX]
	$delay_x := %delay_x_store[$REF_GROUP_IDX]
	$delay_y := %delay_y_store[$REF_GROUP_IDX]
	$sync := %sync_store[$REF_GROUP_IDX]
	
	select ($Sync)
		case 0
			move_control ($Delay_X,0,0)
			move_control ($Delay_Y,0,0)
			move_control ($Time,1,3)
		case 1
			move_control ($Delay_X,1,3)
			move_control ($Delay_Y,1,4)
			move_control ($Time,0,0)
	end select
	
	
end on

on ui_control ($Onoff)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%onoff_store[$a] := $onoff
		end if
		inc($a)
	end while
end on

on ui_control ($Time)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%time_store[$a] := $Time
		end if
		inc($a)
	end while
end on

on ui_control ($Feedback)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%feedback_store[$a] := $Feedback
			%Repeat_helper[$a] := (($Feedback - 1) * (19) / (99)) + 1
			if (in_range($Feedback,25,100))
				%Vdec[$a] := (($Feedback - 25) * ($VDEC_MAX - $VDEC_MIN) / (100 - 25)) + $VDEC_MIN
			else
				%Vdec[$a] := 7500
			end if
		end if
		inc($a)
	end while
end on

on ui_control ($Time_Decay)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%time_decay_store[$a] := $Time_Decay
			%Tdec[$a] := (($Time_Decay - (-100)) * (15000 - 5000) / (100 - (-100))) + 5000
		end if
		inc($a)
	end while
end on

on ui_control ($Tune)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%tune_store[$a] := $Tune
		end if
		inc($a)
	end while
end on

on ui_control ($delay_x)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%delay_x_store[$a] := $delay_x
		end if
		inc($a)
	end while
end on

on ui_control ($delay_y)
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%delay_y_store[$a] := $delay_y
		end if
		inc($a)
	end while
end on

on ui_control ($Sync)
	select ($Sync)
		case 0
			move_control ($Delay_X,0,0)
			move_control ($Delay_Y,0,0)
			move_control ($Time,1,3)
		case 1
			move_control ($Delay_X,1,3)
			move_control ($Delay_Y,1,4)
			move_control ($Time,0,0)
	end select
	$a := 0
	while($a < $NUM_GROUPS)
		if (%GROUPS_SELECTED[$a] = 1)
			%sync_store[$a] := $Sync
		end if
		inc($a)
	end while
end on


on note
	if (%EVENT_PAR[0] = 1000)
		exit
	end if
	if (%onoff_store[%EVENT_PAR[0]] = 0)
		exit
	end if
	$pressed_id := $EVENT_ID
	$trigger_time := $ENGINE_UPTIME
	$old_time := %Time_store[%EVENT_PAR[0]]

	{get Velocity Decay}
	if (in_range(%Feedback_store[%EVENT_PAR[0]],25,100))
		%Vdec[%EVENT_PAR[0]] := ((%Feedback_store[%EVENT_PAR[0]] - 25) * ($VDEC_MAX - $VDEC_MIN) / (100 - 25)) + $VDEC_MIN
	else
		%Vdec[%EVENT_PAR[0]] := 7500
	end if
	
	{get Time Decay}
	%Tdec[%EVENT_PAR[0]] := ((%Time_Decay_store[%EVENT_PAR[0]] - (-100)) * (15000 - 5000) / (100 - (-100))) + 5000
	
	{get number of repeats}
	%Repeat_helper[%EVENT_PAR[0]] := ((%Feedback_store[%EVENT_PAR[0]] - 1) * (19) / (99)) + 1
	
	{get delay time}
	if (%Sync_store[%EVENT_PAR[0]] = 1)
		if (%Delay_Y_store[%EVENT_PAR[0]] = 1)
			%delay_time[%EVENT_PAR[0]] := %Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR
			$old_time := (%Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR)/1000
		else
			%delay_time[%EVENT_PAR[0]] := %Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]])
			$old_time := (%Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]]))/1000
		end if
	else
		%delay_time[%EVENT_PAR[0]] := %Time_store[%EVENT_PAR[0]] * 1000
		$old_time := %Time_store[%EVENT_PAR[0]]
	end if
			
	$count := 1
	
	$Tune2 := %Tune_store[%EVENT_PAR[0]]*1000
	
	$delay_time2 := %delay_time[%EVENT_PAR[0]]
	
	{-----find velocity of the first repeated note-----}
	
			if (((($EVENT_VELOCITY * 100 / 100) * %vdec[%EVENT_PAR[0]]) / 10000) < 1)
				$Velocity := 1
			else
				if (((($EVENT_VELOCITY * 100 / 100) * %vdec[%EVENT_PAR[0]]) / 10000) > 127)
					$Velocity := 127
				else
					$Velocity := (($EVENT_VELOCITY * 100/ 100) * %vdec[%EVENT_PAR[0]]) / 10000
				end if
			end if
	
	{get delay time 2}
	
	if (%Sync_store[%EVENT_PAR[0]] = 1)
		if (%Delay_Y_store[%EVENT_PAR[0]] = 1)
			%delay_time[%EVENT_PAR[0]] := %Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR
		else
			$delay_time2 := %Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]])
		end if
	else
		$delay_time2 := %Time_store[%EVENT_PAR[0]] * 1000
	end if
	
	wait ($delay_time2)
	
	if ($pressed_id = $EVENT_ID)
		note_off ($EVENT_ID)
		$duration := %delay_time[%EVENT_PAR[0]]
	else
		$duration := $duration2
	end if		
	
	
	if ($duration < 5000)
		$duration := 5000
	end if
	
	
	while ($count <= %Repeat_helper[%EVENT_PAR[0]])
	
		$art_id := play_note ($EVENT_NOTE, $Velocity, 0, $duration)
		set_event_par($art_id,0,%EVENT_PAR[0])
		set_event_par($art_id,1,%EVENT_PAR[1])
		set_event_par($art_id,2,%EVENT_PAR[2]+$Tune2)
		set_event_par($art_id,3,%EVENT_PAR[3])
		{change_tune($art_id,$Tune2 ,1)}
			
		$Tune2 := (%Tune_store[%EVENT_PAR[0]] * 1000) + $Tune2
		inc ($count)
		
		{find velocity of the consecutive  repeated notes}
				if (((($Velocity * 100 / 100) * %vdec[%EVENT_PAR[0]]) / 10000) <= 1)
					exit
				else
					if (((($Velocity * 100 / 100) * %vdec[%EVENT_PAR[0]]) / 10000) > 127)
						$Velocity := 127
					else
						$Velocity := (($Velocity * 100 / 100) * %vdec[%EVENT_PAR[0]]) / 10000
					end if
				end if
		
			if (((($delay_time2/ 100) * %tdec[%EVENT_PAR[0]]) / 100) < 1000)
				$delay_time2 := 1000
			else
				$delay_time2 := (($delay_time2 / 100) * %tdec[%EVENT_PAR[0]]) / 100
			
			end if
			if (%Sync_store[%EVENT_PAR[0]] = 1)
				if (%Delay_Y_store[%EVENT_PAR[0]] = 1)
					if ((%Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR)/1000 # $old_time)
						$delay_time2 := ($delay_time2 *((%Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR)/1000))/$old_time
						$old_time := (%Delay_X_store[%EVENT_PAR[0]] * $DURATION_BAR)/1000
					end if
				else
					if ((%Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]]))/1000 # $old_time)
						$delay_time2 := ($delay_time2 *((%Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]]))/1000))/$old_time
						$old_time := (%Delay_X_store[%EVENT_PAR[0]] * (($DURATION_QUARTER * 4) / %Delay_Y_store[%EVENT_PAR[0]]))/1000
					end if
				end if
			else
				if (%Time_store[%EVENT_PAR[0]] # $old_time)
					$delay_time2 := ($delay_time2 *%Time_store[%EVENT_PAR[0]])/$old_time
					$old_time := %Time_store[%EVENT_PAR[0]]
				end if
			end if
			if ($delay_time2 < 100)
				exit
			end if
			wait ($delay_time2)
			if (%onoff_store[%EVENT_PAR[0]] = 0)
				exit
			end if			
	end while
end on
on release
	if (%EVENT_PAR[0] = 1000)
		exit
	end if
	if (%onoff_store[%EVENT_PAR[0]] = 0)
		exit
	end if
	$pressed_id := 0
	$duration2 := ($ENGINE_UPTIME - $trigger_time)*1000
end on

on ui_update
	$OnOff := %onoff_store[$REF_GROUP_IDX]
	$time := %time_store[$REF_GROUP_IDX]
	$feedback := %feedback_store[$REF_GROUP_IDX]
	$time_decay := %time_decay_store[$REF_GROUP_IDX]
	$tune := %tune_store[$REF_GROUP_IDX]
	$delay_x := %delay_x_store[$REF_GROUP_IDX]
	$delay_y := %delay_y_store[$REF_GROUP_IDX]
	$sync := %sync_store[$REF_GROUP_IDX]
	select ($Sync)
		case 0
			move_control ($Delay_X,0,0)
			move_control ($Delay_Y,0,0)
			move_control ($Time,1,3)
		case 1
			move_control ($Delay_X,1,3)
			move_control ($Delay_Y,1,4)
			move_control ($Time,0,0)
	end select
end on
