What's new

Same overlapping notes and KEY_DOWN variable

olmerk

Active Member
Simple situation but I can not find the solution…

I have the same two overlapping notes (check out the picture). ORC1 and ORC2 must behave differently as for ORC1 another note is still held, while for ORC2 it’s not.

In order to detect if note is held I use KEY_DOWN built-in variable, which let me down in this case, because it gets equal to zero for both ORC1 and ORC2.

So I’m really puzzled on how it’s possible two distinguish ORC1 from ORC2? Hope I explained it well…

overlap.png
 
I assume this is with the same MIDI note being played, or? What exactly do you want to do in this case?

Yes, it's the same note (EVENT_NOTE). ORC2 must play an instrument's release sound, while ORC1 must not. Also ONC2 kills the sound (id) of previous note, triggered by ONC1.
 
Killing the previous note should be very easy to sort out by having an array that holds event IDs for each key, then kill events with fade_out(). Like so:

Code:
on init
    declare const FADE_TIME := 5
    declare key_ID[128]
end on

on note
    if (event_status(key_id[EVENT_NOTE]) = EVENT_STATUS_NOTE_QUEUE)
        fade_out(key_id[EVENT_NOTE], FADE_TIME * 1000, 1)
    end if
    key_id[EVENT_NOTE] := EVENT_ID
end on
 
Killing the previous note should be very easy to sort out by having an array that holds event IDs for each key

It's not in issue. I mentioned killing as it was already done in my script. The problem is in different actions for ORC1 and ORC2.
 
Maybe store only the most recent EVENT_ID for each note in ONC. Then check if the ORC has the same EVENT_ID ?
 
Maybe store only the most recent EVENT_ID for each note in ONC. Then check if the ORC has the same EVENT_ID ?

Nope, this doesn’t help either. What’s happening is next:

ONC1 generates, say, ev_id1 then ONC2 produces ev_id2. However on ORC1 both ev_id1 and ev_id2 pops up, while ORC2 stays silent and gives no EVENT_ID at all…
 
Killing the previous note should be very easy to sort out by having an array that holds event IDs for each key, then kill events with fade_out(). Like so:

Code:
on init
    declare const FADE_TIME := 5
    declare key_ID[128]
end on

on note
    if (event_status(key_id[EVENT_NOTE]) = EVENT_STATUS_NOTE_QUEUE)
        fade_out(key_id[EVENT_NOTE], FADE_TIME * 1000, 1)
    end if
    key_id[EVENT_NOTE] := EVENT_ID
end on

Thanks! That one is very useful. Would it work to create a set of arrays of event IDs to be used in larger polyphonies? Like if I wanted to be able to play at most 3 events per key at once (4 voices polyphony per key)...

I am thinking like this:

Code:
on init
  declare const $FADE_TIME := 5
  declare %key_ID[128]
    declare %key_ID2[128]
    declare %key_ID3[128]
end on

