on init
declare $firstnote := (0) - переменная первой ноты из двух, участвующих в легато
declare $lastnote - переменная второй ноты из двух, участвующих в легато
declare $interval - переменная расстояния между двумя нотами в полутонах
declare $firstnote_id - переменная для сохранения ID сыгранной ноты (нужна для корректного релиза при легато)
declare %posintervalgrp [2] := (0,2) - массив с номерами групп для различных скачков вверх (каждая ячейка - полутон) в моем случае, это первая группа для полутонового скачка и третья группа для скачка на тон, но в связи с нумерацией групп 0,1,2, их номера - 0 (первая) и 2 (третья)
declare %negintervalgrp [2] := (4,5) - такой же массив для скачков вниз
end on
on note
ignore_event ($EVENT_ID) - игнорируем воспроизведение чего-либо, дабы не вносить путаницы
disallow_group ($ALL_GROUPS) - отключаем все группы
$lastnote := $EVENT_NOTE - присваиваем этой ноте положение последней ноты
if ($firstnote # 0) - если это не первое нажатие, или переменная слева не обнулялась в калбеке release,
$interval := $lastnote - $firstnote - вычисляем интервал, путем отнимания значения переменной, которая присваевается ноте в конце цикла, от значения, только что присвоенного ей при нажатии
end if
if ($interval >0) - если интервал положительный
note_off ($firstnote_id) - выключаем ноту, сыгранную предыдущей, предполагая, что вы ее не отпустили
allow_group (%posintervalgrp [$interval-1]) -подключаем группу, соответствующую нашему интервала, из массива с позитивными интервалами (не забываем от реального интервала отнять значение 1, теряющееся при присвоении номера ячейки в массиве при нумерации от ноля)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0) -инграем нашу ноту группой с легатными сэмплами (не забываем славить сэмплы на ту ноту, к которой идет скачек, а не от которой)
disallow_group ($ALL_GROUPS) - выколючаем группы
wait (500) - ждем примерное время проигрывания нашего скачка (и это костыль, надо что-то с ним сделать в идеале)
allow_group (1) - включаем группу sustain (в моем случае вторая (1))
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,-1)- играем сустейн
end if
if ($interval <0) - аналогичный цикл, только для скачков вниз
note_off ($firstnote_id)
allow_group (%negintervalgrp [-$interval -1]) - не забываем, что интервалполучился отрицательный, для выбора корректной группы значение надо инвертировать
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,-1)
disallow_group ($ALL_GROUPS)
wait (1000)
allow_group (1)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,-1)
end if
if ($interval = 0) - если интервал не присваивался, то-есть, нота берется в первый раз или после полноценного релиза, играем сустейн
allow_group (1)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,-1)
end if
(это конец цикла, здесь нужно обнулить нужные переменные, и присвоить значения другим)
$interval :=0
$firstnote := $EVENT_NOTE - теперь мы можем присвоить значение этой переменной, чтобы следующий цикл при легато заработал
$firstnote_id := $EVENT_ID - присваеваем значение для корректного релиза
end on
on release
$firstnote :=0 - обнуляем значение. Очень важно понимать, зачем: при релизе во время цикла легато значение обнуляется уже после присвоения значения интервалу, но при релизе ноты без легато, мы даем понять, что легато не тригируется, и следующая нота будет взята сустейном, т.к. интервал будет равен 0
disallow_group ($ALL_GROUPS) - выключаем группы
if ($interval = 0) - если перед релизом было присвоено значение интервалу - нота просто заглушится, если не было - прозвучит сэмпл релиза
allow_group (3) - группа с сэмплами релиза
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0) - нота релиза
end if
end on