Combining fluid.ampslice~ / fluid.ampgate~

If I’m aiming for an increase in accuracy of a small amount of samples (say 128samples), leaving signal-rate, banging some fluid.buf~ objects, and then back, would negate any benefits from the increased accuracy.

I guess the two use cases, to explain it more along those lines, are:

  1. Literally have a gate output version of fluid.ampslice~ where you get a 1 when it crosses the thresh, and a 0 when it returns. Fast and real-time, like a variable duration click.
  2. When I’m interested in having more precise onset (relative to the incoming signal) and don’t mind some extra samples in latency. Again, fast and real-time.

The features of the split up objects don’t seem to allow either of these use cases.

I don’t think the joined up object allowed for these use cases either, but it was harder to tell. This is another situation where it would be powerful if objects that make curves are split up from objects that segment curves I guess.

(1) is trivial to build in Max, except for the signal rate debouncing, which I think would need gen~ if you wanted a gate-like output. (2) is harder, because it sounds like you want all the complex state management of ampgate~, but working on the difference of two envelopes.

I didn’t really play with the original one enough to understand what it actually did, but did the original allow those use cases? I understand the topology of what is now fluid.ampslice~ but never understood where what is now fluid.ampgate~ fit into the equation.

The first use case would be covered with something like an output flag in fluid.ampslice~ where you can set @output trigger or @output gate or something like that. Presumably, like the Max-version of the algorithm, the threshold exceeds the value and then drops below it in a way that is reportable, the object just does the edge~ thing and says it has passed on does nothing after that.

thresh~ would do it in Max-land, but then needs the debounce stuff, so it would be basically rewriting the object, in Max, to get the access to the full state of the object.

For the second one, I can see myself using something like that sometimes, though not very often. It was mainly me spitballing because that’s what I thought the purpose of the object was meant to be (the onset stuff but with crazy time management things).

Other than functioning something like a noise gate with funky time stuff, I don’t really understand the point of fluid.ampgate~. I mean, a noise gate is cool and all, but the time stuff seems wasted on that as a function, particularly in the overall scheme of the fluid.verse~.

With the introduction of fluid.ampfeature~ I’m reminded by how useful it would be to have the “offset” of the internal thresholding be the output of fluid.ampslice~ instead of just the onset.

Most things in MSP-land will be just as happy with a gate as they are a trigger, and edge~ doesn’t care one way or another, and it would add richer output as the variable gate length, in-and-of-itself, could make for a useful pseudo-descriptor or for plugging right into an adsr or something.

But now that you have [fluid.ampfeature~] you can just stick [thresh~] afterwards and have that…

Would have to manage my own lockout though, which isn’t the end of the world.

Just curious if it’s a technical funky thing to implement, a “not enough hours in the day” kind of thing, or an interface/differentiation thing. Just seems like nothing is lost by having it output the off threshold (which is also used for this sort of thing) instead of just the on.

Well, it’s definitely not enough hours in the day thing besides anything else. I also suspect that without adding a Schmitt trigger a la [thresh] (which ampslice doesn’t currently have, IIRC), the offset output would be really (really) noisy. Part of the motivation for breaking out the <x>feature objects was that it leaves advanced users like you much more room to experiment, without needing to keep adding more to the original objects.

Does it not use a Schmitt? I thought that’s what the separate on/off threshes were doing either way. Which is why I was pushing on this back then (and again now) as I thought it was just a matter of changing what variable gets output, rather than adding anything else in since presumably the offthresh is computed to get passed onto the thresholding regardless.

My mistake, it does have a Schmitt trigger.

Here is gen code to do what ampslice~ does, plus output the state

History state(0); 
History debounce(0); 
History prevValue(0); 

Param onThresh(6); 
Param offThresh(-3); 
Param minSlice(4410); 

if(state == 0 && in1 > onThresh && prevValue < onThresh && debounce == 0) 
{
  out1 = 1;   
  debounce = minSlice; 	
  state = 1; 
} 
else 
{
  if(debounce > 0) debounce = debounce - 1; 
}
if(state == 1 && in1 < offThresh && debounce == 0) 
{
  state = 0; 
}
prevValue = in1; 
out2 = state; 
1 Like

Suuuper useful!

Here is an updated version (using the same variable names as fluid.ampslice~ for the sake of my sanity) as well as a “musical example”.


