How to trigger [poly~] object sample accurately?
Max newbie here. My first project is to create a sample accurate sequencer to trigger drum samples. So far I've created a sample accurate [metro] object using gen~. (The gen~ object sends out a 5 ms pulse every X milliseconds.)
I've also built a sample player instrument using [poly~]. The sample player instrument is currently triggered with "bang" messages. Each time a [poly~] voice is triggered, all currently active [poly~] voices are sent another bang to force an internal amplitude ADSR envelope to enter it's release stage. The active voice is muted when the ADSR envelope finishes.
Triggering a [poly~] object with bang messages isn't sample accurate. I can't figure out how to trigger a [poly~] voice from a pulse signal.
1) The [edge~] object can detect pulses and send bang messages but again this isn't sample accurate.
2) Is there a way to detect where the pulse happens in a signal relative to the signal vector boundaries? Something like [edge~] but it would also report that the trigger pulse happens in X samples. This would allow voices to compensate internally when triggered with a message.
3) The voice objects could be manually duplicated instead of using the [poly~] object. I would then need something to handle voice allocation sample accurately. Does something like this already exist?
I've googled but am obviously using the wrong keywords as nothing is showing up.
Is it possible to send a audio signal to a specific voice in the same way messages can be with "target X"?
Thanks Raja! :)
After fair bit of experimenting and searching the forums I think I've found a way. I've made one object that can detect when a pulse occurs with respect to the signal vector boundaries. Using this info, pulses can be translated to bang messages with a matching delay time. A second object receives the bang + delay_time message and outputs an audio rate pulse (delayed by the delay_time amount). This technique does introduce a latency of two signal vectors however.
Example Project: AudioRateMetro.rar
Nesting poly~s is a good idea. I wonder how that would effect CPU usage?
Here's another example with the audio-rate metro object now triggering a sample player. Audio Rate Sample Triggering.rar
Are these one shot samples? If so, you could fire a single sample pulse that's equal to the voice number and then just use ==~ to trigger the process in the patch. You could use gen~ to make a crude voice allocator. (The catch being that it won't be able to know who is busy...)
I've also used chains of playback objects that pass through triggers to the next object in the chain if they're already playing. Was really interesting for granular, though it was fixed in terms of voice count and muting.
I’ve also used chains of playback objects that pass through triggers to the next object in the chain if they’re already playing.
clever
It seems all the patches in this thread have dried up over time? For any futurepeople looking for a patch here's what i came up with.
Save the patch below as "testPoly1"
ten years later... and i am still not convinced that it makes much sense to have signal accuracy when triggering sampleplayers or envelopes.
metro offers 0.7ms at vs32 or 0.35 ms at vs16, and when you use a signal sequencer instead you can reach an accuracy of incredible 0.044ms, but which then only works within that system, because as soon as you need to triggers things from outside or play those signals triggers to the OTB world, that minor precision advantage of your sample accurate system is gone again.
and then there is the other question, which is how useful it will be to have a pure signal trigger sequencer at all. if you work in all signal, why not just store and send the frequency value already as signal from the sequencer? or the playhead/pitch envelope? or a signal gate?
the original question was a great example for the issues you cause with that; even for turning the voices of a poly~ on and off you already need to convert the signal trigger to a signal gate again.
oh i wasnt really talking about your use case, more about that original question from 10 years back.
what could be a good reason to play drumsamples from a signal rate sequencer?
one which justifies the extra processing power and messy things like sending different signal triggers into different poly~ inputs?
yes, you can have bigger vs and leave overdrive off. what´s more?
for synchronisation it is not required.
Lol, Raja the resident ninja strikes again* :p (i saw the post earlier but couldn't respond). Awesome performance though but saying you "souped up" my patch is very generous because it's as barebones as i could get it. If we take that analogy further i'd say i had barely fixed the cooking utensils there...
The fluid-dynamics had me wondering how it would sound when notes are created if ripples collide though? Great performance nonetheless
*because of the edits ofcourse, they have not gone by unnoticed :) They usually make up for a fun read though as almost everything after the edit stops making sense
Honestly Roman, i don't actually know. I've just been brought up with the notion that UI is bad and control-message is bad so this is my gospel now...
And the problem with the inaccuracies is not the individual case but the build-up of each inaccuracy over time?
there are no buildups. the only inaccuracy which appears is when an event switches domains.
if someone uses shitty windows IO without ASIO while he is good at gen~, it might make sense to build signal rate sequencers.
for all other situations i dont see it. from my perspective it simply needs too much CPU as soon as you need to do more than click click boom.
and of course it only makes sense when you exclusively use max/msp.
as soon as you want to use javascript, trigger VST instruments, not to speak of outputting midi or network protocols, print something to a GUI, you have to go back to data rate anyway.
and as soon as you want to send complex numbers using your signal sequencer, you need to deal with mc- oder poly~.
one day we should do a collaborative "how do you do it" thread for sequencing events using all the different tools/domains/threads in max.
Dsp only gets expensive quick indeed. Some quick testing shows max is way more precise than i gave it credit for. While dsp is precise down to the sample there is some delay with Max-messages but it seems the inaccuracy itself remains consistent.
stuff usually starts with the first sample of the next vector, so that at vs 32 incoming events will be quantized to a 0.7 ms grid, which is about what a physical midi connection does to a 3 byte message, too (the pure connection from controller to controller, that is.)
signal accuray is 16 or 32 times better, depending on what you do.
btw., has the original question from 2014 already been answered by any of us?
starting a voice from a trigger is easy:

