Kyma Forum
  Kyma Support
  Luddy - trigger question

Post New Topic  Post A Reply
profile | register | preferences | faq | search

next newest topic | next oldest topic
Author Topic:   Luddy - trigger question
cristian_vogel
Member
posted 30 April 2009 05:52         Edit/Delete Message   Reply w/Quote
You seem to be the person to ask

Its simple but causing me a lot of headache

I have a sequencer that is triggering a sample

I want to hold the !KeyDown if the velocity is 0 , so we hear the whole sample, until the next positive velocity and !KeyDown event - a legato for sequencers, with the sustain dependent on whether the next step has a positive velocity or not.

I just can't seem to find the best way of doing this reliably.

[This message has been edited by cristian_vogel (edited 02 May 2009).]

IP: Logged

Luddy
Member
posted 01 May 2009 19:28         Edit/Delete Message   Reply w/Quote
Hi Cristian,


OneShotTrigger := [ :duration |
| oneshotgate oneshotreset oneshottrigger normalgate |

oneshotgate := ((!KeyDown eq: 1) * (!KeyVelocity eq: 0)).
oneshotreset := EventVariable new.
oneshottrigger := oneshotgate setReset: oneshotreset.

normalgate := ((!KeyDown eq: 1) * (!KeyVelocity ne: 0)).

(oneshotreset <+ (((trigger ramp: duration s + 1 ms) eq: 1) + normalgate))
oneshottrigger)
].

If you call this block this way:

OneShotTrigger value: <sample duration in seconds>.

then it will generate one-shot triggers in response to zero-velocity keydown events. a non-zero velocity keydown event turns off the trigger.

My guess is that this isn't quite good enough. you probably also want to generate a normal gate from the non-zero velocity keydowns. That hurts my head right now, haha. I gotta think some about it. What you want to do in that case is use (!Keydown eq: -1) * (!KeyVelocity ne: 0) to reset the one-shot trigger. This is necessary because you need the little 5ms voice-stealing period to create a gap in the whole output -- a moment when the whole gate is zero (or negative).

-Luddy

[This message has been edited by Luddy (edited 01 May 2009).]

IP: Logged

pete
Member
posted 02 May 2009 06:56         Edit/Delete Message   Reply w/Quote
Sorry if this is a private conv

I'm not sure if I understand what you want but if by velocity you meant !KeyVelocity,
then because the !KeyVelocity is held until the next note you could use.

!KeyDown + (!KeyVelocity eq: 0)

If velocity was just a hot param you could use

!KeyDown + (!KeyDown sampleAndHold: ( !Velocity eq:0))

!Keydown has a single minus one pulse when triggered so this will retrigger on the next note after the long held note. If you don't want this to retrigger you can use

(!KeyDown abs) + (!KeyDown sampleAndHold: ( !Velocity eq:0))

Sorry if I've not understood the requirement.


[This message has been edited by pete (edited 02 May 2009).]

IP: Logged

Luddy
Member
posted 02 May 2009 07:21         Edit/Delete Message   Reply w/Quote
Hi Pete,

>> !KeyDown + (!KeyVelocity eq: 0)

Hmm, doesn't this begin life as a 1 value? I.e., isn't the gate open when you first run the sound?

-L

IP: Logged

cristian_vogel
Member
posted 02 May 2009 08:51         Edit/Delete Message   Reply w/Quote
thanks for putting some thought into this

I found that one sequencer then triggering a second single-step "trigger" sequencer was the only way to pass-thru the values of pitch and velocity , but masking the continuous !KeyDown messages sent by a sequencer. This allows to hold notes/samples/gates until a non-zero velocity step comes in.

The most logical was to have the second sequencer dependent on a !KeyDown * (!KeyVelocity ne: 0)

I tried this in the Step Field , and in the Gate (sequencer reset) field, but this was giving me erratic behaviour - now I understand form Luddy's post, that there is a -1 coming in first and this was probably triggering the logic twice and getting all muddied. It seems that the !KeyDown and the !KeyVelocity values don't seem to happen at the same time also.

Plus, the step/ duration / rate / dutyCycle relation/brainache was probably introducing all sorts on weird behaviour - I WISH THE SEQUENCER WAS MORE STRAIGHTFORWARD ( no pun intended )

I even reached a point of building the whole sequencer in CapyTalk, building on Luddy's scripted version at the Tweaky. But the dutyCycle for the gate is useful, and I couldn't figure how to do this simply in a CapyTalk array sequencer..

Anyhow, I'll try your code tomorrow and let you know how I get on.


IP: Logged

Luddy
Member
posted 02 May 2009 09:01         Edit/Delete Message   Reply w/Quote
Hi Cristian,

Maybe Pete can correct or add to this, but I think the exact sequence of events on a note-on event are:

!KeyDown goes to -1 for 5ms.
!KeyVelocity and !KeyPitch remain at their old values at this time.
This is necessary so that the note-stealing code can end the old notes
smoothly.

!KeyDown goes to +1 so long as the note-off event has not yet arrived
!KeyVelocity and !KeyPitch take on the new values at this point

I hadn't thought about it before Pete's post, but it makes sense I guess that !KeyVelocity and !KeyPitch would keep their previous values even after a note-off event, for the same reason that they keep their values during a note-steal.

-Luddy

IP: Logged

pete
Member
posted 02 May 2009 12:32         Edit/Delete Message   Reply w/Quote
Hi Again

>>>> !KeyDown + (!KeyVelocity eq: 0)

>>Hmm, doesn't this begin life as a 1 value? I.e., isn't the gate open when you first run the sound?

Yes of course you're right Luddy and to over come this you would need

!KeyDown + (!KeyVelocity eq: 0) + (!KeyDown setReset: 0) -1

Hi Cristian, think I see what you are trying to achieve.

You want a sequencer that will play notes of a sample player and to restart the sample on every note, unless you have programmed in zero velocity. In this case the pitch will move, the velocity will stay the same, but the sample will not go back the the beginning but will instead continue from where it is. You are not interested in the on duration of the note as you have set fade out time on the sample player to 1 day .

Please tell me if I have this right?

To achieve this you don't care when the !KeyDown returns to zero as long as it does not go to one at any time when a zero velocity note comes along.

Luddy is correct that at trigger !KeyDown goes to minus one for a moment when trigger comes along. I thought it was for one tick (1 ms) instead of 5 ms but I'm not sure on this one.

Any way

If we use !KeyDown as it is and add one when the zero comes along the minus one will make a trigger when we don't want it.

If we use !KeyDown abs the the trigger will happen (as Luddy says) before the zero velocity has come along and the trigger will get through.

If we use !KeyDown clipTo01 instead, we remove the minus one and the leading edge trigger will now be 1 ms (or 5ms) latter.

So you would need

(!KeyDown clipTo01) - (!KeyVelocity eq:0)

But there seems to be a feature in the sample player to make the steal work correctly.
That is that if you put a negative in the gate the release time is ignored and cuts the signals output abruptly so to stop this happening you need to remove the minus.

((!KeyDown clipTo01) - (!KeyVelocity eq:0)) clipTo01

also it seems that the velocities don't work correctly with

11011101

instead I used

{0.9} {0.9} {0.9} {0.0} {0.9} {0.9} {0.9} {0.0}

which seemed to work.

Don't know why?

This should work but I think you will need to do a bit more work to make the velocity hold during the held note. but sampleAndHold: will do this

hope it helps

[This message has been edited by pete (edited 02 May 2009).]

IP: Logged

pete
Member
posted 02 May 2009 13:35         Edit/Delete Message   Reply w/Quote

SequSleer.kym

 
example attached

IP: Logged

SSC
Administrator
posted 02 May 2009 14:37         Edit/Delete Message   Reply w/Quote
!KeyVelocity * (1 + !KeyDown)

See 'non reattacking sequencer.kym'

[This message has been edited by SSC (edited 02 May 2009).]

IP: Logged

cristian_vogel
Member
posted 03 May 2009 05:28         Edit/Delete Message   Reply w/Quote
the secret life of triggers!

thanks so much, armed with all this knowledge, I think can acheive the exact behaviour I am looking for


IP: Logged

Luddy
Member
posted 03 May 2009 06:15         Edit/Delete Message   Reply w/Quote
>> !KeyVelocity * (1 + !KeyDown)

But this produces a value of 0 when velocity is 0. As I understand it, Cristian wants a longer-than-usual (non-zero) gate in the case of velocity = 0.

-Luddy

[This message has been edited by Luddy (edited 03 May 2009).]

IP: Logged

SSC
Administrator
posted 03 May 2009 09:40         Edit/Delete Message   Reply w/Quote
Hi Luddy!

>> !KeyVelocity * (1 + !KeyDown)

The idea of this expression was to trigger the sample when !KeyVelocity > 0 and to defeat the sequencer from retriggering it by !KeyDown when !KeyVelocity = 0.

Using !KeyVelocity alone would be sufficient except in the case of two or more stages in a row being switched on. In order to retrigger, the gate value has to briefly go to zero first. (1 +!KeyDown) is 0 when !KeyDown goes to -1 during voice stealing, 1 when the key is up, and 2 when the key is down.

The end result is a sequencer where stages with zero velocity do not retrigger the sample, but they also do not silence the sample; the sample continues to play until the next non-zero velocity stage. (This was based on Pete's summary of his own understanding of what Cristian was describing but maybe we misunderstood the original request?)

IP: Logged

Luddy
Member
posted 04 May 2009 02:47         Edit/Delete Message   Reply w/Quote
>> Hi Luddy!

Hi there!

>> >> !KeyVelocity * (1 + !KeyDown)

> The idea of this expression was to trigger the sample when !KeyVelocity > 0 and to defeat the sequencer from retriggering it by !KeyDown when !KeyVelocity = 0.

The problem I see is that the expression must also *trigger* the sample to begin with, when !KeyDown occurs and !KeyVelocity = 0 for the first time. In other words, if the first thing that happens is that Cristian plays a !KeyDown with !KeyVelocity = 0, then a one-shot trigger should occur, and should play the whole sample out. Likewise, if two !KeyDowns occur in a row, each with velocity zero, and if they are far enough apart in time that the sample has been played all the way out, then I think the second one should retrigger the sample.

Maybe we have different interpretations of the requirements. You are interpreting !KeyVelocity = 0 as a purely negative event, something to be ignored as it were. I interpret it as a positive request for a one-shot trigger, a special meaning being given to !KeyVelocity as it were.

-L

[This message has been edited by Luddy (edited 04 May 2009).]

IP: Logged

cristian_vogel
Member
posted 04 May 2009 08:43         Edit/Delete Message   Reply w/Quote
quote:
Originally posted by pete:
example attached

I just tried to run your example on my Paca and got 'ERROR: Improper store into indexable object' which is really strange

I;m still getting erratic behaviour in my program even after all this discussion.. Its a multisample with my own samples, so I will have to try and build it into a generic thing so you can have a hack at the issue in context , and there's no confusion about what the goal is.


IP: Logged

cristian_vogel
Member
posted 04 May 2009 09:18         Edit/Delete Message   Reply w/Quote

nonreattackingsequencer.kym

 
quote:
Originally posted by SSC:

The idea of this expression was to trigger the sample when !KeyVelocity > 0 and to defeat the sequencer from retriggering it by !KeyDown when !KeyVelocity = 0.


You will see from my attachment, how your example was not actually *holding* the gate, but just playing the release. I need a !KeyDown to *sustain* if the next velocity is zero or below a small velocity (like 0.1). I want to respect and play the sample with !KeyVelocity as a volume, not just an on off... This is for the heart of my NeverEngine sequencer which does interpolating/crossfading between two different banks of velocity values slowly over time.

In the example I have attached, I put a sample loop, so you can hear that the gate is not being held, it was just not re-triggering.


IP: Logged

pete
Member
posted 04 May 2009 13:18         Edit/Delete Message   Reply w/Quote
Hi Cristian

I see what you want.

The problem is that you can not have a duty cycle of 1 as this seems to kill the trigger altogether. Any thing less than 1 adds a gap between the notes before the trigger and it's this that makes the zero velocity masking too late.

You could delay the gap to make it line up like this.

((((!KeyDown smooth: 6ms) asLogicValue)-0.5 ) smooth: 6ms)+(!KeyVelocity le:0.2).

This is a two stage delay as you need that to get the trigger lined up.

but a much better way is to use what you have with the simple trigger and with the decay set to 1 day and then use an external AR and VCA to make the envelope.
The gate in the sample is doing two jobs.
Re-triggering the sample and gating the built in envelope.

By putting the release to 1 day you deactivate the built in envelope shaper and you can then add your own to the output of the sample player to make a much neater solution.

hope this helps.

IP: Logged

SSC
Administrator
posted 04 May 2009 15:00         Edit/Delete Message   Reply w/Quote

gatesustainsthrusilentstagessequencer.kym

 
Hi Cristian (aka Tom

In this sequencer, when velocity = 0, the previous stage's gate stays down and the sample continues looping through the silent stage.

Note that there is a FunctionGenerator in Gate field and extended duration is computed and transmitted using ExtraValues to allow for DutyCycle control.

(Example also uploaded to tweaky for future reference).

IP: Logged

cristian_vogel
Member
posted 07 May 2009 02:27         Edit/Delete Message   Reply w/Quote
this solution works great

but seems to fail if there is shuffle/groove in the sequencer duration field


IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply

Contact Us | Symbolic Sound Home

This forum is provided solely for the support and edification of the customers of Symbolic Sound Corporation.


Ultimate Bulletin Board 5.45c