----------begin_max5_patcher----------
1894.3ocuYszbaaCD9r7uBN7PGmN1Z..e2zjI8VuzY5odotiGJRHIzPAxRB4
GMS5u8t.ffDTlTg1lNdhkL2E.6qu8AX9xEqb2T9.sw04mb9SmUq9xEqVoHII
rp84UtGReHqHsQsL2B1cz0MYkUz+y8JMeVthS4l+9ZBxPje7.iWPEpcQ5IVd
TXnhaopIIdrhpUD2Mo7ctN+UK6pTQ1dFe2s0zLgdE9jn0nqbBQpu7P9xuvXu
0ntcUCmQ64gTbk7jr95EWH+3pmi8ll2TejYLsTgHM6y21TTp03qQqIgdgAdj
jXTXLwCObgB1A057ViwIx+EFhR78i8aWVywFQJiKWBZsGJBGmD3S7i8BCepG
FmLpGFiLdKZ5m0mTRhmenOJfPhiBhmHDX1VMsfl1P6zU75jn.TnePHBS7CPl
sy3LAKsPKArWDIvOAgSfHQbvTgS2qlwucAtsLt47QHvoFj3GEA5.NtcA4zrz
GG588CwAdwseFcFbCNZcXh0OwI.7IIQBPHIAfy25GLFPMA1XJsjMtnDz5POH
FkD34GQRhBIm3K6TQz5HTPL.LBHI9XH7+Bvgb58P32D6EzGDCgmilMhGGqfG
EK3YB.kbQC6e0v.v7mJr1v1IiTWY+WmMq0KVktFDpRW8HgJ2t2KLwj9u4oYi
Y033mQMHzzpKN.qJx3q9xOv74KRamH78iiZ.QKQQz1fx4BHFKDQTQh.kIRHu
lJkS1Y.G9coyPKFSlLG.oudw8Qs2hFCSatdeWLWbL46j4lUd3.kKdBBlDLl0
SFuvyyMELJQGM87LHS3SzBaAnwL.7hZ.dgpDMbxqx.NOhK96BfKHRWjPizHD
MlR9zjHNxKsl4Fk7o0FC6NF896XMrMrBl3wA1w1sMzVM7ZU2kqs6aWTl8YZd
dc5tlr5xhB6fVVAK6yh80kG2s2lNkmtoft+oaPy3tmxPKESmSC0M6NTlOjRY
cNXTVTRq20NCt6m1xJnxNoapO1rm1rNksU93mJJKqf+.K+66JkMa6sOKTv3s
NLBhmpGcAlj4PYS4Qd9ZviCtY2ku2htxjmJZPzH+3jks64NJ++b9DLtx9ZZy
9xhbniF771s8DfmA+PCDjggx36D6c78wcY7ELNMCbCB6TE6AndFUAHydNo4T
P2W+EQOpjcAcSRg1a05tjiMCfRZcCqjaoi.1ppxh7JqsH8w+co5fZGsVRhw0
j75HUSkIcCOVIlETcAn2Gq0PpGB8c6OF.yWygqLI2ilHDsaUIUbUBEapRyZw
iMUqgno4.b6cHvMqTkX70HHbfdDRTuGQlioy8rf5PbnhxY7J.H.E8SEsFPG6
b51ziEhaGLsKY8n721plixrKm5WpkWLxrjc0r7RtTIFDNjjMhSN.lx1BrMF0
J3oUirY.RB9kIXB2gTbrYSZspDYA0BSBoLkkECY0suB5VQK6JFmehWTTVMMy
Z1t8mYuaJAlGN2Yq3zb6Qtl6s.vPbaS5cC81hzhh1J.CO9GR4rCoBp4FYDTG
ymT9FOjycivIG.5Yz6Y4h8s2+rmCrbVkAD41EkyY6nMhgzDo5p48TZDOpc5V
jNZ5tcqfdnp.rhgK.RQXMBnH18MsKz.zrc.8u6F6Da6xoCnetxpCKsBUwbH1
brpJFZSerJiSOizjyIoaP3G2Uuy9hHqLcLZqi7BM2LnnjbkVpxXY2mXsAu.q
kbhHFo.yzuojtRAlc2Ug4m+MHuWUzL+itm2g5qF8JTMkVXh5KuDqYhzEhamL
w8WAnVY8iNxZHzKQu68N2vMzj9ri7rSICEVu6ORKNZneC+2SqSO3X0M9RrlU
KCq1xWFXwXX+4Kk8maOQ11KUZjyG9.LsyO7CNLtyGskfjVmh37ymxxn5p8+N
3H+xMbGGvqic9fC98NNNxm6WEb9hKGpNRMQHWUqhH21M7uB+RKZn5i7FAnnc
mxGkhx5L69yqa26P6BqsKrT6s7PuybzF4hZ2au4JUW0IBFDAdRsx263tfYLm
o.ADJvSTe.OYFCZxLF7YSKFfZmDsi0yZF+lT73aTqbJeg+xWqTar9IAynTY+
XExQcmnYgRFR9i6Ff6ITmYBEswWmgERf9iBFuaHq+rqxoybCBOWcPd13YnCg
uw5vb7C9SpCsD0TVl6Dss3HKec5gpszT4r4vEj1CioUAaaaM8ejyHgb9zV35
j0NWG.WOZKLyETFt5XkiW+S4k2yc7hAJMEk22xGttePOA0Rjjl6sovK6soly
8nvApWxrWDp+dTV9Z0ILL0P65OEJzF.dBDHZv8vGO7OHcws+x+iFymqfwyPv
wuEBlLGK1qGw+lZgjwsP7q1BweKKL7sPxyBMMbQGX4UkvXKs3WbBV8hf80+O
hBWS17zRqq3YorwuEto4KZ7hm1kLGTIVK5WujvyQRjkPRj4HIukPRdyQR9Kg
j7mijBVBIELGIEtDRJbNRJZIjTzbjT7RHo34HojkPRIyJy8014hfmacb7h26
ZVcMQuUCFLq5UeCIqmI6jWasTnm75pO4UU+zWS8zuh5Se8zpWM8XuVZ4D3W7
0K9e.3LCj1C
-----------end_max5_patcher-----------

