{***********************************************
Arpeggiator
Author: Native Instruments
Written by: Josef Natterer, Nicki Marinic
Modified: September 11, 2009
**********************{***********************************************
Arpeggiator
Author: Native Instruments
Written by: Josef Natterer, Nicki Marinic
Modified: September 11, 2009
*************************************************}

on init
	
	set_script_title("Arpeggiator")
	set_ui_height(5)
	message("")
	
	declare const $REC_TIME := 30
	declare const $LATCH_TIME := 300
	declare const $LATCH_TIME_TRANS := 1000
	declare $repeat := 1 
	{if up/down: 1 = No Repeat, 2 = Repeat top, 3 = Repeat bottom, 5 = Repeat both}

	declare $latch_mode
	make_persistent($latch_mode)
	$latch_mode := 1
	
	declare $Str_Vel := 100
	declare $count := 0
	
	declare !note_class[12]
	!note_class[0] := "C"
	!note_class[1] := "Db"
	!note_class[2] := "D"
	!note_class[3] := "Eb"
	!note_class[4] := "E"
	!note_class[5] := "F"
	!note_class[6] := "Gb"
	!note_class[7] := "G"
	!note_class[8] := "Ab"
	!note_class[9] := "A"
	!note_class[10] := "Bb"
	!note_class[11] := "B"
	
	declare !note_names [128]
	$count := 0
	while ($count < 128)
		!note_names[$count] := !note_class[$count mod 12] & (($count/12)-2)
		inc ($count)
	end while
	
	declare ui_knob $Latch_knob (0,3,1)
	make_persistent($latch_knob)
	set_text($Latch_knob,"Mode")
	$latch_knob := 1
	_read_persistent_var($latch_mode)
	
	select ($latch_mode)
		case 0 
			set_knob_label($latch_knob,"Off")
		case 1 
			set_knob_label($latch_knob,"On")
		case 2
			set_knob_label($latch_knob,"Hold")
		case 3
			set_knob_label($latch_knob,"Hold +-")
	end select

	declare ui_knob $Dur (1, 200, 1)
	set_text($Dur,"Duration")
	set_knob_unit($Dur,$KNOB_UNIT_PERCENT)
	set_knob_defval($Dur,100)
	make_persistent($Dur)
	$Dur := 100

	declare ui_knob $Strike (1, 5, 1)
	make_persistent($Strike)
	$Strike := 1

	declare ui_value_edit $Steps (2,32, 1)
	make_persistent($Steps)
	$Steps := 16
	_read_persistent_var($steps)
	
	declare ui_table %rhythm[32] (2,2,100)
	make_persistent(%rhythm)
	
	declare ui_knob $Swing (-50,50,1)
	make_persistent($Swing)
	set_knob_unit($Swing,$KNOB_UNIT_PERCENT)
	$Swing := 0
	set_knob_defval($Swing,0)
		
	declare ui_knob $Octave (-6,6,1)
	make_persistent($Octave)
	$Octave := 0
	set_knob_defval($Octave,0)
	
	declare ui_menu $note_order
	add_menu_item ($note_order,"Select Note Order",99)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "As Played",1)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "Up",2)
	add_menu_item ($note_order, "Down",3)
	add_menu_item ($note_order, "Up & Down",4)
	add_menu_item ($note_order, "Down & Up",5)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "Zig-Zag Up",6)
	add_menu_item ($note_order, "Zig-Zag Down",7)
	add_menu_item ($note_order, "Zig-Zag Up-Dn",8)
	add_menu_item ($note_order, "Zig-Zag Dn-Up",9)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "Move in", 10)
	add_menu_item ($note_order, "Move out",11)
	add_menu_item ($note_order, "Move in & out",12)
	add_menu_item ($note_order, "Move out & in",13)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "Random",14)
	add_menu_item ($note_order, "Random (Urn)",15)
	add_menu_item ($note_order, "--------------",99)
	add_menu_item ($note_order, "All (Chord)",16)
	declare $last_note_order := 2
	$note_order := 2
	make_persistent($note_order)
	make_persistent($last_note_order)

	declare ui_switch $Velo_button
	set_control_par_str(get_ui_id($Velo_button),$CONTROL_PAR_TEXT,"Fix Velocity")
	make_persistent($Velo_button)
	
	declare ui_switch $midi_thru
	set_control_par_str(get_ui_id($midi_thru),$CONTROL_PAR_TEXT,"MIDI Thru")
	make_persistent($midi_thru)
	
	{**** from retrigger script*********}
	declare const $Tempo_knob_X := 4
	declare const $Tempo_knob_Y := 3
	
	declare @knob_name
	@knob_name := "Rate"
	
	declare !tempo_names[18]
	
	!tempo_names[0] := "1/128"
	!tempo_names[1] := "1/64"
	!tempo_names[2] := "1/32"
	!tempo_names[3] := "1/16 T"
	!tempo_names[4] := "3/64"
	!tempo_names[5] := "1/16"
	!tempo_names[6] := "1/8 T"
	!tempo_names[7] := "3/32"
	!tempo_names[8] := "1/8"
	!tempo_names[9] := "1/4 T"
	!tempo_names[10] := "3/16"
	!tempo_names[11] := "1/4"
	!tempo_names[12] := "1/2 T"
	!tempo_names[13] := "3/8"
	!tempo_names[14] := "1/2"
	!tempo_names[15] := "3/4"
	!tempo_names[16] := "4/4"
	!tempo_names[17] := "Bar"
	
	declare ui_knob $Rate_knob (0,1000000,1)
	set_text ($Rate_knob,"Rate")
	make_persistent ($Rate_knob)
	
	declare ui_knob $Sync_knob (0,17,1)
	set_text ($Sync_knob,@knob_name)
	$Sync_knob := 5
	set_knob_defval ($Sync_knob,5)
	set_knob_label ($Sync_knob,!tempo_names[$Sync_knob])
	make_persistent ($Sync_knob)
	
	declare $fill_buffer := 11
	make_persistent($fill_buffer)
	
	{**** from retrigger script*********}
	
	declare %pressed_id[128]
	declare %note_buffer[512]
	declare %ordered[128]
	declare %velo[128]
	declare $cursor
	declare $old_latch_time
	declare $a
	declare $aa
	declare $sema
	declare $rand
	declare $bb
	declare $b
	declare $loop_cursor
	declare %loop_buffer[512]
	declare $id
	declare $check_id
	declare $min
	declare $min_note
	declare $max_note
	declare $helper
	declare %help_buffer[512]
	declare $step_length
	declare $strike_count
	declare $duration
	declare $note
	declare $velo
	declare $act_step
	declare $last_order
	declare $oct_cursor
	declare $swing_cursor
	
	declare const $PRESET_LENGTH := 43
	
	declare ui_menu $edit_preset
	add_menu_item($edit_preset,"Select Preset...",100)
	add_menu_item($edit_preset,"--------------",99)
	
	declare %helper_preset[42] := (...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,16,2,1,0,1,294118,100,0,0,250)
	declare %helper_rhythm[33] := (...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,100,100,16)
	make_persistent(%helper_preset)
	declare %default_preset[42] := (...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,100,100,100,100,100,100,100,100,...
	100,100,16,2,1,0,1,294118,100,0,0,250)

	declare %preset_arr[12*42]
	make_persistent(%Preset_arr)
	$a := 0
	while($a < 12*42)
		%preset_arr[$a] := %default_preset[$a mod 42]
		inc($a)
	end while
	
	$a := 0
	set_table_steps_shown(%rhythm, $steps)

	_read_persistent_var($Sync_knob)
	set_knob_label ($Sync_knob,!tempo_names[$Sync_knob])
	
	$Rate_knob := ($sync_knob *1000001) / 17
	set_knob_defval ($Rate_knob,(5 *1000001) / 17)
	set_knob_label ($Rate_knob,!tempo_names[$sync_knob])
	set_knob_unit($Rate_knob,$KNOB_UNIT_NONE)

	declare ui_label $note_order_label (1,1)
	set_text ($note_order_label,"Note Order:")
	set_control_par(get_ui_id($note_order_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)
	
	declare ui_label $Global_label (3,1)
	set_text ($Global_label,"Global Settings")
	set_control_par(get_ui_id($Global_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)
	
	declare ui_label $Pitch_label (3,1)
	set_text ($Pitch_label,"Pitch")
	set_control_par(get_ui_id($Pitch_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)
	
	declare ui_label $Timing_label (3,1)
	set_text ($Timing_label,"Timing")
	set_control_par(get_ui_id($Timing_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)

	declare ui_label $Rhythm_label (3,1)
	set_text ($Rhythm_label,"Rhythm")
	set_control_par(get_ui_id($Rhythm_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)

	move_control($Global_label,1,2)
	move_control($Pitch_label,4,2)
	move_control($Timing_label,1,7)
	move_control($Rhythm_label,4,7)
	
	move_control($note_order_label,4,3)
	move_control(%rhythm,5,8)
	move_control($swing,3,8)
	move_control($steps,4,8)
	
	move_control($Dur,2,8)
	move_control($note_order,4,4)
	move_control($strike,6,3)	
	
	move_control($Octave,5,3)		
	move_control($latch_knob,1,3)
	
	move_control($edit_preset,0,0)
	move_control($Velo_button,4,9)
	
	move_control($midi_thru,3,4)
	move_control($Rate_knob,1,8)
	move_control($Sync_knob,0,0)

	{******************** SET CONTROL HELP ****************************************}
	
	set_control_help($Latch_knob,"Arpeggiator Mode: Choose among three arpeggiator modes. <On> enables the normal arpeggiator mode. <Hold> will latch all played keys. <Hold+-> will latch all played keys and subsequently played keys will be added or taken away from the note buffer. <Off> turns the arpeggiator off.")
	set_control_help($Dur,"Duration: Sets the duration of the arpeggiated MIDI notes in percent. This will only hange the length o the MIDI notes, not the volume envelope.")
	set_control_help($Strike,"Strike: Sets the number of strikes of each note of the note buffer. When <Strike> is set to any other value other than 1, each note of the note buffer will be repeated by the amount specified with <Strike>.")
	set_control_help(%rhythm,"Rhythm Grid: Sets the rhythmic pattern of the arpeggiated notes. The columns set the velocity of each note. If a column is set to 0 (e.g. by Cmd/Ctrl cliking on a table column), the step will not be played. The actual velocity depends on the <Fix Velocity> button, the length of the pattern can be set with <Steps>.")
	set_control_help($Swing,"Swing: Offsets every other step by the specified amount in percent in order to create a swing feel. Positive values delay every other step, negative values push every other step forward.")
	set_control_help($Steps,"Steps: Sets the number of steps of the rhythmic pattern.")
	set_control_help($Octave,"Octave: Sets the octave displacement, i.e. the distribution of the arpeggio pattern in various octaves. The arpeggio pattern cycles from the played octave to the octave set upwards.")
	set_control_help($note_order_label,"Note Order: Defines the pattern for the order in which notes are arpeggiated.")
	set_control_help($note_order,"Note Order: Defines the pattern for the order in which notes are arpeggiated.")
	set_control_help($velo_button,"Fix Velocity: When enabled, played velocities are ignored and taken from the columns in the rhythmic grid. When deactivated, played velocities will be scaled by the columns of the rhythmic grid.")
	set_control_help($edit_preset,"Preset Menu: Selection of factory presets.")
	set_control_help($Global_label,"Global Settings: Adjust the arpeggiator's global settings.")
	set_control_help($Pitch_label,"Pitch Settings: Adjust the arpeggiator's pitch settings, which determine the octaves and note repititions played.")	
	set_control_help($Pitch_label,"Timing Settings: Adjust the arpeggiator's timing settings, which determine the rate and duration of the notes and the amount of swing.")	
	set_control_help($Pitch_label,"Rhythm Settings: Adjust the arpeggiator's rhythm settings, which determine the velocities of the notes and the number of velocity steps played.")	
	set_control_help($Sync_knob,"Rate (Sync): Adjust the tempo in rhythmical values, synced to the master clock. T stands for triplet.")
	set_control_help($midi_thru,"MIDI Thru: When activated, played notes will be merged with the arpeggiated notes.")
	set_control_help($Rate_Knob,"Rate: Sets the rate of the arpeggiator.")

	{******************** SET CONTROL HELP ****************************************}

end on

on pgs_changed

	{On off control}
	$Latch_knob := pgs_get_key_val(arp_controls, 0)

	$latch_mode := $latch_knob
	select ($latch_mode)
		case 0
			set_knob_label($latch_knob,"Off")
			$a := 0
			while($a < $cursor)
				%note_buffer[$a] := 0
				inc($a)
			end while
			$cursor := 0 
		case 1
			set_knob_label($latch_knob,"On")
			$b := $cursor
			$cursor := 0 
			$a := 0
			while($a < $b)
				if (%pressed_id[%note_buffer[$a]] > 0)
					%note_buffer[$cursor] := %note_buffer[$a]
					inc($cursor)
				end if
				inc($a)
			end while
	end select

	{Steps value edit box}
	$Steps := pgs_get_key_val(arp_controls, 1)
	set_table_steps_shown(%rhythm, $Steps)

	{Note order menu}
	$note_order := pgs_get_key_val(arp_controls, 2)

	{Octave knob}
	$Octave := pgs_get_key_val(arp_controls, 3)

	{Duration knob}
	$Dur := pgs_get_key_val(arp_controls, 4)

	{Rate knob}
	$Rate_knob := pgs_get_key_val(arp_controls, 5)
	$sync_knob := ($Rate_knob * 18) /1000001
	set_knob_label ($Rate_knob,!tempo_names[$sync_knob])	

	{Arpeggiator pattern table}
	%rhythm[0] := pgs_get_key_val(arp_table, 0)
	%rhythm[1] := pgs_get_key_val(arp_table, 1)
	%rhythm[2] := pgs_get_key_val(arp_table, 2)
	%rhythm[3] := pgs_get_key_val(arp_table, 3)
	%rhythm[4] := pgs_get_key_val(arp_table, 4)
	%rhythm[5] := pgs_get_key_val(arp_table, 5)
	%rhythm[6] := pgs_get_key_val(arp_table, 6)
	%rhythm[7] := pgs_get_key_val(arp_table, 7)
	%rhythm[8] := pgs_get_key_val(arp_table, 8)
	%rhythm[9] := pgs_get_key_val(arp_table, 9)
	%rhythm[10] := pgs_get_key_val(arp_table, 10)
	%rhythm[11] := pgs_get_key_val(arp_table, 11)
	%rhythm[12] := pgs_get_key_val(arp_table, 12)
	%rhythm[13] := pgs_get_key_val(arp_table, 13)
	%rhythm[14] := pgs_get_key_val(arp_table, 14)
	%rhythm[15] := pgs_get_key_val(arp_table, 15)
	%rhythm[16] := pgs_get_key_val(arp_table, 16)
	%rhythm[17] := pgs_get_key_val(arp_table, 17)
	%rhythm[18] := pgs_get_key_val(arp_table, 18)
	%rhythm[19] := pgs_get_key_val(arp_table, 19)
	%rhythm[20] := pgs_get_key_val(arp_table, 20)
	%rhythm[21] := pgs_get_key_val(arp_table, 21)
	%rhythm[22] := pgs_get_key_val(arp_table, 22)
	%rhythm[23] := pgs_get_key_val(arp_table, 23)
	%rhythm[24] := pgs_get_key_val(arp_table, 24)
	%rhythm[25] := pgs_get_key_val(arp_table, 25)
	%rhythm[26] := pgs_get_key_val(arp_table, 26)
	%rhythm[27] := pgs_get_key_val(arp_table, 27)
	%rhythm[28] := pgs_get_key_val(arp_table, 28)
	%rhythm[29] := pgs_get_key_val(arp_table, 29)
	%rhythm[30] := pgs_get_key_val(arp_table, 30)
	%rhythm[31] := pgs_get_key_val(arp_table, 31)

end on


on note

	if ($latch_mode = 0)
		exit
	end if
	%velo[$EVENT_NOTE] := $EVENT_VELOCITY
	{only one event per Note}
	set_event_par($EVENT_ID,0,2)
	if ($midi_thru = 0)
		ignore_event($EVENT_ID)
	end if
	if (%pressed_id[$EVENT_NOTE] > 0)
		exit
	else
		%pressed_id[$EVENT_NOTE] := $EVENT_ID
	end if
	
	{which notes should be in the buffer}
	select ($latch_mode)
		case 1
			%note_buffer[$cursor] := $EVENT_NOTE
			inc($cursor)
		case 2
			if ($ENGINE_UPTIME - $old_latch_time > $LATCH_TIME)
				$a := 0
				while($a < $cursor)
					%note_buffer[$a] := 0
					inc($a)
				end while
				$cursor := 0
			end if
			%note_buffer[$cursor] := $EVENT_NOTE
			inc($cursor)
			$old_latch_time := $ENGINE_UPTIME
		case 3
			$a := 0
			$b := $cursor
			$cursor := 0
			while($a < $b)
				if ($EVENT_NOTE # %note_buffer[$a])
					%note_buffer[$cursor] := %note_buffer[$a]
					inc($cursor)
				end if
				inc($a)
			end while
			if ($b = $cursor)
				%note_buffer[$cursor] := $EVENT_NOTE
				inc($cursor)				
			end if
	end select

	if ($cursor < 2 and $check_id = 0)
		$check_id := $EVENT_ID
		$aa := 0
		$act_step := 0
		$oct_cursor := 0
		$last_order := -1
		$swing_cursor := 0
		wait($REC_TIME*1000)	
		while($cursor > 0)
			$a := 0
			while($a < 128)
				if ($a < $cursor)
					%ordered[$a] := %note_buffer[$a]
				else
					%ordered[$a] := 0
					%note_buffer[$a] := 0
				end if
				inc($a)
			end while
			$min_note := %ordered[$cursor-1]
			$max_note := %ordered[0]
			sort(%ordered,1)
			select ($note_order)
				case 1
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor)
						%loop_buffer[$a] := %note_buffer[$a]
						inc($a)
					end while					
				case 2	{up }
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor )
						%loop_buffer[$a] := %ordered[$cursor - 1 - $a]
						inc($a)
					end while
				case 3	{down }
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor )
						%loop_buffer[$a] := %ordered[$a]
						inc($a)
					end while
				case 4	{up_down }
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor )
						%loop_buffer[$a] := %ordered[$cursor -1 - $a]
						inc($a)
					end while
					if ($cursor > 2)
						select ($repeat)
							case 1
								$loop_cursor := ($cursor*2)-2
								$a := 0
								while($a < $cursor-2 )
									%loop_buffer[$a+$cursor] := %ordered[$a+1]
									inc($a)
								end while
							case 2
								$loop_cursor := ($cursor*2)-1
								$a := 0
								while($a < $cursor-1 )
									%loop_buffer[$a+$cursor] := %ordered[$a]
									inc($a)
								end while
							case 3
								$loop_cursor := ($cursor*2)-1
								$a := 0
								while($a < $cursor-1 )
									%loop_buffer[$a+$cursor] := %ordered[$a+1]
									inc($a)
								end while
							case 5
								$loop_cursor := ($cursor*2)
								$a := 0
								while($a < $cursor )
									%loop_buffer[$a+$cursor] := %ordered[$a]
									inc($a)
								end while
						end select
					end if
				case 5	{down_up }
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor )
						%loop_buffer[$a] := %ordered[$a]
						inc($a)
					end while
					if ($cursor > 2)
						select ($repeat)
							case 1
								$loop_cursor := ($cursor*2)-2
								$a := 0
								while($a < $cursor-2 )
									%loop_buffer[$a+$cursor] := %ordered[$cursor -2- $a]
									inc($a)
								end while
							case 3
								$loop_cursor := ($cursor*2)-1
								$a := 0
								while($a < $cursor-1 )
									%loop_buffer[$a+$cursor] := %ordered[$cursor -1 - $a]
									inc($a)
								end while
							case 2
								$loop_cursor := ($cursor*2)-1
								$a := 0
								while($a < $cursor-1 )
									%loop_buffer[$a+$cursor] := %ordered[$cursor -2- $a]
									inc($a)
								end while
							case 5
								$loop_cursor := ($cursor*2)
								$a := 0
								while($a < $cursor )
									%loop_buffer[$a+$cursor] := %ordered[$cursor -1- $a]
									inc($a)
								end while
						end select
					end if
				case 6	{zickzack up}
					if ($cursor = 1)
						%loop_buffer[0] := $min_note
						$loop_cursor := 1
					end if
					if ($cursor = 2)
						%loop_buffer[0] := $min_note
						%loop_buffer[1] := $max_note
						$loop_cursor := 2
					end if
					if ($cursor = 3)
						%loop_buffer[0] := %ordered[2]
						%loop_buffer[1] := %ordered[0]
						%loop_buffer[2] := %ordered[1]
						$loop_cursor := 3
					end if
					if ($cursor > 3)
						$a := 0
						while($a < $cursor-2)
							%loop_buffer[($a*2)] :=	%ordered[$cursor-$a-1]
							%loop_buffer[($a*2)+1] :=%ordered[$cursor-$a-3]
							inc($a)
						end while
						$loop_cursor := (2*$cursor)-4
					end if
				case 7	{zickzack_down }
					if ($cursor = 1)
						%loop_buffer[0] := $min_note
						$loop_cursor := 1
					end if
					if ($cursor = 2)
						%loop_buffer[0] := $max_note
						%loop_buffer[1] := $min_note
						$loop_cursor := 2
					end if
					if ($cursor = 3)
						%loop_buffer[0] := %ordered[0]
						%loop_buffer[1] := %ordered[2]
						%loop_buffer[2] := %ordered[1]
						$loop_cursor := 3
					end if
					if ($cursor > 3)
						$a := 0
						while($a < $cursor-2)
							%loop_buffer[($a*2)] :=	%ordered[$a]
							%loop_buffer[($a*2)+1] :=%ordered[$a+2]
							inc($a)
						end while
						$loop_cursor := (2*$cursor)-4
					end if
				case 8	{zickzack updn}
					if ($cursor = 1)
						%loop_buffer[0] := $min_note
						$loop_cursor := 1
					end if
					if ($cursor = 2)
						%loop_buffer[0] := $min_note
						%loop_buffer[1] := $max_note
						$loop_cursor := 2
					end if
					if ($cursor = 3)
						select($repeat)
							case 1
								%loop_buffer[0] := %ordered[2]
								%loop_buffer[1] := %ordered[0]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[0]
								$loop_cursor := 4
							case 3
								%loop_buffer[0] := %ordered[2]
								%loop_buffer[1] := %ordered[0]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[1]
								%loop_buffer[4] := %ordered[0]
								$loop_cursor := 5
							case 2
								%loop_buffer[0] := %ordered[2]
								%loop_buffer[1] := %ordered[0]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[0]
								%loop_buffer[4] := %ordered[2]
								$loop_cursor := 5
							case 5
								%loop_buffer[0] := %ordered[2]
								%loop_buffer[1] := %ordered[0]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[1]
								%loop_buffer[4] := %ordered[0]
								%loop_buffer[5] := %ordered[2]
								$loop_cursor := 6
						end select
					end if
					if ($cursor > 3)
						select ($repeat)
							case 1
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$cursor-$a-1]
									%loop_buffer[($a*2)+1] :=%ordered[$cursor-$a-3]
									inc($a)
								end while
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)] :=	%ordered[$a+2]
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=%ordered[$a+1]
									inc($a)
								end while
								$loop_cursor := (4*$cursor)-10
							case 2
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$cursor-$a-1]
									%loop_buffer[($a*2)+1] :=%ordered[$cursor-$a-3]
									inc($a)
								end while
								%loop_buffer[($cursor-2)*2] :=%ordered[0]
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=	%ordered[$a+2]
									%loop_buffer[($a*2)+(($cursor-2)*2)+2] :=%ordered[$a+1]
									inc($a)
								end while
								$loop_cursor := (4*$cursor)-9
							case 3
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$cursor-$a-1]
									%loop_buffer[($a*2)+1] :=%ordered[$cursor-$a-3]
									inc($a)
								end while
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)] :=	%ordered[$a+2]
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=%ordered[$a+1]
									inc($a)
								end while
								%loop_buffer[(4*$cursor)-9-1] :=%ordered[$cursor-1]
								$loop_cursor := (4*$cursor)-9
							case 5
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$cursor-$a-1]
									%loop_buffer[($a*2)+1] :=%ordered[$cursor-$a-3]
									inc($a)
								end while
								%loop_buffer[($cursor-2)*2] :=%ordered[0]
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=	%ordered[$a+2]
									%loop_buffer[($a*2)+(($cursor-2)*2)+2] :=%ordered[$a+1]
									inc($a)
								end while
								%loop_buffer[(4*$cursor)-8-1] :=%ordered[$cursor-1]
								$loop_cursor := (4*$cursor)-8
						end select
					end if
				case 9
					if ($cursor = 1)
						%loop_buffer[0] := $min_note
						$loop_cursor := 1
					end if
					if ($cursor = 2)
						%loop_buffer[0] := $max_note
						%loop_buffer[1] := $min_note
						$loop_cursor := 2
					end if
					if ($cursor = 3)
						select($repeat)
							case 1
								%loop_buffer[0] := %ordered[0]
								%loop_buffer[1] := %ordered[2]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[2]
								$loop_cursor := 4
							case 3
								%loop_buffer[0] := %ordered[0]
								%loop_buffer[1] := %ordered[2]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[1]
								%loop_buffer[4] := %ordered[2]
								$loop_cursor := 5
							case 2
								%loop_buffer[0] := %ordered[0]
								%loop_buffer[1] := %ordered[2]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[2]
								%loop_buffer[4] := %ordered[0]
								$loop_cursor := 5
							case 5
								%loop_buffer[0] := %ordered[0]
								%loop_buffer[1] := %ordered[2]
								%loop_buffer[2] := %ordered[1]
								%loop_buffer[3] := %ordered[1]
								%loop_buffer[4] := %ordered[2]
								%loop_buffer[5] := %ordered[0]
								$loop_cursor := 6
						end select
					end if
					if ($cursor > 3)
						select ($repeat)
							case 1
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$a]
									%loop_buffer[($a*2)+1] :=%ordered[$a+2]
									inc($a)
								end while
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)] :=	%ordered[$cursor-$a-3]
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=%ordered[$cursor-$a-2]
									inc($a)
								end while
								$loop_cursor := (4*$cursor)-10
							case 3
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$a]
									%loop_buffer[($a*2)+1] :=%ordered[$a+2]
									inc($a)
								end while
								%loop_buffer[($cursor-2)*2] :=%ordered[$cursor-1]
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=	%ordered[$cursor - $a-3]
									%loop_buffer[($a*2)+(($cursor-2)*2)+2] :=%ordered[$cursor - $a-2]
									inc($a)
								end while
								$loop_cursor := (4*$cursor)-9
							case 2
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$a]
									%loop_buffer[($a*2)+1] :=%ordered[$a+2]
									inc($a)
								end while
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)] :=	%ordered[$cursor-$a-3]
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=%ordered[$cursor-$a-2]
									inc($a)
								end while
								%loop_buffer[(4*$cursor)-9-1] :=%ordered[0]
								$loop_cursor := (4*$cursor)-9
							case 5
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a*2)] :=	%ordered[$a]
									%loop_buffer[($a*2)+1] :=%ordered[$a+2]
									inc($a)
								end while
								%loop_buffer[($cursor-2)*2] :=%ordered[$cursor-1]
								$a := 0
								while($a < $cursor-3)
									%loop_buffer[($a*2)+(($cursor-2)*2)+1] :=	%ordered[$cursor - $a-3]
									%loop_buffer[($a*2)+(($cursor-2)*2)+2] :=%ordered[$cursor - $a-2]
									inc($a)
								end while
								%loop_buffer[(4*$cursor)-8-1] :=%ordered[0]
								$loop_cursor := (4*$cursor)-8
						end select
					end if

				case 10 to 13
					$loop_cursor := $cursor
					$a := 0
					while(($a*2) < $cursor)
						%loop_buffer[($a*2)] := %ordered[$cursor -1 -$a]
						%loop_buffer[($a*2)+1] := %ordered[$a]
						inc($a)
					end while
					$loop_cursor := $cursor
					if ($note_order = 11 or $note_order = 13)
						$a := 0
						while($a < $loop_cursor)
							%help_buffer[$loop_cursor - $a-1] := %loop_buffer[$a]
							inc($a)
						end while
						$a := 0
						while($a < $loop_cursor)
							%loop_buffer[$a] := %help_buffer[$a]
							inc($a)
						end while
					end if
					if (($note_order = 12 or $note_order = 13) and $cursor > 2)
						select ($repeat)
							case 1
								$a := 0
								while($a < $cursor-2)
									%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-2-$a]
									inc($a)
								end while
								$loop_cursor := $cursor*2 - 2
							case 2
								if ($note_order = 12)
									$a := 0
									while($a < $cursor-1)
										%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-1-$a]
										inc($a)
									end while
									$loop_cursor := $cursor*2 - 1
								else
									$a := 0
									while($a < $cursor-1)
										%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-2-$a]
										inc($a)
									end while
									$loop_cursor := $cursor*2 - 1
								end if
							case 3
								if ($note_order = 13)
									$a := 0
									while($a < $cursor-1)
										%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-1-$a]
										inc($a)
									end while
									$loop_cursor := $cursor*2 - 1
								else
									$a := 0
									while($a < $cursor-1)
										%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-2-$a]
										inc($a)
									end while
									$loop_cursor := $cursor*2 - 1
								end if
							case 5
								$a := 0
								while($a < $cursor)
									%loop_buffer[($a)+($cursor)] := %loop_buffer[$cursor-1-$a]
									inc($a)
								end while
								$loop_cursor := $cursor*2
						end select
					end if
				case 14
					$loop_cursor := 1
					%loop_buffer[$aa+1] := %ordered[random(0,$cursor-1)]
					%loop_buffer[0] := %ordered[random(0,$cursor-1)]
				case 15
					if ($aa < 2 or $last_order # $note_order)
						$loop_cursor := $cursor
						$a := 0
						while($a < $cursor)
							%help_buffer[$a] := %ordered[$a]
							inc($a)
						end while
						$helper := $cursor
						$a := 0
						while ($a < $cursor)
							%loop_buffer[$a] := %help_buffer[random(0,$helper-1)]
							$bb := 0
							while($bb < $helper)
								if (%help_buffer[$bb] = %loop_buffer[$a])
									while($bb < $helper)
										%help_buffer[$bb] := %help_buffer[$bb+1]
										inc($bb)
									end while
									$bb := $helper+1
									dec($helper)
								end if
								inc($bb)
							end while
							inc($a)
						end while
					end if
				case 16
					$loop_cursor := $cursor
					$a := 0
					while($a < $cursor )
						%loop_buffer[$a] := %note_buffer[$a]
						inc($a)
					end while
			end select
			$last_order := $note_order

					select ($Sync_knob)
						case 0
							$step_length := $DURATION_SIXTEENTH/8
						case 1
							$step_length := $DURATION_SIXTEENTH/4
						case 2
							$step_length := $DURATION_SIXTEENTH/2
						case 3
							$step_length := $DURATION_QUARTER/6
						case 4
							$step_length := ($DURATION_SIXTEENTH/4)*3
						case 5
							$step_length := $DURATION_SIXTEENTH
						case 6
							$step_length := $DURATION_QUARTER/3
						case 7
							$step_length := ($DURATION_SIXTEENTH/2)*3
						case 8
							$step_length := $DURATION_EIGHTH
						case 9
							$step_length := ($DURATION_QUARTER*2)/3
						case 10
							$step_length := $DURATION_SIXTEENTH*3
						case 11
							$step_length := $DURATION_QUARTER
						case 12
							$step_length := ($DURATION_QUARTER*4)/3
						case 13
							$step_length := $DURATION_EIGHTH*3
						case 14
							$step_length := $DURATION_QUARTER*2
						case 15
							$step_length := $DURATION_QUARTER*3
						case 16
							$step_length := $DURATION_QUARTER*4
						case 17
							$step_length := $DURATION_BAR
					end select					
			if ($swing_cursor mod 2 = 0)
				$step_length := $step_length + ($step_length*$Swing)/100
			else
				$step_length := $step_length + ($step_length*(-$Swing))/100			
			end if
			inc($swing_cursor)
			$duration := ($step_length/100)*$dur
			if ($duration < 10000)
				$duration := 10000
			end if
			if ($step_length < 5000)
				$step_length := 5000
			end if
			$velo := 100
			if (%rhythm[$act_step] # 0)
				if ($loop_cursor # 0)
					if ($note_order = 16)
						$a := 0
						while($a < $loop_cursor)
							$note := %loop_buffer[$a] + $oct_cursor*12
							$velo := %velo[%loop_buffer[$a]]
							if ($strike_count > 0)
								$velo := ($velo * $Str_vel)/100
							end if
							if ($velo_button = 1)
								$velo := 127
							end if
							$velo := ($velo * %rhythm[$act_step])/100
							if ($velo > 127)
								$velo := 127
							end if
							if ($velo < 1)
								$velo := 1
							end if
							if ($note > 0 and $note < 128)
								play_note($note,$velo,0,$duration)
							end if
							inc($a)
						end while
						if ($strike_count >= $strike-1)
							$aa := $loop_cursor
						end if
					else
						$note := %loop_buffer[$aa] + $oct_cursor*12
						$velo := %velo[%loop_buffer[$aa]]
						if ($strike_count > 0)
							$velo := ($velo * $Str_vel)/100
						end if
						if ($velo_button = 1)
							$velo := 127
						end if
						$velo := ($velo * %rhythm[$act_step])/100
						if ($velo > 127)
							$velo := 127
						end if
						if ($velo < 1)
							$velo := 1
						end if
						
						if ($note > 0 and $note < 128)
							play_note($note,$velo,0,$duration)
						end if
					end if
				end if
				if ($strike_count < $strike-1)
					dec($aa)
					dec($act_step)
					inc($strike_count)
				else
					$strike_count := 0
				end if
			else

				if ($strike_count < $strike-1)
					dec($act_step)
					inc($strike_count)
				else
					$strike_count := 0
				end if
				dec($aa)
			end if
			inc($aa)
			if ($aa >= $loop_cursor)
				$aa := 0
				if ($octave > 0 )
					inc($oct_cursor)
					if ($oct_cursor > $Octave)
						$oct_cursor := 0
					end if
				end if
				if ($octave < 0 )
					dec($oct_cursor)
					if ($oct_cursor < $Octave)
						$oct_cursor := 0
					end if
				end if
			end if
			inc($act_step)
			if ($act_step >= $steps)
				$act_step := 0
			end if
			wait($step_length)
		end while
		$check_id := 0
	end if
end on

on release
	{only one event per Note}
	if (%EVENT_PAR[0] = 2)
		{ignore_event($EVENT_ID)}
		if (%pressed_id[$EVENT_NOTE] = 0)
			exit
		else
			%pressed_id[$EVENT_NOTE] := 0
		end if
	else
		exit
	end if
	if ($latch_mode = 0)
		exit
	end if
	{which notes should be in the buffer}
	select ($latch_mode)
		case 1
			$a := 0
			$b := $cursor
			$cursor := 0
			while($a < $b)
				if ($EVENT_NOTE # %note_buffer[$a])
					%note_buffer[$cursor] := %note_buffer[$a]
					inc($cursor)
				end if
				inc($a)
			end while
		case 2 to 3
			exit
	end select
end on

on ui_control ($latch_knob)
	$latch_mode := $latch_knob
	select ($latch_mode)
		case 0
			set_knob_label($latch_knob,"Off")
			$a := 0
			while($a < $cursor)
				%note_buffer[$a] := 0
				inc($a)
			end while
			$cursor := 0 
		case 1
			set_knob_label($latch_knob,"On")
			$b := $cursor
			$cursor := 0 
			$a := 0
			while($a < $b)
				if (%pressed_id[%note_buffer[$a]] > 0)
					%note_buffer[$cursor] := %note_buffer[$a]
					inc($cursor)
				end if
				inc($a)
			end while
		case 2
			set_knob_label($latch_knob,"Hold")
		case 3
			set_knob_label($latch_knob,"Hold +-")
	end select
end on

on ui_control ($Sync_knob)
	set_knob_label ($Sync_knob,!tempo_names[$Sync_knob])
end on

on ui_control($edit_Preset)
	if ($edit_Preset < 99)
		{select($edit_Preset)
			case 1
				$a := 0
				while($a < 42)
					%helper_preset[$a] := %preset_arr[(($Preset_knob - 1)*42)+$a ]
					inc($a)
				end while
			case 2
				$a := 0
				while($a < 42)
					%preset_arr[(($Preset_knob - 1)*42)+$a ] := %helper_preset[$a]
					inc($a)
				end while
			case 3
				$a := 0
				while($a < 42)
					%preset_arr[(($Preset_knob - 1)*42)+$a ] := %default_preset[$a]
					inc($a)
				end while
			case 7
				$b := 0
				while($b < 12)
					$a := 0
					while($a < 42)
						%preset_arr[($b*42)+$a ] := %preset_arr[(($Preset_knob - 1)*42)+$a]
						inc($a)
					end while
					inc($b)
				end while
			case 4
				$a := 0
				while($a < 33)
					%helper_rhythm[$a] := %preset_arr[(($Preset_knob - 1)*42)+$a ]
					inc($a)
				end while
			case 5
				$a := 0
				while($a < 33)
					%preset_arr[(($Preset_knob - 1)*42)+$a ] := %helper_rhythm[$a]
					inc($a)
				end while
			case 6
				$a := 0
				while($a < 33)
					%preset_arr[(($Preset_knob - 1)*42)+$a ] := %default_preset[$a]
					inc($a)
				end while
			case 8 
				$a := 0
				while($a < 32)
					if (%preset_arr[(($Preset_knob - 1)*42)+$a ] > 0)
						%preset_arr[(($Preset_knob - 1)*42)+$a ] := random(1,100)
					end if
					inc($a)
				end while
		end select}
		$a := 0
		set_table_steps_shown(%rhythm, $steps)
		$sync_knob := ($Rate_knob * 18) /1000001
		set_knob_defval ($Rate_knob,(5 *1000001) / 17)
		set_knob_label ($Rate_knob,!tempo_names[$sync_knob])
		set_knob_unit($Rate_knob,$KNOB_UNIT_NONE)
			
	end if
	$edit_preset := 100
end on

on ui_control ($steps)
	set_table_steps_shown(%rhythm, $steps)
end on

on ui_control ($note_order)
	if ($note_order # 99)
		$last_note_order := $note_order
	else
		$note_order:= $last_note_order
	end if
end on

on ui_control ($rate_knob)
	
	$sync_knob := ($Rate_knob * 18) /1000001
	set_knob_label ($Rate_knob,!tempo_names[$sync_knob])
		
end on
{END OF SCRIPT}
