1. IMPORTANT:
    We launched a new online community and this space is now closed. This community will be available as a read-only resources until further notice.
    JOIN US HERE

Solved Parallel while loops in note callback

Discussion in 'Scripting Workshop' started by Reid115, Oct 27, 2021.

  1. Reid115

    Reid115 NI Product Owner

    Messages:
    40
    How can I create two simultaneous while loops in the NCB (e.g., two threads)? Basically, when a key is pressed, my NCB ignores the event and instead runs a while loop to continuously retrigger the note with play_note(). I want this retriggering to fade in by incrementally calling change_vol() on the mark group of the retriggering notes. This itself would require another while loop running simultaneous to the retriggering loop. It's specifically a challenge with fading in. I actually have it working perfectly for fading out the notes, because the change_vol() while loop is placed in the release call back. So the notes are still being retriggered in the NCB while the fadeout occurs in the RCB (two threads). But fadeins occur on the key press, not the key release, so both processes occur in the NCB. Any creative ideas for achieving the fadein?
     
    Last edited: Oct 27, 2021
  2. Reid115

    Reid115 NI Product Owner

    Messages:
    40
    Managed to figure it out. Basically I merged the two while loops, and the wait duration at the end of the loop is either the remaining note duration or the remaining time until the next fadein increment, whichever is smaller. Here's the relavent code from the NCB in case anyone wants to do something similar:
    Code:
    on note
        ignore_event($EVENT_ID)
        $callback_id := $NI_CALLBACK_ID
      
        ...
      
        $this_mark := %marks[$active_idx]
        change_vol(by_marks($this_mark), -200000, 1)
        fade_out(by_marks($this_mark), 4000, 1)
        %active_keys[$active_idx] := $EVENT_ID
        set_event_mark($EVENT_ID, $this_mark)
        set_event_par($EVENT_ID, $EVENT_PAR_0, $this_mark)
        set_event_par($EVENT_ID, $EVENT_PAR_1, $active_idx)
        set_event_par($EVENT_ID, $EVENT_PAR_2, 0)
      
        $looping := 1
        $nv := 3
        set_event_par($EVENT_ID, $EVENT_PAR_VOLUME, -49554)
        while ($looping = 1 and search(%active_keys, $EVENT_ID) # -1)
            if ($duration = 0)
                $duration := $size * 1000
                $new_id := play_note($EVENT_NOTE, $EVENT_VELOCITY, $pos, $duration)
                if ($sample_mode = 0)
                    dont_use_machine_mode($new_id)
                end if
                change_vol($new_id, get_event_par($EVENT_ID, $EVENT_PAR_VOLUME), 1)
                change_tune($new_id, get_event_par($EVENT_ID, $EVENT_PAR_TUNE), 1)
                change_pan($new_id, get_event_par($EVENT_ID, $EVENT_PAR_PAN), 1)
                set_event_mark($new_id, $this_mark)
                set_event_par($new_id, $EVENT_PAR_0, $this_mark)
            end if
          
            if ($nv > 200)
                wait($duration)
                $duration := 0
            else
                if ($fadein_wait = 0)
                    { $EVENT_ID in mark group, new events inherit volume from $EVENT_ID }
                    if (get_event_par($EVENT_ID, $EVENT_PAR_2) = 0) { if key hasn't been released yet }
                        change_vol(by_marks($this_mark), real_to_int(56000.0 / pow(int_to_real($nv), 1.6)), 1)
                        inc($nv)
                    else
                        $nv := 201
                    end if
                    $fadein_wait := $in / 200
                end if
              
                if ($fadein_wait < $duration)
                    wait($fadein_wait)
                    $duration := $duration - $fadein_wait
                    $fadein_wait := 0
                else
                    wait($duration)
                    $fadein_wait := $fadein_wait - $duration
                    $duration := 0
                end if
            end if
        end while
    end on
    And the RCB for the fadeout:
    Code:
    on release
        wait(100)
        if (get_event_par($EVENT_ID, $EVENT_PAR_SOURCE) = -1 and search(%active_keys, $EVENT_ID) # -1)
            set_event_par($EVENT_ID, $EVENT_PAR_2, 1)
          
            ...
          
            { fade out key grains }
            $this_mark := get_event_par($EVENT_ID, $EVENT_PAR_0)
            $rv := 1
            while ($rv <= 100 and search(%active_keys, $EVENT_ID) # -1)
                { $EVENT_ID in mark group, new events inherit volume from $EVENT_ID }
                change_vol(by_marks($this_mark), -250 - ($rv * $rv * $rv / 95000 * $rv), 1)
                wait($out / 100)
                inc($rv)
            end while
          
            { kill the inaudible grains }
            $looping := 0
            stop_wait($callback_id, 1)
            if (search(%active_keys, $EVENT_ID) # -1)
                fade_out(by_marks(get_event_par($EVENT_ID, $EVENT_PAR_0)), 1000, 1)
                %active_keys[get_event_par($EVENT_ID, $EVENT_PAR_1)] := 0
            end if
        end if
    end on
    Note that all of the vars are polyphonic.