I can see myself using this in just about all of my use cases…

2 Likes

I guess having a similar output with fluid.bufampslice~ is not so hackable, since the curve/computation is not exposed?

Would be handy to do a similar process to above, but on buffer-based samples.

Well, in the first instance, you could use the code above with the non-tilde gen and peek~ your way through.

I guess I meant more for the context of having a longer buffer analyzed and getting the separate ‘onsets’ and ‘offsets’ like you get out of fluid.bufampgate~.

That’s what I had in mind


----------begin_max5_patcher----------
2048.3ocyZs0aaaCE9YmeEDFCCo.oAhTWr7ZSQ1a6kALfArWVJBjsnsUqLkf
DUtzh1e6i7PIYYYJK5XYg8PiKOjh77ctyKe+pISWj7BMeJ52P+KZxjue0jI.
IIgIksmLcavKKiCxggMcYx1sTFe5Mp93zW3.8+NNZIEklDw34UcFEBckr3Ku
m3WQjUrMofGS4v7YURMMfubSDa8iYzkbE+3L29VqaPdV9xevtVxeHh+h97to
JhUMSXIseb0Ux+bigfYKMOOXM8.v7z2RR1h9ErFfzANvkTUj3ulRUfX5zZtU
GDcckfx0i.HECHjzEBIuADxnOK35C.32hQ1jYd9n7jLN585.pmdfR5Dn2XHX
sA847K.XeN3I5pjrs+TCbbzCGutfyp3j.tDSG4+DGky2G1KJVshlwB1RUKLK
OY0pZ+AcBEePN3Y6.hCWOnkSCoBXKJGri0beG4vzHsbGXok8+qkVyrHmpzZ4
l.lbxo7lFwmsLrC2qUwEQg2JALQfQz8gzbdDKfGkvPsPYCgtK4DisnjeG0oa
N3r44ARJr+ri6zgGUQ.59bdPFWpZP5h.4hGd4AVD2wU5uMGjDp.uih.IZWRy
lgkrOQLJml9U3Nk4RlKA6njQgmrlFtKUZyXI9mXljEAr0x.EvuFfUeHuxbmi
iU7EH645rjhTcPlLzIOKsacmC1s99iekBchU7PiUkZc7gpdOTaqA1CsRU5XO
xtn5wGY9EIBzEDdKJ37DlNn3sq1gLQUEbZ1iTVvhXZysZXZxj9h9LSAPHyJw
o5uW7fObTDJRC3wyOQ+PvbvT0IwG7FwD6QKg4ZpNcL9TylzpPTCxmnToyl0S
9jlyirpC.ek.bxzUQwzmnY4h5cZL5ISCRSaPdRiOQJU9RBLQ92TSJhoHYWSJ
i9TT02aUSMHSfFt.JEYppoewqZKOxoIITTncQTsJBzOkrDnIjUgmmFrT8wg4
o2tS9KWyJYjqZ63NtpcwMypdO5UhIg5dcbxxuRCaxgSSRorHVZFMmx3Pcf60
cHcUPQL+wUILddz2.1.StUa+qJYSscVucheOKJHtFAqyhBSXRlXO0gjb0xIB
M6pNpglfAFAKHUyGKrGExkN5TTaKuHeQPlTaUFBhT0IOIId+tp+tX5JdY2oQ
LVKoHOIs6NyhVu4He6hDQmaO1bC8j+XAS06iBCC9i4h8It+3BhiK8Y2e5eIf
EsMfS4QJU.wptSUX3M4KyRhi2CupddRSOgBC8kzmiB4afEpowfX3QoUFQSq0
xgQqE6yXeZ7f046SIm+pRn2fTwhRG4G4zsowBTr+.DtHh8xjuI447xAVYn0T
.r6rzZ5X2L.3dzOVfv14tq2hzAQDaRWaxsdNYptBGpNwMrJ01AkgcXDQqJ5P
7+xXLCunP.DDoCYAoaYgUOfUcfTtDHOmsa+vEOfvcoH9rbj5Qkc2nhznmNBc
1eQ30eccryO9mhHZP5fvOM0DqDG3jE77gTmNNdsDb5hZ2UFUUNIg.A3j+P30
kj8JRFNkds069.5AVEMoLqfsrMYQNlm9mf3hJ5Ov9KY4fHAOrQj9YSRb30XU
WkcrZ0tdbazgf4xkmqcLkslu4ZGGb0LFs5ZfiP2cGxB8q+JR3f9olqfjVMif
9X6tpXc36emXJ+9CLDRnlvn6P3OfPHY6cipEqHXBtb.k7f7Kdf8Cw+nw4T0r
8.Wvi0SvmjqRioq9+99xuceHgUPBKY7FBm2UM0UqqU42tCo2I+LIUAVHhVvH
+.Z53Eanq3jNu8XCfItK3S8lCMrqhh3HVW4IfEW1udwPdRQ1xJW3xHCBcUS9
nw4r0Xbh3hByzOajR3svCVFvCNWPd.aHOX2IOTRTQYX1.SJk90ehBK1t8Uca
jY1ItuaS2+hsOjwV82t2+h8vAzhuEIjpV5.YG2hjsQm8mA6NsbS3pqOwwYzN
qn0TQbMdFJOXaptyxGSNQfCIj66jwTnE6CAh7wi1Vw4nEnXTrNbheiJXSwpi
eCHOJfUrU.QnCdgHAm5BEPxaMRCzsF5C9rDxXEjw1il0rBm5tHv4u0Sao2iO
C6pNv9RWWuQS+VBVTd1Rzhrh7MTsWF2EC3NDW.3ybTpY7HembB7KBZshFHOp
nehtWkLEDG2KVY40wkq893HWF68YpqhScRRipEvt6gTFEWTHEQma9k1PvFOS
cpSyGdAPWOvE4ovo8xN7Fxm2hsKdmB9v5l6NbFLh8qSVg110EVh4CpGzuY8f
GuVvJjkEpNDWKsh4gbgczuv3yZg8LXg82U86adcrIFrP6yLaiBKeWXvHHVkO
4E3GGQ7+YtGzzkLSkV.RR.sFZUkM1.j3RFKYlK9RXVHucu98DvC.Hkk5uaun
8rR5sLlqdfXpq7EaAW.CzZnkJx6zseoBYzjJDSjJp3mJmGn0P6P3XahTYHBh
HuDudkJsXmVREr5IM435zvXAZctNqlvasLfZya91pyRVUgaoJS1ZH3s9zPUt
7mWbCSxmXez37hsrIiqCwws8rpZL3gwMgSw9GiSK4NGrm7mJaIYqy0NetA1R
j8GT6rkX0qEAC1Rk6MDZMzAEMhYAC+9YVP02r0Pq0wljWSdDaCSDbReqzP3y
gMoLAr2X4cStD0ifMonK7fj4Eaf47fn1LoXBLdnfDwPi9N7PcT64z0sQnNn0
4xayNgvvmuahgJ1NxOisUwmTBAO0wFiOegfQNvVGHCTa2s0KCRtFsdQPsdMP
G9Rf59U.09E.Au9Gcu7G44Ib0Ot5+.vC87WG
-----------end_max5_patcher-----------
1 Like

Ah super handy!

These abstractions should end up somewhere in the final distribution (snippets or whatever).

Maybe. I’m reticent about adding too much more stuff to repos without much sense of how shared maintenance is going to pan out in the future, especially given the current focus on trying to ensure that we have as much parity between hosts as possible.

That said, feel free to shine them up and put in a PR.

Something useful on the learn platform – if we can be bothered to collate and flag that its not maintained code but community code – would be to have a “snippets” area where people can peruse community sourced stuff. Keeps it out of the repos but makes it more exposed.

1 Like

That’s a good idea.

Unless I’m gonna get into the core guts of the stuff, it doesn’t make too much sense to try to edit help files or add snippets if it’s not in the correct style, or going to be implemented at all, etc…

Nor should you feel the need to – having workable but dirty patches on this forum is fine. We can tackle discoverability as a separate issue later :slight_smile: