# Key repeater



## Vladinir (Aug 2, 2013)

Greetings. I want to make a repeater (as Chris Hein Horns for example), but nothing happens. Help me, please.

on init
declare $ham_note
declare $rep_note
declare const $repeater_key_first := 36
declare const $repeater_key_second := 38
set_key_color ($repeater_key_first, 3)
set_key_color ($repeater_key_second, 3)
declare $rep_key
declare $harmony_velocity
end on

on note
$ham_note := $EVENT_NOTE
$rep_note := get_event_par($EVENT_ID,$EVENT_PAR_NOTE)
select (get_event_par($EVENT_ID,$EVENT_PAR_NOTE))
case $repeater_key_first to $repeater_key_second
$harmony_velocity := $EVENT_VELOCITY
$rep_key := play_note($rep_note,$harmony_velocity,0,-1) 
end select
end on

Thanks in advance.


----------



## Big Bob (Aug 2, 2013)

Hi Vladinir,

Your code (in a very clumsy way) will only generate a duplicate note for each note played in the range from 36 to 38. I'm not familiar with what a Chris Hein Horn's repeater is but I doubt that its this.

Could you define more clearly what you are trying to do (apart from relating it to CHH)?

Rejoice,

Bob


----------



## Vladinir (Aug 3, 2013)

No. This is not it. I tried it reposed, to make it clear that I want. Thank you.


----------



## mk282 (Aug 3, 2013)

You do know that among the factory scripts you have a Retrigger script (in Performance subfolder within Script Editor presets menu)? Use it.


----------



## Raptor4 (Aug 3, 2013)

mk282 @ Sat Aug 03 said:


> You do know that among the factory scripts you have a Retrigger script (in Performance subfolder within Script Editor presets menu)? Use it.


It is in the Preset -> Factory -> Sequencing -> "Retrigger" - forgive me if I'm wrong :D 
But, there is a major script design problem... The "Rate" knob parameter can not update the "duration" values in real time if you play & hold a note and try to tweak the "Rate" knob (it works if you release the key and retrigger it). It is essential for such code in cases when you want to Midi learn the "Rate" knob and control the rate in real time.
The solution is simple - I just moved/nested the "Select ($Tempo_menu) code part into the "while" loop.
As a whole the code can be much optimized but it is not important...
Here is the "Rate" updated code:


```
{*******************************************
Retrigger
Author: Native Instruments
Written by: Nicki Marinic
Modified: July 30, 2009
Updated: August 4, 2013 by www.audiogrocery.com
*************************************************}

on init
	
	set_script_title("Retrigger")
	set_ui_height(2)
	message("")
	
	declare $duration
	
	declare const $Tempo_label_X := 4
	declare const $Tempo_label_Y := 2
	declare const $Tempo_knob_X := 3
	declare const $Tempo_knob_Y := 2
	
	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_label $tempo_label (1,1)
	set_text ($tempo_label,"Tempo Sync:")
	move_control ($tempo_label,$Tempo_label_X,$Tempo_label_Y)
	set_control_help ($tempo_label,"Tempo Sync: Choose whether the tempo is free or synced to the master clock.")
	
	declare ui_menu $Tempo_menu
	add_menu_item ($Tempo_menu,"Free",0)
	add_menu_item ($Tempo_menu,"Sync",1)
	move_control ($Tempo_menu,$Tempo_label_X,$Tempo_label_Y+1)
	make_persistent ($Tempo_menu)
	set_control_help ($Tempo_menu,"Tempo Sync: Choose whether the tempo is free or synced to the master clock.")
	
	declare ui_knob $Free_knob (1,1000,1000)
	set_knob_unit($Free_knob,$KNOB_UNIT_MS)
	set_knob_defval ($Free_knob,500)
	$Free_knob := 500
	set_text ($Free_knob,@knob_name)
	make_persistent ($Free_knob)
	set_control_help ($Free_knob,@knob_name & " (Free): Adjust the tempo in miliseconds, regardless of the master clock.")
	
	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)
	set_control_help ($Sync_knob,@knob_name & " (Sync): Adjust the tempo in rhythmical values, synced to the master clock. T stands for triplet.")
	
	declare ui_label $beat_label (1,1)
	set_text ($beat_label,"Beat multiplied by:")
	set_control_help ($beat_label,"Sync (Beat): Adjust the tempo in fractions/multiples of one beat, synced to the master clock. <0.25> equals a 16th, <0.75> a dotted 8th, <2.5> two quarter notes and an 8th, <0.2> a quintuplet etc.")
	
	$Tempo_menu := 1
	move_control ($Sync_knob,$Tempo_knob_X,$Tempo_knob_Y)
	move_control ($Free_knob,0,0)
	move_control ($beat_label,0,0)
	
	_read_persistent_var($Sync_knob)
	set_knob_label ($Sync_knob,!tempo_names[$Sync_knob])
	
	_read_persistent_var($Tempo_menu)
	select ($Tempo_menu)
		case 0
			move_control ($Sync_knob,0,0)
			move_control ($Free_knob,$Tempo_knob_X,$Tempo_knob_Y)
			move_control ($beat_label,0,0)
		case 1
			move_control ($Sync_knob,$Tempo_knob_X,$Tempo_knob_Y)
			move_control ($Free_knob,0,0)
			move_control ($beat_label,0,0)
	end select
	
end on

on ui_control ($Tempo_menu)
	select ($Tempo_menu)
		case 0
			move_control ($Sync_knob,0,0)
			move_control ($Free_knob,$Tempo_knob_X,$Tempo_knob_Y)
			move_control ($beat_label,0,0)
		case 1
			move_control ($Sync_knob,$Tempo_knob_X,$Tempo_knob_Y)
			move_control ($Free_knob,0,0)
			move_control ($beat_label,0,0)
	end select
end on

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

on note
	ignore_event ($EVENT_ID)
	while ($NOTE_HELD = 1)
         select ($Tempo_menu)
		case 0 {Free}
			$duration := $Free_knob * 1000
		case 1 {Sync}
			select ($Sync_knob)
				case 0
					$duration := $DURATION_SIXTEENTH/8
				case 1
					$duration := $DURATION_SIXTEENTH/4
				case 2
					$duration := $DURATION_SIXTEENTH/2
				case 3
					$duration := $DURATION_QUARTER/6
				case 4
					$duration := ($DURATION_SIXTEENTH/4)*3
				case 5
					$duration := $DURATION_SIXTEENTH
				case 6
					$duration := $DURATION_QUARTER/3
				case 7
					$duration := ($DURATION_SIXTEENTH/2)*3
				case 8
					$duration := $DURATION_EIGHTH
				case 9
					$duration := ($DURATION_QUARTER*2)/3
				case 10
					$duration := $DURATION_SIXTEENTH*3
				case 11
					$duration := $DURATION_QUARTER
				case 12
					$duration := ($DURATION_QUARTER*4)/3
				case 13
					$duration := $DURATION_EIGHTH*3
				case 14
					$duration := $DURATION_QUARTER*2
				case 15
					$duration := $DURATION_QUARTER*3
				case 16
					$duration := $DURATION_QUARTER*4
				case 17
					$duration := $DURATION_BAR
			end select				
	end select
		play_note ($EVENT_NOTE, $EVENT_VELOCITY, 0,$duration)
		wait ($duration)
	end while
end on

{END OF SCRIPT}
```

