# Real Note off vs coded note_off?



## robh (Sep 28, 2011)

I'm very new to KSP and I'm trying to write a script that uses a breath controller in a similar way that WIVI treats the breath controller. (retriggering a held note by "tonguing" on the BC, for example.)

I'll go into details later if necessary, but the short question is:

Is there a way to distinguish between a real note off (physically removing your finger from the key) and a "note_off" code in the script?

If there is, It would essentially be the last hurdle (and biggest) to get what I've coded working exactly as I want.

If not, then I guess I'll have to go into more details.

Rob


----------



## polypx (Sep 28, 2011)

Rob,

I don't know the WIVI method, but it depends what you mean by "distinguish".

Within KSP itself, every event has an ID ($EVENT_ID) which is unique. So you can grab the event ID of a note-off generated by MIDI, and treat that differently from a note-off created by the script. (see the KSP manual page for "note_off()")

But a Kontakt Instrument won't respond to these two note-offs differently unless you script it to.

Not sure if this helps or not.

cheers, 
Dan


----------



## robh (Sep 28, 2011)

Thanks. Your information is helpful because what you're saying to me is it somehow can be done - although it is probably more of a pole vault rather than a hurdle!

In a nutshell, this is what I'm trying to do:

1 -play a note, but no breath control (CC#2=0) : nothing is played*EDIT* until CC#2>0
2 -play a note and CC#2 is already >0: note plays.
3 -if the note is held and CC#2 drops to 0: note turns off, but if the note remains to be physically held, then a CC#2>0 will re-trigger the note from the beginning of the sample.

Scenario 3 is the part that I've managed to get working _almost_ the way I want.

BTW, just to clarify for those familiar with WIVI, I am only trying to sort this out for monophonic playing (solo wind/brass instrument). Trying to keep it simple for now.

Here's the script as it is now:

```
on init
    declare  $note_on
    declare   $note_num
    declare  $note_vel
    declare $CC2_on
    $note_on := -1
    $CC2_on :=1
    message (" "){all messages were used for testing purposes}
    
end on

on controller
    if (%CC[2] >0 and $note_on>0 and $CC2_on =0)
        $CC2_on:=1
    end if
    if (%CC[2]=0)
        if ($CC2_on=1)
        note_off($ALL_EVENTS) {I need to do something else here, right?}
        $CC2_on:=0 
        end if  
       $note_on := -1
    end if   
    if (%CC[2]>0 and $note_on=0 and $CC2_on=0)
        play_note($note_num,$note_vel,0,-1)
        $note_on:=1
        $CC2_on :=1        
    end if
    message($note_on)
 end on
  
on note 
   ignore_event($EVENT_ID)
     if ($note_on =-1)
      $note_on:=1
      else
          inc($note_on)
          end if
    $note_num :=$EVENT_NOTE
    $note_vel:=$EVENT_VELOCITY
    while(%CC[2]=0)
                wait(10)
                message($note_on)
            end while
  
       if ($note_on >1)
          set_controller(64,127){switches to legato}
             
            end if
  
           play_note($note_num,$note_vel,0,-1)
          message ($note_on)
          inc($note_on)
     
end on
     


on release
  dec($note_on)
  if ($note_on<=0)
      $note_on:=0
      set_controller(64,0)
  end if
  message($note_on)
  
  
end on
```


----------



## robh (Sep 28, 2011)

Additional info:

I had tried using "$NOTE_HELD" or "%KEY_DOWN" as conditions, but I discovered that executing a note_off code nullifies them - hence the original question.

Rob


----------



## polypx (Sep 28, 2011)

Rob,

I think this is definitely possible, but it's getting late and I haven't gone through your script.

But basically, I can see this:



> 1 -play a note, but no breath control (CC#2=0) : nothing is played*EDIT* until CC#2>0



Use a variable to track the "last note played", this is very simple, especially if you're aiming at mono mode.

But "ignore event" on note, so that nothing is played immediately.



> 2 -play a note and CC#2 is already >0: note plays.



A controller callback:

if CC#2 > 0 
$my_note_ID := play_note ($last_note_played, $last_velocity, etc.... )




> 3 -if the note is held and CC#2 drops to 0: note turns off, but if the note remains to be physically held, then a CC#2>0 will re-trigger the note from the beginning of the sample.



another controller callback:
if CC#2 = 0 
note_off ($my_note_ID)



I realize this isn't written out properly, but the logic makes some sort of sense to me in KSP English.
It *should* work.

Hopefully tomorrow I can have a closer look at your existing script.

cheers
Dan


----------



## robh (Sep 28, 2011)

I just noticed that I need to add another scenario:

After scenario 3, if the key is physically lifted up, then you can no longer trigger the last note played when CC2 > 0 again.

Hm. "$my_note_ID := play_note ($last_note_played, $last_velocity, etc.... ) "
It didn't occur to me you could do something like that. I think that's the missing piece to the puzzle!

Thanks for the suggestions. I'll have to see how I can make it work tomorrow.

Rob


----------



## robh (Oct 4, 2011)

Woohoo! It works! 

Thanks Dan, for steering me in the right direction!

I pretty much started over from scratch and tested things every step of the way.


Here's the final code for those interested in using a breath controller for your wind/brass samples. I'm going to be using this to revive the old Sampletekk "Bigga Orchestra Brass", but I'm sure it could work with other wind/brass libraries as well (with the proper set up).


```
on init
    declare  $note_on
    declare   $original_note_num
    declare $new_note_num
    declare  $original_note_vel
    declare $new_note_vel
    declare $CC2_on
    declare $original_note_ID
    declare  $new_note_ID
    $note_on := 0
    $CC2_on :=0
    message (" "){all messages were used for testing purposes}
    
end on

on controller
    if (%CC_TOUCHED[2] =1)
       if (%CC[2]>0 and $CC2_on =0 and %KEY_DOWN[$original_note_num]=1)
            $new_note_ID := play_note($original_note_num,$original_note_vel,0,-1)
            inc($note_on)
            $CC2_on:=1
        
       end if
        
       if (%CC[2] = 0 and $CC2_on =1)
           note_off($new_note_ID)
           $CC2_on :=0
           end if
          message("Event ID  " &$original_note_ID & "  note ID  "& $new_note_ID &"  note num  " & $original_note_num &"  key down  " & %KEY_DOWN[$original_note_num] & "  note on  " & $note_on & "  CC2  " & %CC[2] & "  CC2 on  " & $CC2_on)

    end if
 end on
  
on note 
   ignore_event($EVENT_ID)
   if ($original_note_ID # $EVENT_ID)
       note_off($original_note_ID)
   end if
   $original_note_ID:=$EVENT_ID
   $original_note_num := $EVENT_NOTE
   $original_note_vel := $EVENT_VELOCITY
   
   
          
           if (%CC[2]>0)
            inc($note_on)
            end if
            if ($note_on>1)
                set_controller(64,127){triggers legato groups}
                $note_on:=1
                
                end if
         if (%CC[2]>0)
          $new_note_ID := play_note($original_note_num,$original_note_vel,0,-1)
         end if
          message("Event ID  " &$original_note_ID & "  note ID  "& $new_note_ID &"  note num  " & $original_note_num &"  key down  " & %KEY_DOWN[$original_note_num] & "  note on  " & $note_on & "  CC2  " & %CC[2] & "  CC2 on  " & $CC2_on)
        
     
end on
     


on release
  if ($EVENT_ID= $new_note_ID)
  dec($note_on)
  end if
  
  if ($EVENT_ID=$original_note_ID and %CC[2]=0)
      $note_on:=0
  end if
 
  if ($note_on =0)
      set_controller(64,0){triggers non-legato groups}
  end if
  message("Event ID  " &$original_note_ID & "  note ID  "& $new_note_ID &"  note num  " & $original_note_num &"  key down  " & %KEY_DOWN[$original_note_num] & "  note on  " & $note_on & "  CC2  " & %CC[2] & "  CC2 on  " & $CC2_on)
  
  
end on
```


----------



## Big Bob (Oct 5, 2011)

Hi Rob,

Are you sure that this script does what you wanted it to do? I haven't taken a lot of time to study it but, it seems to me that there are number of situations that it won't handle 'appropriately'. However, I'm not sure I know what 'appropriately' is for your situation. :lol: 

For example, you didn't specify what you want to happen when multiple overlapping keys are played. But, just to illustrate the kind of thing that I don't think your script will handle properly, try the following:

1. With BC=0, play C60 and hold the key down.
2. Raise BC and of course the note begins to sound.
3. Add key C62 and hold both it and C60 down.
4. Lower BC to zero.
5. Release both C60 and C62.
6. Raise BC and the voice is still sounding. Is this what you want? :? 

Rejoice,

Bob


----------



## robh (Oct 5, 2011)

Funny you should chime in, Bob.  

What I have neglected to mention (and I should have mentioned) is that I'm also using the SIPS legato script in the second script slot. 

I just tested it and it appears the legato script is making my script work properly - or should I say, as I want it to.
With the SIPS script bypassed, it does indeed do the behaviour you listed.

So, for the time being, *anyone wanting to use this BC script should use the SIPS legato script as well.*

Rob


----------



## Big Bob (Oct 5, 2011)

> What I have neglected to mention (and I should have mentioned) is that I'm also using the SIPS legato script in the second script slot.



Ah hah! That of course will make a difference and that's why I qualified my comments by saying that you didn't seem to indicate how you would handle multiple, overlapping notes. 8) 

When I get a little time, I'll look over your script more carefully in the light of following it with a solo-mode-type script. I happen to be in the middle of writing the WIPS scripts (WIPS is the wind-instrument successor of SIPS), and, I was just turning my attention to the breath controller logic so your posting caught my eye.

Rejoice,

Bob


----------



## robh (Oct 5, 2011)

Bob,

If you can use what I've done in your WIPS, then go ahead.

Rob


----------



## Big Bob (Oct 5, 2011)

robh @ Wed Oct 05 said:


> Bob,
> 
> If you can use what I've done in your WIPS, then go ahead.
> 
> Rob



Don't I wish it were that easy :lol: 

Unfortunately, the WIPS context is very complex and the BC logic is much trickier to implement than one might imagine. Most likely I will incorporate the BC logic into the Articulation script where it will also have to deal with natural and TKT variation control and a whole ton of other nifty complications :roll: 

But, thanks for the offer, I know your heart is in the right place. :wink: 

Rejoice,

Bob


----------



## Big Bob (Oct 6, 2011)

Hi Rob,

I took a closer look at your BC script and I have a few thoughts that I'll share with you.

In the past, we have had some problems with the reliability of using -1 for the 4th parameter of the *play_note *function. There are situations in which it can leave notes hanging. This information goes back to the days of K2 but, NI may not have done anything to improve the situation. I don't know this for sure but, since it's easy to turn off generated notes overtly, you might want to consider doing that just to be safe.

Here's a script that uses overt note off control that you may want to examine. This design will run with or without SIPS and it also has a more WIVI-like behavior in that each new note cancels the prior note after about a 2 msec overlap. At least that's how I remember that the EWI behaved. I wasn't sure how you have SIPS setup to use CC64 but I assumed that you want to have CC64 off for the first note of a legato phrase and on for all the 'inside' notes.
**EDITED**
*on init*
``*declare* *const* BC := 2```_{ Breath CC }_
``*declare* *const* LC := 64``_{ Legato Switch CC }_
``*declare* orig_note```_{ originating MIDI note properties }_
``*declare* orig_vel
``*declare* orig_id
``*declare* new_id``````_{ current generated note ID }_
``*declare* new_lastid``_{ prior generated note ID }_
``*declare* lockout`````_{ glitch note lockout timer }_
``message('')
*end on* _{ ICB }_

*on note*
``ignore_event(EVENT_ID)
``*if* ENGINE_UPTIME > lockout``_{ discard 'glitch' notes }_
````note_off(orig_id)```_{ kill any prior orig note }_
````orig_id := EVENT_ID _{ copy played note properties }_
````orig_note := EVENT_NOTE
````orig_vel := EVENT_VELOCITY
````*if* CC[BC] > 0
``````*call* play_new`````_{ generate new note if BC on }_
````*end if*
``*end if*
*end on* _{ NCB }_

*on release*
``*if* EVENT_ID = orig_id
````note_off(new_id)``_{ two lines added for alternate all keys up mode }_
````new_id := 0
````orig_id := 0``_{ clear this since it is used as a flag }_
``*end if*
*end on* _{ RCB }_

*on controller*
``*if* CC_NUM = BC
````*if* CC[BC] > 0* and *new_id = 0* and *orig_id # 0
``````*call* play_new`````
````*end if*
````*if* CC[BC] = 0* and *new_id # 0
``````note_off(new_id)
``````new_id := 0
````*end if*
``*end if*
*end on* _{ ICB }_

*function* play_new
``*if* new_id # 0 _{ inside note of phrase }_
````new_lastid := new_id
````set_controller(LC,127) _{ use offset groups }_
``*else*``````````_{ first note of phrase }_
````set_controller(LC,0)```_{ use normal groups }_
``*end if*
``new_id := play_note(orig_note,orig_vel,0,0)
``*if* new_lastid # 0
````lockout := ENGINE_UPTIME + 2 _{ reject more orig notes for 2+ msec }_
````wait(2000)``_{ overlap prior note for 2msec to emulate WIVI }_
````note_off(new_lastid)
````new_lastid := 0
``*end if*
*end function* _{ play_new }_
I'll try to continue this in the next post because I'm having trouble getting the forum to accept two BB Code snippets in this single post. To be continued... (I Hope) :lol:


----------



## Big Bob (Oct 6, 2011)

Here's the continuation, I hope.

You might also want to consider adding a retrigger feature as illustrated with the following script. This is something I Wish that I had included in SIPS. Having a retrigger option is a natural for wind instrument control. It's usually used to play very convincing trills and such. For example a C to D trill can be played by holding C down and then just oscillating the D key.

**EDITED**
*on init*
``*declare* *const* BC := 2```_{ Breath CC }_
``*declare* *const* LC := 64``_{ Legato Switch CC }_
``*declare* *const* IGNORE_RLS := 1212``_{ note tags }_
``*declare* *const* GENERATED := 1942
``*declare* orig_note```_{ originating MIDI note properties }_
``*declare* orig_vel
``*declare* orig_id
``*declare* new_id``````_{ current generated note ID }_
``*declare* new_lastid``_{ prior generated note ID }_
``*declare* lockout`````_{ glitch note lockout timer }_
``*declare* KeyID[128] := (0)``_{ played note IDs for current phrase }_
``*declare* keys_down```_{ total keys still down for current phrase }_
``*declare* polyphonic duplicate``_{ note tag used when note duplicates occur during phrase }_
``message('')
*end on* _{ ICB }_

*on note*
``ignore_event(EVENT_ID)
``*if* KeyID[EVENT_NOTE] # 0
````duplicate := IGNORE_RLS``_{ This is a duplicate note, simply discard it }_
````exit
``*end if*
``KeyID[EVENT_NOTE] := EVENT_ID
``inc(keys_down) 
``*if* ENGINE_UPTIME > lockout
````orig_id := EVENT_ID
````orig_note := EVENT_NOTE
````orig_vel := EVENT_VELOCITY
````*if* CC[BC] > 0
``````*call* play_new
````*end if*
``*end if*
*end on* _{ NCB }_

*on release*
``*if* duplicate = IGNORE_RLS
````exit``_{ discard duplicate notes during phrase }_
``*end if*
``*if* get_event_par(EVENT_ID,EVENT_PAR_1) # GENERATED``_{ original notes only }_
````KeyID[EVENT_NOTE] := 0
````dec(keys_down)
````*if* EVENT_ID = orig_id``_{ only the latest orig note can retrigger }_
``````*if* keys_down = 0`````_{ end of phrase }_
````````note_off(new_id)```_{ 2 lines added for alternate all keys up mode }_
````````new_id := 0
````````orig_id := 0```````_{ retire orig_note }_
``````*else* _{ retrigger }_
````````GetPriorKey(orig_note)
````````*if* CC[BC] > 0
``````````*call* play_new
````````*end if*
``````*end if*
````*end if*
``*end if*
*end on* _{ RCB }_

*on controller*
``*if* CC_NUM = BC
````*if* CC[BC] > 0* and *new_id = 0* and *orig_id # 0
``````*call* play_new`````
````*end if*
````*if* CC[BC] = 0* and *new_id # 0
``````note_off(new_id)
``````new_id := 0
````*end if*
``*end if*
*end on* _{ ICB }_

*function* play_new
``*if* new_id # 0 _{ inside note of phrase }_
````new_lastid := new_id
````set_controller(LC,127)
``*else*``````````_{ first note of phrase }_
````set_controller(LC,0)
``*end if*
``new_id := play_note(orig_note,orig_vel,0,0)
``set_event_par(new_id,EVENT_PAR_1,GENERATED)``_{ tag note }_
``*if* new_lastid # 0
````lockout := ENGINE_UPTIME + 2 _{ reject more orig notes for 2+ msec }_
````wait(2000)``_{ overlap prior note for 2msec }_
````note_off(new_lastid)
````new_lastid := 0
``*end if*
*end function* _{ play_new }_

*function* GetPriorKey(*pnote*)
``*declare* n
``orig_id := 0
``*for* n := 0 *to* 127```_{ find the prior orig note }_
````*if* orig_id < KeyID[n]
``````orig_id := KeyID[n]
``````*pnote* := n
````*end if*
``*end for*
``_{ this next line is only needed if you want to use the original velocity }_
``orig_vel := get_event_par(orig_id,EVENT_PAR_VELOCITY) 
*end function* _{ GetPriorKey }_



Finally, I'd like to get your input on the subject of all keys up. With a real wind instrument, there is no counterpart to the keyboard's all keys off. So when using a keyboard and BC combination, several choices exist. What you are doing now is essentially requiring that both the keyboard and the BC be active before starting a new note. Then further, you are requiring that both the keyboard and the BC be inactive before the last note terminates. It might be more consistent if lifting the last key would also silence the last note. What do you think? 

To really mimic a real wind instrument, we might define all keys up as some actual note (just like the real instrument) so that whenever the BC activates, a note is always played regardless of whether any keys are depressed. However, I think such a mode will be counterintuitive for keyboard players. I think the two best choices are as you have it now or change the way the last note ends. I'd like to hear your take on this subject.

Rejoice,

Bob

BTW If you want to try the above scripts you will need to copy and paste them into Nils' Editor before you can paste them into K4 (since I used KSE syntax).


----------



## robh (Oct 6, 2011)

Hi Bob,

I've been at my computer only in small chunks of time today, so I will have to give your scripts a try at another time. Re-trigger. Yeah, as I was working on my script I thought that would be cool to do, but I figured I better get one step done at a time! 

What I do have time for is to give you that feedback you asked for.

First of all:


> What you are doing now is essentially requiring that both the keyboard and the BC be active before starting a new note.


Yes, that's correct.



> Then further, *you are requiring that both the keyboard and the BC be inactive before the last note terminates*. It might be more consistent if lifting the last key would also silence the last note. What do you think?


 Actually, with my script (in combination with the SIPS legato script) it works as an either or, unless I'm misunderstanding you? The reason I have BC re-trigger the note that's held is so that the player can be able to somewhat mimick double or triple tonguing if necessary, or even play more like a wind player that repeats notes. (A wind player wouldn't lift his/her fingers off the keys for repeated notes.) As it works now, a keyboard player has a choice in his/her playing style for a particular passage.



> To really mimic a real wind instrument, we might define all keys up as some actual note (just like the real instrument) so that whenever the BC activates, a note is always played regardless of whether any keys are depressed. However, I think such a mode will be counterintuitive for keyboard players


I agree, it is counterintuitive. First, how would you define what note plays when only BC is activated? It also would end up being a cause for additional MIDI editing, because if your performance is not quite right - BC comes before note trigger - then you will have unintentional "grace" notes that you would need to edit out, or do an unecessary re-take.



> I wasn't sure how you have SIPS setup to use CC64 but I assumed that you want to have CC64 off for the first note of a legato phrase and on for all the 'inside' notes.


 You are right in how I want CC64 to behave. I built this instrument with sustain groups and staccato groups to blend in as the attack. The staccato groups are set to trigger only when CC64 is off.

Rob


----------



## Big Bob (Oct 6, 2011)

Hi Rob,



> The reason I have BC re-trigger the note that's held is so that the player can be able to somewhat mimick double or triple tonguing if necessary, or even play more like a wind player that repeats notes.



Oh absolutely, you have to have that feature. It's the 'all keys up situation' I was questioning, see below.



> Actually, with my script (in combination with the SIPS legato script) it works as an either or, unless I'm misunderstanding you?



Ah, I think then we are in accord here. The problem was that I guess I didn't read your script carefully enough and rather relied on how it seemed to behave.

To clarify further, what I am talking about here is how the script behaves after the following.

1. Pressure the BC so that BC>0 and remains there for a while.

2. Play some kind of riff on the keys and leave at least one down.

3. Then, while keeping the BC > 0, release all keys. 

I was suggesting that under these conditions, I thought it would be better if the sound terminated when the last key was lifted, even if the BC was still pressured. However, it appears now that this is probably what you intended all along.

But, yesterday when I tested your script, it seemed to keep the last note sounding until BC=0 also. However, I just retested it and I get a mixed bag. Sometimes lifting the last key terminates the sound and sometimes not. (Probably depending on how clutsy I play a quick riff :lol: ).

In any case, I made the wrong assumption earlier when I posted the scripts. I assumed you wanted the last note to continue sounding (even after all keys were lifted) until the BC=0 condition also occured.

However, it's a simple matter to change this 'end condition' for the scripts I posted so I'll edit them as soon as I post this. Sorry for the confusion.

Rejoice,

Bob


----------



## robh (Oct 6, 2011)

Hi Bob,

Not sure if it makes a difference to your testing, but I had my script in the first slot, and the SIPS legato script in the second slot. (Does the order matter?)

Rob


----------



## Big Bob (Oct 6, 2011)

Oh yes, the order matters but I assumed that SIPS should follow your script. The intermittent behavior might easily have been the result of careless key caressing on my part :lol: Although, since your script doesn't have any overt protection against 'glitch' notes, it might be a good idea to provide such a thing.

Usually, when I test a script that 'spawns child notes', I run my fingers sideways up and down the keyboard rapidly. This often generates very short little notes periodically and it often runs afoul of Kontakt's packet handling machinery. This very often results in hanging notes that never get shut off. If you examine the scripts I posted, you may notice I included some lockout protection for that. This scheme isn't perfect but, it's usually better than nothing. :wink: 

In any case, I edited the posted scripts so they will now terminate the sounding note when either the BC=0 *or* all keys are lifted. However, if you are happy with the performance of your scripts please don't feel any pressure to change anything. I just wanted to point out a few things that you may want to consider.

BTW A while back I decided that keyboard + BC was the best combination for controlling virtual wind instruments so I decided to dump my EWI. But, now when I finish implementing WIPS, I will have no way to test the Wind Controller mode. Do you have a WIVI or EWI? If so, would you like to do some beta testing?

Of course I have no idea when WIPS will be done but probably not for several months yet. :roll: Please let me know if you are interested though.

Rejoice,

Bob


----------



## robh (Oct 6, 2011)

> Do you have a *WIVI* or EWI? If so, would you like to do some beta testing?



Did you mean "BC"?

I use the Yamaha BC3 with a keyboard. I don't have an EWI. And sure! I'd love to help beta test WIPS when it's ready!

Rob


----------



## Big Bob (Oct 7, 2011)

> Did you mean "BC"?



No, I still have my BC3. But WIPS will have an option to run keyboard only, keyboard + BC, and Wind Controller only. That 3rd option assumes it will be driven by a note-producing controller such as an EWI. This mode is intended primarily for live performance. But, since I sold my EWI awhile back, I won't be able to test this mode with the real hardware so to speak.

It's not too important actually because all 3 modes result in the same output from the front-end articulation script. Actually, the WC mode is the simplest because no note processing is required (within the instrument range). The EWI produces a 'one-note-at-a-time' output with a few milliseconds of overlap (when breath is steady) just like the scripts I posted. I assume the other WCs are similar. In the keyboard mode, the note input stream is processed similarly to the scripts I posted except that the BC code is shorted out. And lastly, in the keyboard+BC mode, the note processing is similar to the scripts I posted.

By doing it this way, all three modes produce essentially the same output format so the legato/vibrato scripts all see the same note stream regardless of which of the 3 modes the articulation script is in.

It's just that you originally said you were trying to emulate WIVI-like behavior so I thought perhaps you had a WC as well as a BC. In any case, I'll let you know when I have something ready to test. Meanwhile, why don't you PM me with your email address so I can notify you directly.

Rejoice,

Bob


----------



## ScoringFilm (Oct 7, 2011)

As always Bob; a very elegant bit of coding as the solution. I learn so much from studying your code snippets.

Thanks,

Justin


----------



## robh (Oct 7, 2011)

Hi Bob,

I just tried both scripts. I really like the re-trigger one! Thanks a million! 

Had a few glitches along the way:

I compiled them in Nils KScript Editor and it added a line "$BC := $BC" after each "call play_new" function, which then gave an error message of "constant variable $BC cannot be assigned".

I took the extra lines out and tried them out. Both scripts worked fine until I turned on SIPS. If you play notes overlapped (legato), the last note played gets stuck on. (You did say it should work with SIPS, right?) CC2 on (after being off) does not re-trigger note, lifting finger from key does not turn note off.

Rob


----------



## Big Bob (Oct 8, 2011)

Hi Rob,

I'll recheck the script with SIPS right after I post this response but, I'm almost positive I tried it with SIPS. What version of SIPS legato are you using?

The KSE problem you mentioned has been reported before. There is an option setting 'use automatic workaround for Call bug' that you need to uncheck. With this option checked, the compiler tries to insert NOPs that apparently sometimes erroneously equates a constant to itself. I assume you are using the latest version of Kontakt? If not, you may need to leave this option checked. In that case we'll have to manually edit the script and insert a more appropriate set of NOPs in the KN function bodies.

I'll get back to you after I retry the script with SIPS. Meanwhile, you might post your version numbers for K4, SIPS, and the KSE so we can get on the same page.

Rejoice,

Bob


----------



## Big Bob (Oct 8, 2011)

Hi Rob,

I just rechecked the script with SIPS V151 and everything works as it should.

However, I think I know what the problem is. You are using CC64 to switch legato groups and SIPS will see that as the sustain pedal. Try reassigning the group control CC number to some unused CC. Then edit the script constant LC to match that. I think SIPS sustain pedal logic is interfering.

When I tested here, my BC wasn't hooked up so I changed BC to 11 and used my expression slider instead. I also changed LC to 63 so it wouldn't interfere with SIPS pedal logic.

Let me know if you still can't make it work right.

Rejoice,

Bob


----------



## robh (Oct 8, 2011)

Thanks, Bob.

Changing LC to 63 did the trick (along with the group control, of course!)

Rob


----------



## robh (Oct 8, 2011)

oops. forgot to post my specs.

I'm using Kontakt 4 version 4.2.4.5316, KSE version is 1.4.5, SIPS version is 2.05.

Rob


----------