on note

    {first, check if array 1 is active}
  
    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE)    {if first array is taken, has notes}
        if (event_status(%key_ID2[$EVENT_NOTE]) = $EVENT_STATUS_INACTIVE)  {if so, check if array 2 is empty}
        %key_ID2[$EVENT_NOTE] := $EVENT_ID    {if it is, enter event note as event ID in array 2}
        else
            %key_ID3[$EVENT_NOTE] := $EVENT_ID  {if not, enter event note as event ID into 3rd array}
        end if
    else
        %key_ID[$EVENT_NOTE] := $EVENT_ID   {if first array is free, use it}
    end if

    {if all arrays have information, fade out first array and then enter current note in there}
    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID2[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID3[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE)
        fade_out(%key_ID[$EVENT_NOTE],$FADE_TIME*1000,1)

        { and then perhaps wait another 3 seconds, then fade out the second, then the third? That would be good. }
      
        %key_ID[$EVENT_NOTE] := $EVENT_ID
    end if


    {messages on what´s happening}

    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_INACTIVE)
        message("Friggintastic, first array is free, entering note nr " & $EVENT_NOTE & "´s EVENT_ID in place of EVENT_NOTE! ")
    end if
  
    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID2[$EVENT_NOTE]) = $EVENT_STATUS_INACTIVE)
        message("Events found for key nr " & $EVENT_NOTE & " in first array, so checking 2nd array..")
        wait(2000000)
        message("great, second array is free, entering ID there! ")
    end if

    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID2[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID3[$EVENT_NOTE]) = $EVENT_STATUS_INACTIVE)
        message("Events found for key nr " & $EVENT_NOTE & " in first array, so checking 2nd array..")
        wait(2000000)
        message("nope, still events, going for third array... ")
        wait(2000000)
        message("great, third array is free, entering ID there! ")
    end if

    if (event_status(%key_ID[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID2[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE and event_status(%key_ID3[$EVENT_NOTE]) = $EVENT_STATUS_NOTE_QUEUE)
        message("Events found for key nr " & $EVENT_NOTE & " in first array, so checking 2nd array..")
        wait(2000000)
        message("nope, still events, going for third array... ")
        wait(2000000)
        message("nope... all slots filled, going for a fadeout of last one there... :/ ")
    end if

end on

on release

    message("note off, waiting 3 secs, then fading out all, so you can keep watching the array choices! ")
  
    wait(3000000)
    fade_out(%key_ID[$EVENT_NOTE],$FADE_TIME*10000,1)
    wait(1000000)
    fade_out(%key_ID2[$EVENT_NOTE],$FADE_TIME*10000,1)
    wait(1000000)
    fade_out(%key_ID3[$EVENT_NOTE],$FADE_TIME*10000,1)

  
  
end on


So, the script makes 3 separate arrays. If array 1 is filled, it enters the EVENT_ID of EVENT NOTE (on note) into array 2. If these are both filled, it enters it into array 3. If they are all filled, it fades out array 1.

This is just some of the parts. The fading of 2nd and 3rd arrays if all is filled and the 1st is faded is what would keep the first from always being used past the first 3 events. Havent gotten to that part yet. Perhaps the fade_out is enough in my case (piano with multiple hits), for sustain pedal off events. But for when the pedal is on is the issue here mostly. As more events can build up.
 
If you're using SublimeKSP it already has support for multidimensional arrays. Forget about that 2011 post :)

https://github.com/nojanath/SublimeKSP/wiki/Added-Features


Thanks, I read that this morning on that page, do not understand the concepts really or how to apply it although it looks like concise code, especially after seeing the compiled code. Is there more info on 2D arrays in a list of resources? Have been searching through the items here and other forums.
 
Thanks, I read that this morning on that page, do not understand the concepts really or how to apply it although it looks like concise code, especially after seeing the compiled code. Is there more info on 2D arrays in a list of resources? Have been searching through the items here and oth
If you're using SublimeKSP it already has support for multidimensional arrays. Forget about that 2011 post :)

https://github.com/nojanath/SublimeKSP/wiki/Added-Features

er forums.

Thanks, I read that this morning on that page, do not understand the concepts really or how to apply it although it looks like concise code, especially after seeing the compiled code. Is there more info on 2D arrays in a list of resources? Have been searching through the items here and other forums.

This one has endless possibilities. Not only for arrays of event IDs. In essence, after reeling this one in, one could make release sound script using a multidimensional array with all lengths of all samples in a large "spread sheet" and call upon each note in a specific velocity for a specific sample. The list could be set using bash/shell-script and SoX or something, then creating a list of lists for a perfect release setting for all notes, individually. Would definitely perfect my current release note solution.
 
If you're using SublimeKSP it already has support for multidimensional arrays. Forget about that 2011 post :)

https://github.com/nojanath/SublimeKSP/wiki/Added-Features


Actually, I managed to put together a good basic "virtual 2D" array and call a line into a label/text-box. I used your script and the manual, for other´s references:

Manual, page 20, "% (array)". Your post from 2011, on AudioThing´s thread on "Saving Presets... ":
https://vi-control.net/community/th...ays-and-resource-container.20862/#post-273489

Perhaps this is unnecessary for the OP, olmerk, and for the thread but still, might be useful.

My script does the following:
- adds a 2D array where there are 8 values * 3 lines
- prints each line into a message box, a ui_label element.


Code:
on init
    declare %array_2d[8*3] := (...
        {1}000,001,002,003,004,005,006,007,...
        {2}008,009,010,011,012,013,014,015,...
        {3}016,017,018,019,020,021,022,023)

    declare $r {while inc value for row}
    declare $c {while inc value for col}

    declare ui_label $label3 (3,6)
    set_text ($label3,"Just initiated engine. Press any key to initiate script.")

    declare $cell_number
    $cell_number := 0


end on
on note

    set_text ($label3,"")
  
    $r := 0
    while($r*8 < 24)

        add_text_line($label3, "Row nr " & $r & " (0 based, so nr " & $r+1 & ") in 2D array")

        $c := 0 
        while($c < 8)

            $cell_number := $r*8 + $c     {just the nr of the "cell" or array nr.}

            {Adding one line of text with the array cell number and the value of the cell}
            {Since every "row" has 8 "cells", the "$r" inc()-rement is multiplied by 8 for each row, $r*8 + $c, $c being the cell.}
            add_text_line($label3, "Cell / array nr: " & $cell_number & " in array. Value: " & %array_2d[$r*8 + $c])

        inc($c)
        end while

    inc($r)
    end while

    add_text_line($label3, "That´s it. That´s all it does.")
  
end on


Kontakt-KSP-programming-nested-while-loops-for-retrieving-2D-array-data.png
 
Last edited:
I don't get it... Why don't you just use it like you're supposed to use 2D arrays? sKSP supports that, and on the page I linked to you even have a tidbit of code that showcases how to use them. (https://github.com/nojanath/SublimeKSP/wiki/Added-Features#multidimensional-arrays)

Code:
on init
    declare const X_SIZE := 4
    declare const Y_SIZE := 6

    declare i
    declare j

    declare 2Darray[$X_SIZE, $Y_SIZE]

    { writing to it }
    2Darray[2, 3] := 1000

    for i := 0 to X_SIZE - 1
        for j := 0 to Y_SIZE - 1
            2Darray[i, j] := j * 10
        end for
    end for
end on

Isn't that much nicer to read, and simpler to use?
 
Top Bottom