![]() |
![]() ![]() ![]() ![]() ![]()
|
next newest topic | next oldest topic |
Author | Topic: trigger at the end of sample | |
franz Member |
![]() ![]() ![]() Hi! I need some help on this: Best, IP: Logged | |
pete Member |
![]() ![]() ![]() Hi Franz Yes you seem to have the right idea about using the ramp as a dummy sample time reference. Now you need to step back and think about the triggers. You are making a trigger mask which is derived from a trigger that has to be masked by the same trigger mask. Hence a feed back loop is needed. So if you put the formula (hence the TriggMask) into a sound to global controller, that controller will be transmitted everywhere both forward and backwards in the sound (al be it 1 ms latter which is what you need) and can be picked up and used further back to the left of the sound to global controller. This produces the required feed back. Now for the detail. If you look at what the ramp: is producing, it rests at +1. When a trigger comes along, it jumps down to zero and then slowly rises back to its resting place +1 again. For clarity if we turn it on it's head i.e. 1- (xxx ramp: xxx) then we can say that any time it is greater than zero it should be masking out the triggers and when it is zero (or less) it should let triggers pass. So just to make sure that the rest is in the correct place (it could be a tiny fraction above zero) , we can change it to 0.99999 - ( xxx ramp: xxx ). Now the rest point is guaranteed to be zero or below. Now we can use asLogicValue after out ramp: formula to give us a zero when at rest or one during the ramp time. This forms the mask. Now we want to turn the mask on it's head and multiply it by the triggers using the same zero assurance trick as before. So you need a constant module (name it FlushedTrigger), with this formula in the value field. ( !Trigger * ( 0.99999 - !TrigMask ) ) asLogicValue This Module is pasted into the sample players trigger/gate field and also pasted into the next formula which lives in the soundToGlobalController Module. ( 0.99999 - ( [FlushedTrigger] L ramp: !Duration ) ) asLogicValue Then make sure that the SoundToGlobalController is transmitting !TrigMask. I hope this makes sense and I hope it helps. Pete IP: Logged | |
SSC Administrator |
![]() ![]() ![]() A while back, Joel Chadabe came up with an interesting alternative solution to this problem: If your sample is quiet at the end, you can put an AmplitudeFollower on the sample itself. Then you could use something like the following: <randomTrig> gateWhen: (<ampEnv> lt: !Threshold) Let us know what you come up. Thanks! [This message has been edited by SSC (edited 07 March 2013).] IP: Logged | |
SSC Administrator |
![]() ![]() ![]()
The key is a SoundToGlobalControl whose GeneratedEvent is: !RandGate and whose Value is: (0.5 s random gt: 0) gateWhen: ((!RandGate ramp: ('count.aif' fileDuration / !RandRate) s) eq: 1) IP: Logged | |
franz Member |
![]() ![]() ![]()
thank you for the hints! Both solutions work fine. Now I tried to make Petes solution polyphonically playable. And again I´m stuck. I tried to combine the triggers with the expression countTriggersMod: ?NumberVoices eq: (?VoiceNumber - 1), but somehow I´m missing something (see attached sound). Either the sample is triggered despite !triggerMask is on or !triggerMask does not reflect the end of the samples. And how would I make the AmpFollower solution polyphonically playable? Here again I´m stuck with the combination of the Trigger and AmpFollower… Thanks a lot! Best,
[This message has been edited by franz (edited 08 March 2013).] [This message has been edited by franz (edited 08 March 2013).] [This message has been edited by franz (edited 08 March 2013).] IP: Logged | |
SSC Administrator |
![]() ![]() ![]()
We have revised your example to include the possibility of polyphony. Rather than use a counter to determine whether to trigger a voice, instead it uses a different rule: a voice can be triggered if it is not playing now and all of the lowered number voices are already playing. We have simplified the logic for the generated !TrigMask to use ([FlushedTrigger] L ramp: !Duration) lt: 1 (It is ok to do this because ramp: goes to 1 at the end of the ramp.) Next, each voice generates a global controller named !PermitTriggering for the next voice that tells the next voice whether it is permitted to trigger. The next voice's PermitTriggering is created from this voice's !PermitTriggering and !TrigMask: !PermitTriggering * !TrigMask This means that the next voice is permitted to trigger if this voice is permitted to trigger and this voice is playing. This recursively makes it so that higher numbered voices are permitted to trigger only if *all* of the lower numbered voices are already playing. Finally, the FlushedTrigger Sound is the actual trigger for the Sample. It triggers the sample if !Trigger is on (1) and this voice is permitted to trigger and this voice is not already playing: !Trigger * (!Trigger sampleAndHold: !PermitTrigger * (!TrigMask ne: 1)) IP: Logged | |
pete Member |
![]() ![]() ![]()
Is this maybe what you are looking for? The triggers count is multiplied by the trigger else it stops being a trigger and becomes a continuos value 1. Also it only treats the incoming trigger and does not interfere with the feedback needed for the mask. let me know if it's doing what you want? Pete IP: Logged | |
pete Member |
![]() ![]() ![]()
You may want to try V4 attached. As SSC says they can guarantee that the ramp: will reach absolute value 1, and as such we don't need to double invert it or make use of the as Logic value. I was not in front of a Kyma at the time so I couldn't try it out to see if it would work, so I assumed true one may not be reached and compensated accordingly. Now I know it does, and I can test it out, the attached is basically the same as before but the formula are much simpler. It's great to see SSCs approach as well. It only goes to show there is never only one answer to a question. Pete IP: Logged | |
pete Member |
![]() ![]() ![]() Hi Franz There is a floor in my approach that doesn't happen in SSCs. That is that if you fired 6 triggers and then fired a 7th when the first voice had became available, it would not make use of the first voice as it would be trying to fire the third (which is still playing) so it would not trigger another sound even though there was a voice available. This may not even be noticeable in normal use and is less likely to happen, the greater the polyphony used. Hope this makes sense. IP: Logged | |
franz Member |
![]() ![]() ![]()
There is just one problem which solution is certainly very simple but I can´t figure it out. I took the sampleAndHold example from SSC and tried to add a modulation to the Frequency (which is now constantly changing) of the sample (so the initial frequency is taken from the modulating source and then modulated further by the same source). Best, IP: Logged | |
franz Member |
![]() ![]() ![]()
I give it another try: I´m stuck with the question how to calculate the duration of a sample which frequency is constantly modulated (e.g. a LFO). The expression in the frequency field would be: default + (!Modulation * 30). Which expression would I put into a SoundToGlobalController that should show me the Duration of the sample? (The problem is the "plus". If the frequency would be multiplicated, I´d simply divide the duration of the sample by the modulator.) And how would I make this polyphonic so that two or more samples are being modulated by the same modulator (but triggered at different times so that their duration is different)? Attached is a sound that shows the structure I was thinking of. I hope this makes sense. Thanks a lot! Best wishes, IP: Logged |
All times are CT (US) | next newest topic | next oldest topic |
![]() ![]() |
This forum is provided solely for the support and edification of the customers of Symbolic Sound Corporation.