to turn the signal which goes to the thispoly~ back to zero is more complicated.
in most cases you might be fine with data rate accuracy though (like the flag which adsr~ or line~ provide.) it does not hurt if the voice is turned off a bit later.
or wait... hm. no, you have to do it with signal accuray, too. :)
actually, if it is a sample player, you should create "note off" triggers on a parallel stream from outside the poly anyways.
"btw., has the original question from 2014 already been answered by any of us?"
The question in question:
"Triggering a [poly~] object with bang messages isn't sample accurate. I can't figure out how to trigger a [poly~] voice from a pulse signal."
Yes, my post from 12th of july tackled this. In~ 1 is just an integer counter at signal rate so it functions like a trigger and sets the index for poly-voice.

sorry for overlooking you. but this is a lot of stuff. what about making it shorter?
and did you notice that the data rate output of poly~ is not sample accurate? :)
you can do it without loop, and therefore without data rate.
the 1 sample delay which is required alternatively to the feedback loop approaches means that you can now send note events as fast as SR/4.

"what about making it shorter?"
This is what i came up with, if you feel it can be done shorter by all means go ahead...
"and did you notice that the data rate output of poly~ is not sample accurate? :)"
i did yeah, hence the loadbang and sig~ after thispoly. :) It only captures the voice-number and doesn't output anything unless you bang it
"you can do it without loop, and therefore without data rate."
But how do you deal with voice-allocation now? Because that's done with a signal in my patch. And i'm just going to pretend i'm hallucinating the qmetro :p
lol, the qmetro is a leftover from what i tried there back in the days.
its purpose is to reset the accumulator, because that thing cannot run endlessly and is "full" after a while (earlier than after a 64 bit float maximum, that is)
unfortunately resetting it flips the flipflop state to 0, so you should only reset it when no notes are running.
somebody else posted another version based on phasor and modulo (or pong?) somewhere in the forums many years back but i cannot find it now.
voice allocation? to what? to poly~ voices?
ah yeah, that also unsolved "i need a signal [cycle]" problem, which once again requires code where a single sample routes itself. no idea.
as a quick workaround you could only compose monophonic music from now on.
no, seriously, just use different trigger sequencers for different trigger counts, or eventually different size of triggers. (1.0, 2.0, ....) then you can sort and route them later.