Author: Sander
Script Version: 2
Minimum CoyoteMIDI Build: 553
// toggle the ostinato_generator on or off
%ostinato_generator_enabled = !%ostinato_generator_enabled
if !%ostinato_generator_enabled
indicator false default default 49
return
// store the ostinato_generator parameters
%ostinato_generator_pattern_size = ($parameters Size)
%ostinato_generator_pattern_length = ($parameters Length)
%ostinato_generator_basenote_interval = ($parameters BasenoteInterval)
%ostinato_generator_basenote_repeat = ($parameters BasenoteRepeat)
%ostinato_generator_speed = 1 / ($parameters Interval)
// generate a new random pattern
runscript default new_pattern
// prepare some local variables
$steps = (count %ostinato_generator_pattern)
$step = 1
// loop while ostinato_generator is running
while %ostinato_generator_enabled
// show logo indicator to indicate it is running
indicator true R:255,G:0,B:0 0.5 49
// get all the currently held down notes
$held_notes = (heldnotes)
$sorted_notes = (sort (mapkeys ($held_notes)))
$count = (count $held_notes)
// if there are notes held down...
if $count > 0
// if the current step has exceeded the amount of steps in the pattern, reset the step
if $step > $steps
$step = 1
// get the pattern note at the current step
$item = (%ostinato_generator_pattern $step)
// if there are less notes held down than the pattern note to be played, use the highest held down note instead
if $item > $count
$item = $count
// print the text that visualizes the pattern being arpeggiated (only for debugging!
// print (runscript default generate_text_representation step:$step,held_notes:$sorted_notes)
// get the actual note number to play from the pattern note number
$note = ($sorted_notes $item)
// get the velocity that this note was pressed with
$velocity = ($held_notes $note 1 velocity)
// if the pattern step is the first one or the halfway one, boost the velocity slightly to support the rythm
if $step == 1 || $step == %ostinato_generator_pattern_length / 2 + 1
$velocity = $velocity * 1.2
// If the note is a forced root note, play it at a lower velocity instead
else if (mod $step %ostinato_generator_basenote_interval) < %ostinato_generator_basenote_repeat
$velocity = $velocity / 2
// play the midi note, perform a rest, and release the note
midi note $note $velocity true
rest %ostinato_generator_speed
midi note $note 0 true
$step + 1
// if there are no notes held down, reset the step
else
$step = 1
rest %ostinato_generator_speed
// this generates a new pattern at a different trigger than starting the script, allows for changing the pattern while the ostinato_generator is playing
script new_pattern private
%ostinato_generator_pattern new list
$step = %ostinato_generator_basenote_repeat
repeat %ostinato_generator_pattern_length
// if configured, play the lowest note of the pattern every time at this interval
if %ostinato_generator_basenote_interval > 0 && (mod $step %ostinato_generator_basenote_interval) < %ostinato_generator_basenote_repeat
%ostinato_generator_pattern + 1
else
$min = 1
// avoid using the forced root note whenever a random not forced note is generated
if %ostinato_generator_basenote_interval > 0
$min = 2
%ostinato_generator_pattern + (random $min %ostinato_generator_pattern_size true)
$step + 1
// for debugging purposes. laggy!
script generate_text_representation private
$text = "Pattern:"
$i = 1
repeat %ostinato_generator_pattern_length
$j = (%ostinato_generator_pattern $i)
if $i == $step
$text = $text " >$j"
else
$text = $text" $j"
$i + 1
$text = $text " | Notes: ${held_notes}"
return $text
// any note pressed down while the ostinato_generator is playing should be canceled
event midi note
if %ostinato_generator_enabled
return true
// sustain should not be passed through as it is used to hold the chord in the ostinato_generator
event midi controlchange 64
if %ostinato_generator_enabled
return true
event startup
%ostinato_generator_enabled = false
event uirefreshed
translationparameter Size (numberbox "Note Size" "The amount of different notes that may occur in the pattern." 5 default false 1 128 1)
translationparameter Length (numberbox "Pattern Length" "The amount of notes that the pattern should contain before repeating itself" 32 default false 1 default 1)
translationparameter BasenoteInterval (numberbox "Root Interval" "The interval at which the pattern should be forced to play the root note instead of a random note" 2 default false 1 default 1)
translationparameter BasenoteRepeat (numberbox "Root Repeat" "The amount of times that the Root Interval should be repeated when played." 1 default false 1 default 1)
translationparameter Interval (numberbox Interval "The interval of each note being played. For example: 4 for quarter notes." 16 default false 1 128 4)
6 downloads