Same overlapping notes and KEY_DOWN variable

Discussion in 'KONTAKT: Sampling, Programming & Scripting' started by olmerk, Jun 11, 2018.

  1. olmerk

    olmerk Member

    90
    5
    Nov 1, 2015
    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
     
    KrisY likes this.
  2. EvilDragon

    EvilDragon KSP Wizard

    5,684
    3,539
    May 25, 2010
    Croatia
    I assume this is with the same MIDI note being played, or? What exactly do you want to do in this case?
     
  3. OP
    OP
    olmerk

    olmerk Member

    90
    5
    Nov 1, 2015
    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.
     
  4. EvilDragon

    EvilDragon KSP Wizard

    5,684
    3,539
    May 25, 2010
    Croatia
    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
     
    KrisY likes this.
  5. OP
    OP
    olmerk

    olmerk Member

    90
    5
    Nov 1, 2015
    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.
     
  6. polypx

    polypx Complete Idiot

    843
    52
    Jan 7, 2007
    Maybe store only the most recent EVENT_ID for each note in ONC. Then check if the ORC has the same EVENT_ID ?
     
  7. OP
    OP
    olmerk

    olmerk Member

    90
    5
    Nov 1, 2015
    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…
     
  8. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark
    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.
     
  9. EvilDragon

    EvilDragon KSP Wizard

    5,684
    3,539
    May 25, 2010
    Croatia
    Sure, you could use a 2D array for that. You don't even need multiple arrays for this.
     
    KrisY likes this.
  10. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark
    Great! What does one look like?
     
  11. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark
    To my own last remark: found your old entry. To the issue from 2011 "Saving presets, working with arrays and resource container!". Will study this a little while. Any help on a wax on wax off basic example would look would be greatly appreciated.
     
  12. EvilDragon

    EvilDragon KSP Wizard

    5,684
    3,539
    May 25, 2010
    Croatia
    KrisY likes this.
  13. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark

    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.
     
  14. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark
    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.
     
  15. KrisY

    KrisY Member

    71
    5
    Mar 28, 2018
    Denmark

    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: Feb 11, 2019
  16. EvilDragon

    EvilDragon KSP Wizard

    5,684
    3,539
    May 25, 2010
    Croatia
    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?
     
    KrisY likes this.

Share This Page