# Sustain pedal function on a polyphonic arpeggiator loop



## nosfoe (Sep 8, 2017)

Hi everyone,
I have an instrument that uses a complex polyphonic arpeggiator (using a while-loop and wait, triggering all kinds of midi-notes and changes to notes) and I would like to implement a traditional sustain pedal function that acts on the arpeggiator: Keep the loops running even when you release the fingers from the keyboard if the sustain pedal is pressed. And if you release 3 fingers, but leave 2 fingers on the keys, then the loops of those 2 notes should continue playing even after releasing the sustain pedal - sounds pretty basic, but it's more tricky than I thought... 

My 1st thought was: It's simple, register the note numbers of all midi-notes that are tiggered between the moment of activating and deactivating the sustain pedal, compare these to the notes that are still pressed when deactivating the pedal and then simply tell the arpeggiator-loops of all notes that were playing but are not pressed anymore to stop, via a stop_loop-variable. 
But here's the catch: I don't think I can "reach" the relevant polyphonic loops any more since you can only address polyphonic events from either the note or release CB! 

Before I give up on this: Does anyone know of a way to address polyphonic events individually, for example by using the event ID? Maybe am just not thinking straight and missing something really obvious?

Thanks!


----------



## Lindon (Sep 11, 2017)

well your arpeggiator notes will have ids so address those?


----------



## nosfoe (Sep 11, 2017)

Hi Lindon, thanks for the reply!
stopping the notes themselves is not the issue, that's all working fine. What I'm looking for is a way to stop individual looped (polyphonic) delay lines that are running. So far I have used a polyphonic stop_loop variable that's set to 1 and stops the correct loop, because I only stopped the loop on a key-release so far - works like a charm because the polyphonic variable in the release callback "knows" which event originally triggered it. 
What I now want to do is stopping an individual looped delay line independent of the release callback, so if I'm not mistaken a simple polyphonic variable won't help here.

But I've been thinking of a way to do it: I think I could make the stop_loop variable an array of 127 elements so that every key on the keyboard has a designated spot in this array instead of a polyphonic variable that's controlling its stop/don't stop behavior. That should work because only 1 delayline per midinote is possible in the instrument. Haven't tried it yet, but I'll report back whether it works...


----------



## Lindon (Sep 12, 2017)

So if I understand you right you have a bunch of notes you would like to stop, independent of key activity or RCB?

If so first thing I would do is collect the note ids in each of your "delay lines" using set_event_mark - you can have up to 28 groups...

When I wanted to "end" this set of notes I'd simply 

fade_out(by_mark($MARK_1),$some_fade_time,0)


----------



## nosfoe (Sep 12, 2017)

No, as I said above, stopping the notes is no problem. I register all notes that are playing anyway, so fading them out if needed is something that I'm doing already (for custom voice-stealing for example). What I needed was a way to stop individual (as in: not always all of them) running polyphonic delay-lines/ loops, because otherwise that loop continues to run and triggers new notes. 
I now implemented the method I described above and it works just fine, its actually quite simple and easy to manage. It works even with more than one delay-line per midi-note by the way - you can keep firing new arpeggiator loops while holding down the sustain pedal and they all stack up and keep running until you release the sustain pedal. So if anyone is interested: this worked!

Thanks for your replies Lindon!


----------



## Lindon (Sep 14, 2017)

I have no idea then what a "delay line" is in this context - I suggest next time you post your code so we can all be on the same page.


----------



## nosfoe (Sep 15, 2017)

Okay, point taken. Code will clarify things, yes. 
What I meant by delay line/ loops here is a while-loop with a wait that triggers midi-notes in regular intervals, like this (the real code is far too much to paste, and it wouldn't make things clearer so I use a simplified example): 


```
on init
    declare polyphonic $a
    declare polyphonic $keep_loop_running
    declare $num_steps := 8
    declare $wait_time := 200000
end on


on note
    $a := 0
    $keep_loop_running := 1
    while ($a < $num_steps and $keep_loop_running = 1)
        {trigger and change all kinds of stuff}
        message ("step counter: " & $a)

        wait ($wait_time)
        inc ($a)
        $a := $a mod 8   
    end while
end on


on release
    $keep_loop_running := 0
end on
```


----------



## Lindon (Sep 18, 2017)

Well then this is exactly what I originally thought it was at the start, so like this:


```
on init
    declare polyphonic $a
    declare polyphonic $keep_loop_running
    declare $num_steps := 8
    declare $wait_time := 200000
    declare ui_button $all_off
    declare $note_id
end on

on ui_control($all_off)
    $keep_loop_running := 0
    fade_out(by_marks($MARK_1),1000000,0)
end on

on note
    $a := 0
    $keep_loop_running := 1
    while ($a < $num_steps and $keep_loop_running = 1)
        {trigger and change all kinds of stuff}
        $note_id := play_note(random(60,72),100,0,$DURATION_QUARTER)
        set_event_mark($note_id,$MARK_1)
        message ("step counter: " & $a)

        wait ($wait_time)
        inc ($a)
        $a := $a mod 8   
    end while
end on
```


----------



## nosfoe (Sep 21, 2017)

Hi Lindon,
just saw that you replied, thanks for that again.
Just to clarify: I guess you missed the fact that $keep_loop_running is a POLYPHONIC variable in my original script example. So in your altered version, hitting the button "$all_off" fades out all notes that are currently running, but the while-loop continues to run and triggers new notes until you hit the panic button. It doesn't stop the loop at all, because the connection between the original polyphonic event that triggered the loop is only retained in the on-note and release CB (afaik).
What I needed to do was being able to choose WHICH while loop to stop and which ones to keep running, depending on which key is still pressed when releasing the sustain pedal. And the method I laid out above turned out to work:

_But I've been thinking of a way to do it: I think I could make the stop_loop variable an array of 127 elements so that every key on the keyboard has a designated spot in this array instead of a polyphonic variable that's controlling its stop/don't stop behavior._

It's something along these lines:


```
on init
    declare polyphonic $a
    declare %keep_loop_running[128] {changed this into an array that can hold all midi note numbers}
    declare $num_steps := 8
    declare $wait_time := 200000
    declare ui_button $all_off
    declare $note_id
end on


on ui_control($all_off)
    {find out which loops need to be turned off and set the value in...
       the array %keep_loop_running[Note-number] to zero - this will...
       turn off only the loops that you CHOOSE to turn off}
end on


on note
    $a := 0
    %keep_loop_running[$EVENT_NOTE] := 1
    while ($a < $num_steps and %keep_loop_running[$EVENT_NOTE] = 1)
        {trigger and change all kinds of stuff}
        $note_id := play_note($EVENT_NOTE,100,0,$DURATION_QUARTER)
        message ("step counter: " & $a)

        wait ($wait_time)
        inc ($a)
        $a := $a mod 8 
    end while
end on
```


----------

