# A rhythmical gate



## CarlLofgren (Jun 25, 2012)

After been playing around with the built-in modulators - especially the step modulator - I've come to the conclusion I have to build one myself.

If one would create a modulator - that would be able to make changes to volume, such as ON-OFF-ON-OFF-ON-OFF-OFF-OFF (repeat synced in tempo) - where would one start? I have been looking into the NI sequencer scripts - but cannot really get the gist of it.

I was thinking to store the "pattern" in a table/array and then modulate maybe the gainer as an insert effect (that way I could use it for automating effect parameters later on).

I guess that my first step would be to create a simple square LFO in KSP - but where would one start? Any advice will immediately result in joyful singing from my part 

/C


----------



## CarlLofgren (Jun 26, 2012)

Damn I'm close.

I made a quite crude step modulator which works apart from one annoying detail: The Modulation is POLYPHONIC!

If I would make this step modulator to play monophonically - what I am missing?

In other words - if I add a playing tone, I would like that tone to be modulated in the same way and rhythm as the other tones - not start all over again.



> on init
> declare ui_table %steps[8](4,4,450000)
> %steps[0] := 0
> %steps[1] := 0
> ...


----------



## CarlLofgren (Jun 26, 2012)

Nope. That script totally sucks... :oops:


----------



## Lindon (Jun 26, 2012)

try adding something to start the "sequencer " just once...warning, not near my audio machine or a KSP manual so buyer beware...

```
on init

declare %empty_array[128]
declare $sequencer_running := 0
declare $counter

declare ui_table %steps[8](4,4,450000)

end on


on note

if $sequencer_running = 0
   $sequencer_running := 1

   {OK so its not running so start it...}
   while $sequencer_running = 1
      message($counter) 

      set_engine_par($ENGINE_PAR_GN_GAIN,%steps[$counter],-1, 0,1) 

{I use $ENGINE_PAR_VOLUME here...to be honest...}

      wait($DURATION_EIGHTH) 

      $counter := $counter + 1 
      if ($counter >= 8) 
           $counter := 0 
      end if 

  end while
end if

end on

on release
 {test to see if all notes are off...}
 if array_equal(%empty_array, %KEY_DOWN) {never tried it this way by the way...}
   {if so turn off the sequencer.....}
   $sequencer_running := 0
 end if
end on
```


----------



## CarlLofgren (Jun 26, 2012)

If you did that not being close to your audio computer - your KSP Kung-Fu is considerable. It worked almost without alteration. Trying to understand what you did, I'm quite confused what the empty array is doing.

Another thing is the release phase. As it is now, the effect stops as soon as you stop playing which creates a bit wonky effect with pad like sounds with long release. 

I've probably consumed a weeks supply of coffee over the KSP docs this morning. I sort of having the feeling on note might not be the optimal way to do it - but I cannot figure out any alternative way.

/C


----------



## polypx (Jun 26, 2012)

If you use a PGS thread, you can keep it going indefinitely. (Hence the Restart button to resync this) :


```
on init
declare ui_button $Restart
declare $counter
declare ui_table %steps[8](4,4,450000)
make_persistent(%steps)
pgs_create_key (COUNTER, 1)
_pgs_set_key_val(COUNTER, 0, 0)
end on

on note
if (pgs_get_key_val(COUNTER, 0) = 0)
_pgs_set_key_val(COUNTER, 0, 1)
$counter := 0
end if
end on

on pgs_changed
while (_pgs_get_key_val(COUNTER, 0) = 1) 
	set_engine_par($ENGINE_PAR_GN_GAIN,%steps[$counter],-1, 0,1)
	wait($DURATION_SIXTEENTH)	
	$counter := ($counter + 1) mod 8
end while
end on

on ui_control ($Restart)
pgs_set_key_val(COUNTER, 0, 0)
$counter := 0
$Restart := 0
end on
```

cheers
Dan


----------



## mk282 (Jun 27, 2012)

I see no need to use a Gainer here and use up an FX slot.

Why not use a Constant modulator set to "Invert", then change the modulation amount of it to sequence volume.


----------



## Lindon (Jun 27, 2012)

Carl,

In the on release call back we are trying to ascertain if the user has stopped pressing down on any keys...and if so then we can turn off the effect. The system array %KEY_DOWN is 128 elements big and has a 1 in each element where the user is holding down a key...and a 0 where they are not...we want to stop the sequencer when the user has stopped holding down keys..so in that case %KEYS_DOWN would be full of zeros, so an empty array lets call it %empty_array is also full of zeros, so a quick comparison says if %KEYS_DOWN = %empty array then the user has stopped pressing any keys....

you could do this instead

