Trying to wrap my head around fluid.ampgate~ at the moment, and unless I’m doing something wrong (totally possible, as always) the @onthreshold and @offthreshold are inverted for fluid.ampgate~ and fluid.ampslice~. In fluid.ampslice~ the higher value is the @onthreshold (as can be seen in the comparison between the onset detection algorithms here), but in order to get something that kind of makes (sonic) sense in fluid.ampgate~, I have to set @onthreshold as the lower number.
To further confuse the issue, the reference for fluid.ampgate~ has this to say about what the thresholds do:
on top of that, (almost) all the examples for fluid.ampgate~ have both threshes set the same, so it’s difficult to infer what these are.
In addition to what seems like a reference gap and/or a bug, in playing with fluid.ampgate~, I’m not entirely sure how this object is meant to be used. My initial understanding, in speaking with @tremblap is that @weefuzzy and him broke the old fluid.ampslice~ into two objects. But I’m not entirely sure how they should be used in conjunction. To give a more practical example, I’m presently using fluid.ampslice~ as my default onset detection algorithm as I can get comparable results with the homebrew version, so I want to dip back in and also get a gate signal (for use in modular land) from the same algorithm. So effectively using the fluid.gate~ algorithm on the differential from fluid.ampslice~. Obviously (and unfortunately) fluid.ampslice~ doesn’t spit out its envelopes in order to do this, but when trying to mix the homebrew with fluid.ampslice~ I was finding no joy (particularly with the inverted attributes).
Oh, another funky issue. I have no idea what the @rampup and @rampdown attributes do for fluid.gate~. Are they the up/down times for an envelope follower? Are they smoothing applied the state transitions? Let me check the reference file…
First, yes, it looks as if the the reference docs for ampgate didn’t get populated when the object was split. Easily fixed, thanks for the spot.
As in the previous monolithic ampslice, the thresholds behave as a schmidt trigger, the same as thresh~ in Max. So, for the object to go 0->1 the input envelope has cross onthreshold from below. To then go 1->0 it has cross offthreshold from above.
The rampup/downs are indeed envelope follower attack / release, and behave identically to slide~ in Max. If you need hysterisis in time on the state transitions, we don’t use smoothing, but lookahead / lookback (at a greater CPU cost and latency), in conjunction with a minimum slice length to control the friskiness and greediness of the switching (these are what make it more powerful than abs~-slide~-thresh~)
The two in conjunction: ampslice now behaves like the other slice objects, and emits spikes when something looking like an onset in its feature signal is spotted. It decides there’s an onset when a fast moving envelope follower goes beyond a certain number of dB above a slower moving one. On its own, it’s possible you’d still get a lot of triggering in very quiet, notionally silent bits, so you can use [*~] or [gate~] to couple this to an ampgate that would stop this happening below some noise floor you’ve selected. (If you still have the Max patch of @tremblap’s that birthed this object, I think that this is pretty much how it works there as well)
That’s where I’m thrown in that that fluid.gate~ works off absolute thresholds, rather than relative ones (well, the differential), meaning that I would presumably having to super tightly define the absolute on/off thresh for fluid.ampgate~ to be able to use it along with fluid.ampslice~, and even then, there would be tons of times .ampslice~ would trigger and .ampgate~ wouldn’t, again, because of the absolute vs relative threshes.
So in my use case, I would love to have .ampgate~ behavior, but with .ampslice~ relative/differential thresholding, which appears to be impossible with how it’s currently built. I can do a mix-and-match, like in the code example above, but that seems to defeat the point to separate the object, if they can’t “get put back together”.
That’s where I’m thrown in that that fluid.gate~ works off absolute thresholds, rather than relative ones (well, the differential), meaning that I would presumably having to super tightly define the absolute on/off thresh for fluid.ampgate~ to be able to use it along with fluid.ampslice~ , and even then, there would be tons of times .ampslice~ would trigger and .ampgate~ wouldn’t, again, because of the absolute vs relative threshes.
That part of the old object was absolute-thresholded as well. If you want to make it relative, then use, e.g. fluid.loudness to drive the thresholds.
Ah right. Why would it matter to the object/algorithm what kind of signal and what range (and order) the numbers come in? It could be useful for all sorts of signal gating (though a “normal” gate would also be fine). (or for gating envelopes, like in my example)
I don’t really understand how the old object worked, but was this aspect of it completely independent of the differential stuff?
This seems good, but I guess this will have all kinds of slop from going signal->control->signal again, which would defeat some of the tightness and usefulness of having a signal rate gate signal.
It was. Splitting up the object was done partly on the basis that this fact was very difficult to dechiper
There will be a small amount of slop, but even without leaving the signal domain, a threshold relative to a slower moving envelope implies the added latency of that envelope process, which could well drown out any timing changes. Give it a shot…
The latency isn’t so much an issue (although I’m not a huge fan), it’s more the inconsistency of being +/- a vector (or more?) from changing domains a couple of times.
As much as it would be a bit redundant, I may just try tweaking it so I use the vanilla max version of the algorithm and then slap fluid.ampgate~ (with the highpass filter bypassed) on the differential and call it a day.
I’m not sure what output you’re after, but having a play with ampslice on its own with brushes.aif made me think that a single instance would probably never get all the stuff in there, because the amplitude contributions of those toms vs the hats are so great. Here’s what happens if I use two, the fuse the results with a third to tidy up the mess. One of the two has the hpf set pretty agressively, and with a lower floor to try and get those hats, the other is more orthodox.
Yeah that seems to work, though it’s confusing stuff as I would have thought I was already doing that in the subpatch. But I guess it’s more about what fluid.ampgate~ is doing with the numbers. This first example is what I was looking, so perfect!
I hadn’t thought about ‘double dipping’ the onset detection, and I like the clever use of another one was a “lockout”-ish thing.
This is great for coming up with a very instrument-specific use case, but I’m all about “the perfect (no latency!) algorithm that works, in the way I want, across all kinds of material” kind of thing, lol.
This is very interesting indeed and I did not think of using our objects as such, but I get very good results with this too - playing with parameters of each detector (why not adding a spectral one like onset there) and then deciding with a meta one with ampslice like this is genius. I keep my minslicelength smaller, but I also have this following patch to hear how fast I want it to detect. (notice my thresh is lower than @weefuzzy’s to be more ‘precise’ on the debouncer - 1 sample, enjoy