{************************************************************* Drum Roll Please Author: Eric von Bayer Email: KSP at ericvonbayer.us Modified: April 28, 2005 Version: 1.0.0 Notes: Please feel free to email me if you have any suggestions or you really find this script useful. Copyright: Copyright (C) 2005 Eric von Bayer, All right's reserved. Use of this script is free unless you use and distribute it as part of commercial sample set. If you use this in a commercial sample set, you must give me a free license of the commercial sample set it is used in. Description: This script will map repetitious drum notes to a drum roll (on a different key) and will trigger a release note on ending the drumroll. **************************************************************} on init { Disable debug output } RESET_CONDITION(debug) declare ui_label $label1 ( 1, 1 ) set_text( $label1, "Threshold:" ) declare ui_menu $threshold_menu add_menu_item( $threshold_menu, "1/64", 64 ) add_menu_item( $threshold_menu, "1/32", 32 ) add_menu_item( $threshold_menu, "1/16", 16 ) add_menu_item( $threshold_menu, "1/8", 8 ) add_menu_item( $threshold_menu, "1/4", 4 ) add_menu_item( $threshold_menu, "1/2", 2 ) $threshold_menu := 32 declare ui_label $label2 ( 1, 1 ) set_text( $label2, "Transpose:" ) declare ui_menu $trans_menu add_menu_item( $trans_menu, "+5 Octaves", 60 ) add_menu_item( $trans_menu, "+4 Octaves", 48 ) add_menu_item( $trans_menu, "+3 Octaves", 36 ) add_menu_item( $trans_menu, "+2 Octaves", 24 ) add_menu_item( $trans_menu, "+1 Octave", 12 ) add_menu_item( $trans_menu, "-1 Octave", -12 ) add_menu_item( $trans_menu, "-2 Octaves", -24 ) add_menu_item( $trans_menu, "-3 Octaves", -36 ) add_menu_item( $trans_menu, "-4 Octaves", -48 ) add_menu_item( $trans_menu, "-5 Octaves", -60 ) $trans_menu := 48 declare ui_label $label3 ( 1, 1 ) set_text( $label3, "Rel Offset:" ) declare ui_knob $rel_off ( 0, 60000, 1 ) $rel_off := 14000 declare ui_label $label4 ( 1, 1 ) set_text( $label4, "Rel Velocity (%):" ) declare ui_knob $rel_vel ( 0, 100, 1 ) $rel_vel := 90 declare ui_label $label5 ( 1, 1 ) set_text( $label5, "Crossover Time:" ) declare ui_label $label6 ( 1, 1 ) add_text_line( $label6, "(% Threshold x 2)" ) declare ui_knob $CrossTime ( 0, 100, 1 ) $CrossTime := 2 move_control( $label1, 1, 1 ) move_control( $threshold_menu, 2, 1 ) move_control( $label2, 1, 2 ) move_control( $trans_menu, 2, 2 ) move_control( $label3, 3, 1 ) move_control( $rel_off, 4, 1 ) move_control( $label4, 3, 1 ) move_control( $rel_off, 4, 1 ) move_control( $label5, 3, 3 ) move_control( $label6, 3, 4 ) move_control( $CrossTime, 4, 3 ) make_persistent( $threshold_menu ) make_persistent( $trans_menu ) make_persistent( $rel_off ) make_persistent( $rel_vel ) make_persistent( $CrossTime ) declare $threshold declare $cross_time_act declare %last_play[256] declare %is_held[256] declare %held_id[256] declare polyphonic $note { Clear out the messages } message( " " ) end on on note { Determine the threshold (in ms) each time because tempos can vary } $threshold := $DURATION_EIGHTH / $threshold_menu / 115 { If the last event was closer to us than the threshold, hold the roll for the threshold length } if( $ENGINE_UPTIME - %last_play[$EVENT_NOTE] < $threshold ) { Mark the time so the next note knows if it's still in a roll } %last_play[$EVENT_NOTE] := $ENGINE_UPTIME { If the note is not held, start a roll note } if( %is_held[$EVENT_NOTE] = 0 ) USE_CODE_IF(debug) message( "Started roll for key " & $EVENT_NOTE & " (" & ... %is_held[$EVENT_NOTE] & ":" & %held_id[$EVENT_NOTE] & ")" ) END_USE_CODE { Kill the original event and begin a roll } ignore_event( $EVENT_ID ) %held_id[$EVENT_NOTE] := play_note( $EVENT_NOTE + $trans_menu, ... $EVENT_VELOCITY, 0, 10000000 ) else USE_CODE_IF(debug) message( "In roll for key " & $EVENT_NOTE & " (" & ... %is_held[$EVENT_NOTE] & ":" & %held_id[$EVENT_NOTE] & ")" ) END_USE_CODE { kill the original event, let the roll continue } ignore_event( $EVENT_ID ) end if { Hold this note for the threshold time and then release it } inc( %is_held[$EVENT_NOTE] ) wait( $threshold * 1000 ) dec( %is_held[$EVENT_NOTE] ) { Kill the roll if there are no more references } if( %is_held[$EVENT_NOTE] = 0 ) USE_CODE_IF(debug) message( "Ended roll for key " & $EVENT_NOTE & " (0:" & ... %held_id[$EVENT_NOTE] & ")" ) END_USE_CODE { Calculate the crossover time in us } $cross_time_act := $DURATION_EIGHTH / $threshold_menu * $CrossTime / 100 * 16 { Fade out the old note and then terminate it } fade_out( %held_id[$EVENT_NOTE], $cross_time_act, 1 ) { Play a new note and fade it in while the other is fading out } $note := play_note( $EVENT_NOTE, $EVENT_VELOCITY * $rel_vel / 100, ... $rel_off, $cross_time_act * 4 ) fade_in( $note, $cross_time_act / 4 ) end if else { This event didn't come in soon enough to trigger a roll, note the time it came in and just play it } %last_play[$EVENT_NOTE] := $ENGINE_UPTIME USE_CODE_IF(debug) message( "Threshold of " & $threshold & " not met (" ... & ($ENGINE_UPTIME - %last_play[$EVENT_NOTE]) & ")" ) END_USE_CODE end if end on