Regards
_____________________
www.audiogrocery.com


----------



## Vladinir (Aug 4, 2013)

Thank You, Raptor4. My English is very bad. and it's hard to explain. But I'll try.
I have two keyswithes C1 :=36 and D1 :=38. I hit a note for example (F3)
(in_range($EVENT_NOTE,$Key_Min,$Key_Max)), than I push keyswich C1 or D1 and they repeat the same note (F3) or another I clicked before. Hopefully now you understand me.
Best Regards.


----------



## mk282 (Aug 4, 2013)

Oh. In that case:


```
on init
    declare const $MIN_NOTE := 48
    declare const $MAX_NOTE := 84

    declare $prev_note

    make_persistent($prev_note)

    set_key_color(36,$KEY_COLOR_YELLOW)
    set_key_color(38,$KEY_COLOR_YELLOW)

    message("")
end on

on note
    if (($EVENT_NOTE = 36) or ($EVENT_NOTE = 38))
        ignore_event($EVENT_ID)
        play_note($prev_note,$EVENT_VELOCITY,0,-1)
    else
        if (in_range($EVENT_NOTE,$MIN_NOTE,$MAX_NOTE))
            $prev_note := $EVENT_NOTE
        end if
    end if
end on
```

That should do it. You will be able to repeat the last played note within the range defined by $MIN_NOTE and $MAX_NOTE with C1 and D1.


----------



## Vladinir (Aug 4, 2013)

Thanks a lot. And last question. I'd like, when I push note 36 or 38, note in_range($EVENT_NOTE,$MIN_NOTE,$MAX_NOTE) will be stopped.
Thank You.


----------



## Raptor4 (Aug 4, 2013)

Vladinir @ Sun Aug 04 said:


> I'd like, when I push note 36 or 38, note in_range($EVENT_NOTE,$MIN_NOTE,$MAX_NOTE) will be stopped.


Hi Vladimir,
I just created some complex code based on the Mario's and your new requirement. 
Copy it, set the KS1 & KS1 boxes to C1 and D1 or what else. Set the Min & Max performance range, save and reopen your instrument. 


```
on init
  message("")
  make_perfview
  declare $i
  declare ui_value_edit $KS1(0, 127, 0) 
  make_persistent($KS1)
  read_persistent_var($KS1)
  declare ui_value_edit $KS2(0, 127, 0) 
  make_persistent($KS2)
  read_persistent_var($KS2)
  declare ui_value_edit $Min(0, 127, 0) 
  make_persistent($Min)
  declare ui_value_edit $Max(0, 127, 0) 
  make_persistent($Max)
  declare $prev_note
  make_persistent($prev_note)
  set_key_color($KS1,$KEY_COLOR_CYAN)
  set_key_color($KS2,$KEY_COLOR_CYAN)
end on

on ui_control($KS1)
  $i := 0
  while ($i<=127)
    if ($i # $KS1 and ($i # $KS2))
      set_key_color($i,$KEY_COLOR_NONE)
    else
      set_key_color($i,$KEY_COLOR_CYAN)
    end if
    inc($i)
  end while
end on

on ui_control($KS2)
  $i := 0
  while ($i<=127)
    if ($i # $KS1 and ($i # $KS2))
      set_key_color($i,$KEY_COLOR_NONE)
    else
      set_key_color($i,$KEY_COLOR_CYAN)
    end if
    inc($i)
  end while
end on

on note
  if ($EVENT_NOTE=$KS1 or ($EVENT_NOTE=$KS2))
    fade_out($ALL_EVENTS,10000,1)
    ignore_event($EVENT_ID)
    play_note($prev_note,$EVENT_VELOCITY,0,-1)
  else
    if (in_range($EVENT_NOTE,$Min,$Max))
      $prev_note := $EVENT_NOTE
    end if
  end if
end on
```
Regards,
____________________
www.audiogrocery.com


----------



## Vladinir (Aug 4, 2013)

Thank You so much. I think it will suit me. You are the best!
Best Regards!!!
Vladinir.


----------

