# Vibrato Script and On Controller



## Mike Greene (Dec 14, 2010)

I'm writing a vibrato script that addresses both pitch and tone. I don't want to use an ordinary LFO because that's not what a voice's vibrato really looks like.

I'm using the set_engine_par($ENGINE_PAR_TUNE,$tune,4,-1,-1) command (to work on group 4 in this example.)

Here's a simplified version of what I'm doing:



> on_controller
> if ($CC_NUM = 1) {mod wheel}
> $count = 0 {set counter for while loop}
> 
> ...



I'm oversimplifying because the exact details aren't that important. basically it works . . . . except . . . 

additional movements of the mod wheel apparently retrigger this same on controller callback, which starts cascading new instances of the while loop, which effectively speeds up the vibrato to nutty speeds in a hurry.

I suspect this is a something that's been dealt with many times before mine, so first: Is "on controller" the best way to do a vibrato that's controlled by the mod wheel? (I do want to use the mod wheel because it's obvious for the user, plus they can vary the amount of vibrato.)

And if so, how do I keep it from cascading and compounding on itself?


----------



## Hans Adamson (Dec 14, 2010)

If you only are using the mod wheel as a trigger, you could just insert "if over 64 trigger the vibrato". You probably already knew that. Otherwise I guess you would have to write something that says on controller 1, start vibrato, and then let cc1 also control some parameter(s) of the vibrato. (o)


----------



## Hans Adamson (Dec 14, 2010)

OK, I didn't read your script as thoroughly as I should have...

Your script requires a run through the while loop for each of the cc1 data that comes at a blistering speed when you move the mod wheel. Maybe it is not possible to perform these calculations as fast as the mod wheel can produce new data?


----------



## Dynamitec (Dec 14, 2010)

Is there a reason you are using set_engine_par($ENGINE_PAR_TUNE,...) instead of change_tune?


----------



## Mike Greene (Dec 15, 2010)

Hans, I do want the values in CC1 to control depth, so it won't be an on or off thing. I think you're correct in your assessment of why the while loop is doing what it's doing. I just don't know how to make it only behave as if there is only *one* CC1 value/trigger.

Benjamin, I really wanted to use change_tune, but it wouldn't let me address $EVENT_ID in an "on controller" callback. But maybe "on controller" is the wrong way to approach this? I do know that you tackled the vibrato challenge very successfully, so if you're suggesting change_tune, then that's how I'm gonna do it, too! :mrgreen: 

I'm now tempted to skip the "on controller" method and do my vibrato somewhere in the "on note" callback instead. There are lots of advantages to that, including that each individual note would get it's own independent vibrato. But there's one flaw I can't figure out how to overcome: I don't know how I would engage the vibrato if someone pulls up the mod wheel *after* the note on. I can't slip an "on controller" inside an "on note" callback, can I?

I suppose that I could do a while loop inside the "on note" callback that checks every few milliseconds for whether CC1 has been engaged. Seems inelegant, though. But maybe that's the only way?


----------



## Hans Adamson (Dec 15, 2010)

Wouldn't that make the instrumet monophonic - no new on note could be processed until you are finished triggering vibrato? But doesn't the on note callback have to be executed before the note is triggered?


----------



## andreasOL (Dec 15, 2010)

Mike Greene @ Wed 15 Dec said:


> ...
> But there's one flaw I can't figure out how to overcome: I don't know how I would engage the vibrato if someone pulls up the mod wheel *after* the note on. I can't slip an "on controller" inside an "on note" callback, can I?



Hi,

you can do a magic play_note in your "on controller" and pass parameters with EVENT_PAR_0 to EVENT_PAR_3, recognize this in your "on release" and handle CC#1 there. Something like


```
on init
    ...
    declare id
    declare const cc1_cookie := 1234
end on

on release
    if EVENT_NOTE = 0 and EVENT_PAR[3] = cc1_cookie
        ignore_event(EVENT_ID)
        { do something with CC[1] }
        exit
    end if
    ...
end on

on controller
    if CC_NUM = 1 and CC_TOUCHED[1] = 1
        ignore_controller
        id := play_note(0,1,0,1) { play with duration of 1 microsecond }
        set_event_par(id, EVENT_PAR_3, cc1_cookie)
    end if
end on
```

(KScript Editor syntax without $ etc.)

Only "on release" gets called, not "on note" because the event is generated in this script slot.

regards,
Andreas


----------



## Mike Greene (Dec 15, 2010)

Hans, the way I had it set up would require the vibrato to be applied to the entire group. That wouldn't necessarily require it to be monophonic, but with a synchronized vibrato like that on all notes at the same time, it would sound pretty bad if it were anything *but* monophonic. That's why I'm going to try Benjamin's change_tune idea.

Andreas, that's very clever. The one thing I can't figure out, though, is since I want to use change_tune (instead of overall engine parameter stuff,) then how do I make CC#1 effect the original note, as opposed to the magic note, in that release callback? In other words, in that release callback, how do I say to Kontakt, _"You know that note you were playing before I moved the mod wheel? THAT'S the note I want to use change_tune on."_

Dan, thanks for that link. That's a fairly similar direction to what I've been thinking of doing, although I don't know that I'll need PGS stuff (famous last words.) Although that pgs_changed callback may be pretty handy, so maybe PGS will be the way to go.

Thanks for the input, guys. 8)


----------



## andreasOL (Dec 16, 2010)

Mike Greene @ Thu 16 Dec said:


> ...
> 
> Andreas, that's very clever. The one thing I can't figure out, though, is since I want to use change_tune (instead of overall engine parameter stuff,) then how do I make CC#1 effect the original note, as opposed to the magic note, in that release callback? In other words, in that release callback, how do I say to Kontakt, _"You know that note you were playing before I moved the mod wheel? THAT'S the note I want to use change_tune on."_
> 
> ...



Well, you have to remember the notes you want to modify after triggering them in one or the other way, regardless of whether you do that in the "on controller" which is not allowed or in the "on release". You can store the ids in an array[128] and keep track of played and released notes in the note and release callbacks.

BTW, I have this idea of passing information to the note callback from the original crossfade script, so once more, kudos to Nils.

Cheers,
Andreas


----------



## andreasOL (Dec 16, 2010)

Yes, the principle looks good. Just make sure that all variables that you use in a "local way" (loop counter, temp buffer, etc.) after the first wait() are polyphonic.


----------



## Mike Greene (Dec 16, 2010)

Yikes! I totally forgot about making the variables polyphonic! You just saved me a bunch of troubleshooting I would have had to go through! 8)


----------



## andreasOL (Dec 16, 2010)

You're welcome. :D


----------