```
for $idx := 0 to 127
   $summ := $summ + %KEYS_DOWN[$idx]
end for

if $summ = 0
  {looks like there are no held keys....}

...
...
```

If you want the effect to continue past the last "key up" event , to account for long release sections

I'd do this:

```
on release 
 {test to see if all notes are off...} 
 if array_equal(%empty_array, %KEY_DOWN) {never tried it this way by the way...} 
   {if so turn off the sequencer.....} 
    wait(DURATION_EIGHTH)   {or some other longer duration if you want it....}
    $sequencer_running := 0 
 end if 
end on
```

As Mario says I wouldnt use a gainer, as that ties up an fx slot I'd just do it to the group volume instead, of course this is a bit cruder in some ways...


----------



## Lindon (Jun 27, 2012)

actually thinking about it for a nano second I'd do this in the on release...as it would allow you some "release time" and would make any re-keyed or new notes to be played in that time and the sequencer stay in sync with itself....


```
on release 

  wait(DURATION_EIGHTH)   {or some other longer duration if you want it....} 

  {test to see if all notes are off...} 
   if array_equal(%empty_array, %KEY_DOWN) {never tried it this way by the way...} 
     {if so turn off the sequencer.....} 
     $sequencer_running := 0 
   end if 
end on
```


----------



## Lindon (Jun 27, 2012)

I'm starting to monopolise this thread now...sorry:

Carl: "I sort of having the feeling on note might not be the optimal way to do it - but I cannot figure out any alternative way."

Here's another way :


```
on init 
declare ui_table %steps[8](4,4,450000) 
declare $counter 
set listener ($NI_SIGNAL_TIMER_BEAT,1)

end on 

on listener
   if $NI_SIGNAL_TYPE = $NI_SIGNAL_TIMER_BEAT
      set_engine_par($ENGINE_PAR_GN_GAIN,%steps[$counter],-1, 0,1) 
      inc($counter)
      if ($counter >= 8) 
          $counter := 0 
      end if 
   end if
end on
```

Should work in stand alone and in your DAW, been a while since I did anything in the "BEAT" area myself so again caveat emptor...this should run for ever, and will change the modulation frequency to match any tempo changes in your DAW, of course its not out the bag able to select your own frequency...its based in triggering every beat...but it'd be trivial to make it multiples of beats if you wanted...

Lindon


----------



## CarlLofgren (Jun 27, 2012)

Hi all - a big thanks for all the help. Really really appreciated.

The reason why I'm leaning towards using the Insert Gainer, is because I have some perverted plans of modulating effects as well. You know - a big reverb on the first beat - that kind of cheesy-ness :lol: 

Lindon: on listener is the way to go. Absolutely - it feels way more robust. The only snag (there is always always a snag) is that the volume changes are a bit soft. Not snappy at all - but that isn't necessarily a bad thing. Just different.

But if one would try to make the volume changes razor-sharp - where would one get ones hands dirty? When I was experimenting with the step modulator (couldn't use it for a number of reasons) the gates it created was way way more distinct.

Now it's a bit soft - but as I said, that's not a bad thing.

/C


----------



## Lindon (Jun 28, 2012)

Carl, On listener has no effect on the volume ramps, its a trigger only, the only thing I can think is that *perhaps* a once per beat approach may be giving your gainer more time to change values and Kontakt is taking it. 

I say this because I use ENGINE_PAR_VOLUME to change the volume of groups and when I watch the volume dial change I perceive it moving slower when I have modulation frequency set lower...I could be wrong. So two things to try:

1. try changing ENGINE_PAR_VOLUME instead of using the gainer...
2. Try upping the frequency of your modulator..

in the on init

change:

set listener ($NI_SIGNAL_TIMER_BEAT,1)

to:

set listener ($NI_SIGNAL_TIMER_BEAT,2)

which *I think I recall* doubles the frequency to to twice per beat...

Lindon


----------



## CarlLofgren (Jun 30, 2012)

Lindon - 

I tried both your suggestions - and sadly, they don't make any difference. I've captured the differences in pictures. Note that the KSP is clearly fading in and out, while the NI LFO does much sharper cuts.

It's quite clear when you listen to it as well. The picture with KSP is using a faster clock and working om volume instead of the gainer.

Any ideas coming though your mind what it could be?

/C


----------



## CarlLofgren (Jun 30, 2012)

*Damn it. I may have found it the reason for the wonky fades.*

By pure desperation I tried to modulate the volume via MIDI CCs instead. And voila - no more fades. The cuts are now razor sharp.

Won't draw any conclusions just yet - everything has been working for ten minutes = still room for issues to show up. I'll dig deeper and see what I come up with.

It sounds totally crazy, I know. Internal routings should with all logic be quicker than an external one.

/C


----------

