Training for real-time NMF (fluid.nmfmatch~)

Ooooh!

I’ll have a proper look in the morning (too).

will look at it tomorrow too - in the meantime: check the schmidt gating I do in the identification example (bird finding) to check which one it is - although you might want to have the singe, most probable output instead of the polyphony I make available in there… more soon!

Ok, got it working, but I had to massage a bunch of settings in places (did you mess with more attributes of fluid.transientslice~ in the inspector? I couldn’t get it to fire as often as it was in the vid until I brought thresfwd way down, at minimum).

Also, did you analyze 30ms or 50ms windows? (in your video it shows zero)

I still get some false reporting in places, though it seems a bit better with the Sensory Percussion audio.

Pretty exciting!

What’s odd is that it works alright with the incorrectly placed mstosamps~ in there, meaning it was matching some arbitrary-ish bit of time before the transient (I was wondering why my filter dict for one of the hits looked very very different).

In terms of the fluid.transientslice~ vs the p onsetdetector subpatch, was this matching faster, or what made you switch to that?

I’ll have a look for the schmitt in there, though I have to say, I have no idea what that example is supposed to do… (you keep referring to it as a “bird finder”, but following all the instructions in the patch still leaves me scratching my head)

edit: had a quick look, and it’s just a straight unpack → schmidt thing. I thought you were doing some fancy vexpr schmitt-ing.

Hopefully @weefuzzy gets back about the best play in terms of sum/scale/average(/noramlization), so then I can create a training routine to build up better dicts to match against.

Its very possible I did some massaging… it was very late and I did a lot of nasty, cheap shortcuts.

No windows. I’m using the bang from fluid.transientslice~ to sample the most likely nmf match.

I was using the DPA in that example so I’ll try to tweak it more openly with your other channel of audio.

fast_onset is fast but I thought for sake of consistency I would use the transientslice~ to chop up real-time audio as that is what is used off-line to segment the initial audio chunk. It is probably possible to tweak them both to be equally fast as each other and I have no idea which one is the most performant.

EDIT:

I just realised (as I was writing this the next day) that there is no segmentation and that the hits come pre-separated. A lot of the other reasoning for using the transient slicer is relevant :slight_smile:

1 Like

Ok, did some more testing. Some findings below.

It seems like fluid.transientslice~ is around 3-15ms (varies) slower than the fast_onset subpatch. If I add a delay 8 after fast_onset I get comparable results.

There’s probably some room for improvement here in terms of waiting the minimum amount of time, but looking at the most meaningful output of fluid.nmfmatch~ (is maximum 0. the best thing? Maybe it’s the most amount of activations within a period? Is there a way to turn the list of ranks into a confidence measure or something?).

Yeah, for the sake of testing I just used prechopped audio files, but there’s a bit of silence at the start, hence still using fluid.buftransientslice~ inside the p batchProcessFolder subpatch, so it finds the transient and analyzes fro there.

I meant that the p batchProcessFolder subpatch is analyzing a window of audio, so in your case you ran it with 0. (which I guess if you tell it to analyze 0. samples it analyzes the whole buffer? It does return dicts if you do that…

Ok here’s a new version of the patch.

The batch training has the sampstoms~ bug fix, as well as the correct window size compensation.

It also has a comparison bit for the two onset detectors.

And it has a list schmitt gate to help tune what value is returned.

Still not perfect, but an improvement.


----------begin_max5_patcher----------
9556.3oc68k9iiibkmetp+JHR3EXG6rTE2QvFX81dF6w9Ct2owzyAV3YPAJI
lYR2ThZHkprJaL0e6abPJwaF7Tr7VUiVoDOeuewKdwKh3c7We6adXazm7Sdv
46b9SNu4M+029l2nOj5.uI82u4gCdeZWnWh9xd3n+qQa+yO7n4Tm8+zY8gCi
71evOIwArA.fYmN5x4P+ym+7Ieyq3gGb9OSOUvd88IeVuyEmc8uDreu+Q0If
oG43kCAGkOij7G7j24cuDb74OD6u6r4ICgtzMzGcHbzFJ0kBbQbNlf4xi4h2
.dzAg1.t91kOVCsYdtpC9e+12p93wICG5IJHbm.T.4xZBEDfY.EdJLR9PZlQ
ez4gsdGetdFl+vUNI16f+Y+3O3ezaan9tA8k0ADnh0wtDEeRqxsOEEevSe0r
Z4ez.3+cQGN3e7bUw.uy9G28YmnmbNG6cLIPdQIgA67+R1kFFbzeWzki5qGU
Ec3jG5IBPnLCmiT3fP+CLtwlav.X2KRl8Ris1AJfvznWaCNSLoM3HtlCEnML
nKf3B3HDixPRlGB5RXGmQdm8Ojp+6gm7RN+gniI9Z13Q0GEa7jb0zoo3W4.a
EIqCAot0JTf5DkHHQEEBHWkbxDqPX6kymiN1Hi0nx.BcJkMPThVWPcxFHs9A
0my+nAIuFHoMGjSOGK.ipscF2c6LW24GwIK2PdmcBcBacHfZ4QjaeUvID2Fh
W1GGx6P9EMc73G8+zoXmewSPmeo7ST+ZMQ791qMkSk8XUMiJNccMzMEaSu0m
hj5MC9K5iAkDeaM2pq8n7IoeE+l3.uvG5bjtTAA9xLTeCRFmb1c5x4fC9wMB
kRj1qA84W05YCVgFCVUy..LZWhU4erRFz.NonijNBB8+nebRPTdiUeyCdmNk
6vuI2snfz+bj9AId75gBNZND35gh8+XP18itdTuXIycVxYWhM79mXYFIodLQ
68iOdI3Z+AciaJIoaFUXVxIuclaV0Zmc5avEEoAEn.o+iqomGleCijxIOGFs
6m82mmleH5j+wfimh8SjVK3cNk3ud589O4cI77GJzNKMX0kBEL2r+U2U+TJA
W6ipVwf27vywA6iNpHoBMLpCm8xkCYX3TZdVSeEG8NUyMKkWknTCmLQxxWR1
5EqZ2RUCj0v8v4nnvhm558E5+z4zSeJ33wRX54nSMex3fmeok6caj7jGZ6Yq
OSxGtbzb1ODpL+Kw6iEQ6ydggoc8K93+j2w.oRFeUeeM6BtdRipvWR1EGEFV
feMm4i0bl8RQ9c9uFr+7K5Wzlbs2xKO3TlH0CWak2G7rex4hG6r2yIEORx4O
a.8bG5x1ztzePZ96I0jUJdAEVUf78eyqjrvwKorznD4ZmyhZ8f4OdciFzjtL
r1pFH2LedZ1mWEeqYRN4NS1b0Tjgz.a+3O5E5Dbz4PhSPhSr+on3y96cjnhe
AB+3d+OkSoR5.Go5WFH9TXvjhCnr0o.9ztIzUL0H+sZktlVaCZVESiyBWqvj
KzsMFkmfVagVHTUNH8NkV6Vg1hCTWwn70A1BAlE3fsd.22IUWMBfkLdfEMFf
MUsBQqVAal.0p.WGkp.5cVbkH9aVMAr6Mzpm468RQflIFtbIuwQ+AVo+ivsd
zeXCi9qnOmDo0kINRq2juEGui6Ss.PZLPpsA0ZD.Z8.jhgBjldlSGN5oPsTf
rUvqNovay8Psh3MXzolITmudTMI5R7tLLKEZbJxPRinOGb757x9SW0QptNqZ
S6KMvsjFPyHMvrjFji.6.mIZfZIMvlQbfXIM.mQZ.2i1h4hFPVRC3FogzCls
xJOnlu79OXVafO3c9bbv1KmMciyuTQ8ZNr1sFIOGFs0KLcdrWG9rlIB+1arP
eWxuKG11x55UcIReQx+6hBMKm0eRZUrKxk.gbFgCnBA5w5ODlV3XpCcaI4TF
tT7YJXHBCPbI.BjPzWMfCQ.tP.b4XyyDf3DLAJDBNhxYx924dl4mUiUa7x1m
mZ1JeiLEziEG9O3G9Q+yA67ttTrRKlN9bQ5s40Tma1ZPHQ+GpHORO8MdkV14
b7S1x5MgaDSPu2OQLXf6LAips8bI2lI40Db3xgaS0rIq1erY9EhFJ+ZjZ5je
QK3VlRQS4VlhMq3csaT7Btio96e9lORTOVz1FSQDOLL9t1sJlflgl6FX7mBu
DreSImEw4626uM5xwc9NDBD378uJskN5UkdSGpy2e9kX+jWd50821e4ZcqjJ
3XRvyGk1nWqSZvGJBJmDAiKjp.ELNTnEb.P8YnSpjSS9byKAO+xC0niC9Pu8
kLhdVQDh1CIvvxSvdB7jlFcbnnWqgGP8VrVNYYXNdn5BvLA7vgKgmCjBp6uY
izN4Do+r7CyPaY5fxFmmzamDfM.iSj1AQvPrzrGYmYisPcdj7FGkHgjr8LIC
gUaaXfRmyMmvn1VBYyprwHXaPXv4O2QSjqqteS5PKHiAILRQJQ9NjX9UVqHk
NiapcXPx4eZ2KGBNetmtthaeccEWAV6rCP8HsPib621U576JsvrB0HWiHhVP
fH.yxlRi1.911P+ssg9uI1F5V1FfXoFEeGPqK+ZggkZz+0Zw+cl3MpBZV4VD
CrgI+Gh5xyrTUTVoYSCPL+avhAYgCGYg7EGYScWbJeCekgl+5+Wcs4p4mrai
Sve4ERQ3MJISAwBrbg15ue8nfR38RpLEI4hx9658CIy6yuCQ2IZnt.DzEZbB
BMzHfV.IKTG0+RnyyRUemFApzriQgrBUvlcyakgJg9GGAl.FJlfn5oU.wZil
w70iJcIlHmvP7nFhzcjhJovBYogkt2y6lU.SG5FdicMLqVmA95mCXGuWA9DP
y3CavdVgQlXtvG3JAe3C2gIPyI9fmP7oUGuEKF4vtDiK3XED.FqHxr3YHXac
KCkkyylOQfs0wLPyo2gfs00LTl9NeXAzVmyfOmXAv1VD24z+LbM.c2Twb5oJ
ZgNqnBvbSEVIWLqsH1JchEyIUXsz4b1SMCnsSeQwKLJduYo5g2YRCzLoAlGR
iO99zKgWWs.9S0XB4T7jl6.f37gR7BkrHFC6Sl1bkA0c4Y+d6Mc4a8mT9GCZ
N8.PAKmOer2Oz6yxVi966OPZecjozThPswAr6L3EWmjrlZSja1YdRcBkGq+a
p+eevNktKu3OWeb02eO6.X7HEAaCg6B.XWfY6SLKOjnYHflsA+gAmdwWsme5
sKFd0wE26c1qr9W0E2v7V71lDEJ0YKIR8Fs8v+hTgryu4x9fnMu58waSRRue
1WUG25U8yxoSouJO0EnNRtKHLJ5TwI5ImU1wyxYk8A0tl1vnYQwAOKGoJTs+
bQYYZhxy66+5hWl6NnkYSB18PoQXMOEIi774Wxx2JkeL5a77kio9YgbZ2jhW
fZuza9kbRkpM1EEqZsuNvZwGfVq1wLYgMkOYXXzqlQAywtEunjS9lMvs58q1
.1jyw9Rpnk2c6DXR3k3rMxsJ.UDFy4SHx28teNoDbH6+U2qPCSIuD7TdXnMS
NFPee++xduceoF+Xxs29eIjvMQnBFV16xRcRK5j5SSM5PLo4End6jl8VGUVt
qAKpvvhu4YLUxWCt4hIVHEZ9Kfx+luw7Mei4a9Fyv1fJId6s6mcdR8eVDlrO
V4KVkdB5y5Oq1LOkJPnw77pVrVWJdaY1MuqY7QHUJf47NNXXaOAbzXiIMQAg
KsGWTH.FFPfrVzeeZYBd8eaK3ZHgkloi.KbjRWzIuK4kT9gNF+22oozjBZHN
bxnBrbDjoc0DLwLrJ0FDCrPHlbJSYH1+SusRBv4cTve2C8M6GLWXGgAzXGw3
V2KO10VNOHNJI4KRMEsqapx7vaLF9uCtUF1UCuPWSjXAVO9ygYYbjFWLbUfr
k2YRQHgdXCFyLjJd83mdQG80oV.Kx9IO1EvxVdfEnSOGLrNwbvVZOroMUnk7
Gz5BlvkSgIVXD.wHy7ZEqnwZdGoQfhd+.JyjcWW.EsQfhc+.Ji2prt.JVi.k
3tATjzP6cUAT7FAJ26GPQoqNfpQUTDwcv32M4zjSVQnTii3Q3KOJo2z4L03q
ITB0HJwtGnD3lN70DJAaDkn2IThbK2LrZPoFAIxhCRTie6ZTdCcWXPpf+dXo
SOTYQfH8YswJ.pj4dQhLQpc55bP1Ty9cl2CRl4o8LIfMc8A1bjwj1UEXmrK5
z0zzR6grSrDv8ysW0jZ5+YcvqvvlsFkYBgEv0+b+Whse4WrYo0rKf3VrkoPI
YQEvr0qb0Ddg+5u3TZ9R8FPIKNfhwlE.ldywDVK3Y9rpzHVLMzxOwhLoTFDZ
MntPK6qYuH9hCDn7qrwHrBACZls3Io6OVOmMW35QZUmRgz3JBAniAX4KOtp1
eBSYlRatovc8fquaTCQItC64SJVhA3rhY2ZAK8NGse63vS3xqLUfLxlFepyp
zbwWO34xuCFW6qu9vyTcn5rFn5iQgr3kezoLI0TGQ.fVQhpaSFkfJlb+DTgX
qSFBvU1jyw7U2jyk8qx6xGeML4bBrgIm+NiGU7N7XledFfb+lgd24GftrEGN
3rnPlGpfAitxJL64QgVyS.Lxf8EQiuOHHiuDccmqfD1lt9EyYjXKrMFnEyYj
XKf8gJf0Gbsn6KoQfKcb+ZMogHKczRKrNbxAqVRSulIKaKJ21fLWLmYsCNvx
3IGOmURDlsXgxA7lsLR.y17nBawEVrmzV7t+VSZPdyj17nO25zyCZNKYQXaq
WP0XkvLKVYMowcWZwJjnOpDlsTkBoOoVI38N40fDyb4dBYyHE7YlHrY3JHcE
T3qfy4XlPZursAMWjAoWjwrkMgr09X9bN2l5Li7NjJ1fitXA92HoHnFh+9qA
YIpeUiB90vu+kf86KDQz8HogPfF+1jYJfXKWMu5i9e5Tryu3InyuT9Ix46S1
4E5EqBc9ak7G6PBn6.K8U0kwXfb5L.BEyORez6lH1XRcPsVkrxZ1kHhp3hUH
rtyp3XlJTWGknt5VKLy9AwHaDTNjeE7FR5VpPm5q8laoe8G8Bu3G8T0D5vMT
HC.ukFGtcNYKwy0i9EtLIpcNvKrJfV3pNjVAaxAh08TxxMS2TCl6ZRdIJ9bY
J5s4UBNH0MMUFlfab96UsnN+KwdA5LRSMo1iq4so7a1fdMOGbsLrN2JhktqB
JoHrKUvI.DVU2GQPSdXs4RBDXdK3fmb1pn2eLNZmT27+XT39N5jtKz2KVUhq
pMEm06JGT5tL.PaHLHDAX.JgYp7X3tphPn++ubkBRnWUdnHcyYPo4BquUGg9
VtR4a4JkA5M.+JG9fKoHCtdOHGHvXQpItObWOdt61KO8je7WbTMDNH6RdLs6
S9fgtWjBWnwdc4PmBDVPQzr78mQC3JInrMU9SIvUo3epWvNUOwb0ATHDfc99
Sd62K4V44HB4rB9Y+Wcdmp9fZ7I0spr2CXCIeEBErQTn7gBkmcqRUu9WpmSd
hqPYDk2fyUN3jIO.pkX4R6WnDHzUvwfzAtSSaF556xJHVlt11b7vSxFjWhNo
gKLRik5uyj.4SOc952Uk1C8PjIJtv46kMp+rCTdMAgxyHeT59FMB1HaxQN8A
sYT8n9blQl2TJLTtR48OlIzYYp.max8NOIgg8NAGcRFVRTRzrJUZGZKR0IPE
aT0yajf.4tYxjqHmi9TrbDEmeWbbTbCduAevhJoX.VZPsqtplKbITLTowjYi
C3sPhMI9gNXqhlglcLb1PG5kYJqPJOoioJ86RYDDCxgpJ+NlrdhNgm8OqVc.
mDuCmR5tPC0JXAFitGUGHlXiKmQ3.WBOKQKamOchWVyVzi7Js9O9bxDX6Bev
9QEy0r.a0IkAAqoffwYqSfU8EayPXl6PApLKgcQaPb.00Eynnr5Vu65oNnoG
p6jYgRb1Ge4Ph0xZMiZM2uDaU+Rt6FFUZaLTkP3ob.FpVZ2UTTVbx2+m6amx
FQK5HQq5FVLsNDtVJJivAOUTFaj53qyvIzJxq8adVVWmZUmwIQ6YZL9XGkDQ
1fgxgIQxNjtPhbppJvisvXXaSGRp05bji2QuvO+W7sJK8zGbv0DJho4he7Bm
sFFQkkiN3JKmqYrbLZzUVtlaZlixLWKczNjbNRaz4WrLWS1tZaHdvhSFrs1t
U7kNq7M1bjKYtRQtoJeH4yiLjUgxlcdg6tnVLWof8YuPm8WLqqReW5DJc3U8
P8hkvUfSo0oR.V3kQoMjxrl.6tDGKuBmhE9ihPwfmPBgYJB0Ld9vEecrHclU
byWkbfit77KZ.HoIDXvykMsHxR4vMRMKBAlKRWMYHbMgF6h8Ufg2I4rMjBF5
ueP0EwI5Imcu3c7neXhZI1Ly4su8lHC1LGYOHSvgIL4obJdE0Exa+dGU4FRM
H5gKgmCRQpghRCtiFmaxtRLHZCiQXbjfBSWwDHZMgXFSMbd8knP+TXx4RhZW
IhNF9YmmhiN37Gchhc9myD65MJN789gpMalfgaHUWNW9JBFe8E+iN6iN56n7
wME5UiMb1.V3AKxAkScyEaxGnnq69xpAgT3hVmtTokr24v5PhGgnjFKLJsXq
IcVuD8pyAuie1Lf2+69BIngaWDJSfAQQa3k5ewrp6UIF5OeI4bvSA6t5bIK0
tudx6RhxBSmcgQxurOvKL54du6bCuvZmUTJDafkWnW9WU.Yhenjqb7bdJuef
YODNb0WDVZ8OQrQTdhd1YjwZACyL5vfkklqSikFj9swBvz7InQQ+Zxx0ZUtm
eycGJSSMUFGdpE7nUDOW2jZapLlzqYqXx1oqQVVWZGjs0oJLpptnlp9a+SDA
XSBjwrxZokFo0QwXQskYaGex3CO3UrWU9aQoU9CDBSg.NAYJwfL3ZZqECT+W
maowiE9Siv0fUYhkV.1DbIVOag8deolSkuUOrpOFbL6dQCvCkrd1+mwAOH9X
6rQDvMp8ZkxDXpw340D7btOc0ZDkFsJIBlswsx1HRWQE6oSd+rixW+BNp2jC
GnCbfE7ODdnaHMIMSyViLED82L8433Qtt8058LqoNcl0s++3ghgZz+wCM4Xe
CdHLB1z8pNegNaFnqBW6KXvNv.GNFO5Sm2lUtuGgCnB3s3HZE4Z8mbTwlQ7.
8UHwPgGUpXTI5Pbq3r1BStouK3o7y+VzVUDIZLpqZJxqJc60EAVMDEVMGIVc
GMVMEQVEhJKKhLqRQmUgJYcZjcfYkV3h5iOKKhQKahSqNiUKKiWqVhYK6haq
NhcqNieqNigqNhiqtikqNimKKhoKahqq9DaWsDeWcFiWsGmWsGqWsGuWsFyW
ME2W0G6WMD+WVECX0GGXkUfTVKcky2k15xiu6KkL26jTvwhrPyckkABW99aZ
z+FMIRZpHV9OHxUZ.fP67hpfjkxgDDC6BY.0tLJ0yWqO601ndEF4q3neyL9t
K5v1fi9NGj+HwYiygjbQFkCP++UPtlVL5VbN91ZZHUdAsncssfRoZzgWQoZO
ZaUGS0zxcgbhPMfsxywM5ZwzNabQ2+F2KG+yQAGcHOXUSziMDGCUlzEYz8j3
fMhxnMAXBOenKU..b4QaZszpAro2evVaYoy2axCENu7x2c3v2kjzIzeMLHZE
ygsi4ntw7bAEnArsCXWBo3xtMpk91Wq9xeqtQZ6XDAzrmj1ts4U7nzxDT0jv
6WAvJbrvJzT3sVBbcIDWqj2mqfXnYwTCNSapADBwoGxZrDL0xnEmmQkjFcUH
ttr4UM.c0DsYkz5Ul0vMk54xkr05kPvfoPPeoPvBSgTbOnPF5NPgj9PgYryh
RgYIKUqnPxciBQ8gBQ2CJD2GJjrvTHrOsxnt6Km6j4WVqtxrfkWSuAM2+1yz
fkVdf2VkAVlnE1DGmRyRASPvBSYC2+MQaLQ7ZsgAKDhWQaeV5RhH+SnZ0EGV
7Vgm.nhv2vfPNkh4PfYyyboqoMjcqr+4VGcJSy4ZhSy1Hs9wa+Teu0l80pfq
nwFoL0DPwXWaD+nKq3m7uOE7ogI8gcGIJUa5PPvWOxdp0S23HrZuyZb0sIzX
EppM.9bAqIGURudhNgsBTl0brs7rABN1M7tlXvlt17nqw5jI3Q6JNTDaCR16
Soex9f3GsbI2Fv3RtMCN21f3jMhFsifH1f4zUDNMNTBNXX5p+SBoanLByMWN
sYEIIoU3zg+Bj1eK6+ase2fSsVW62wAkCcRtM3EYYvqX4qz2IUMcW4KI6p63
CqyWMVlxWZs3WN3e7h0hNM1GysOgst2kyQmhNcIayag1nmWQQFR9e+27u865
pDsCZJ+lgX3MBKztUvy7LFQpd2+f2NUvok7hye329cu+eMwON48wQ6iCdN58
+zmOt68+Xbj1eEd++X3k+gnev68+ndtsIu+e12KTs6KNGO7z6exK4rygT598
dW1GD8dUDUFJuvBNE1Y+CoqY4C.ny6b9idwO6u4UuOpZNdT8A.IO7O3uO3xg
hGGKO9OcvKLr3gIxC+iJjWeXKKyASfOMs02+TS96FcrizWm+tYUIjG7MeVxF
eVBkl3RPlHUKMqZPQeyok9lSK8MmVZk5zRp5nh2y9M5K.+1+o+O+tw4tRid+
9gtha4.JB9qGORxBO5thMRid+VMfETZACS9O4LRjV1PZ04tayAuuef2ducew
A5fZAr33wJZkliVMtYKk90C57K+RmcJqozV2paxOB.rVoMWZcdK+J02A+7tP
+u3HDfIAVASCrZz3wXqHMdcMbgRXvg5.bnfwMpQgj.6vF1PkP4uBhzudF1Ps
auV289Qa76I9DgkPDV6LODLEPEoAYV8445utc.ONYzdJlAwP36qG3sXd2Dmz
GOyws1KtZIocQbUhdQ5j1obvxR48wkx33UEn2aRGtZP893lbY74x5Het8oyH
+dPg79hgKsyP1GkBvu49TCeq6zyR9oqoCecshB37Nn7Cni5y+G6M9V06Tojw
j7eefY2B5XytETNaCTZAjK00kktoLX7ZL+lKMf3TTh+WFdtFFOZzhAEafkRd
k.wJJv6qVMFzxeAcjA8aDxZ1kfX1gX0l3KfxITaylRszhX2khgU+jgQiUDlv
EaTwu.BffDQpGPXRF+kietYr0n6jReaaYOAMz7RO2kXRSbiOwz2dNsqRrurH
fV6oZc7PQsL2vhOZPq6bjVkoBNA.WkfCp.rL3QEnlRJiRlBA..nrOUlqWYEH
AZ.jpOeANGRTsCLCNuDlkZMlZfo1jJXaBL2pXtUVufaPUclUmCvpXNckYjzT
nHTzT5Vat5KMHfVRDb9LREppMWwIy1.UHfyMUXCVvXyIUfsUrXVwBakKTybX
9nBfsRmr4lJrQ5jSlQpfYq5B24lHfVRDn4hHDVhDDwbBEbakMAyIUXsNq4re
Z1CuasEyIQXqxB1bNTlsijglSMVTakMg34jJrEKlS0lTaGNkNqMHnxguaSxl
U0scHX+oH4rXSxJyNZmH.aRP4HSF1s3u3XyzrbQW+0bxWDaZhoyM5ZiflxE8
K0LTFcSK5tBSZAO0QCJ7KpIu0fkvpdgOU+bNYLqrEDM2vK1FsItcI7RLHopP
8HTA5.jB.HBARzwA4FZsmZlXKh0ZFlSvkf5gYcj4hHrcjy4zTFrsF3xmyAsv
1NzIFN2TgMZzfrh6C3zRE1ZbIeN0tis0LB8XmyFVXsItypbgs1QvQyMUX0Dh
gUtvxCH.MihxIzxIGeUZinyyQUdSTobRLiia3byId.ljAHwo6q.SEfoE4YDZ
idkOa4THWXk.2xLrZ0yLWXg0KbzbZuMxZs3y4bAQ1p+DM6TgUSIEOiKZCxZa
LlSnvVS9HzNsjU1uxj9.XajcZgXB819fRM6aQMmatXLa0.gmyUGDAmL8fp58
VpZKnTWGNyKItoMK2gmS1ANMrCAb+YGaMlaNMfA51mc5o3JKT02FuOjVMKoT
UOFc5IMaL6CMmKkFz1gyvr4lJrZwdlSSfg1Nc.7bN0HHtGaGCdtHBXOmwbyp
IYLTp0uFGhvj8KJ8K.M2haV7WYKMGDaFadFWZNaYZVyC3dyoBzg+ZCdUvsnw
VksC9Ic7O+genPxmHK5sqmz297SAgg6hBiZLD8y77mGLWUgvcO699SN.ctSB
Jj7yFIDyQL82jegRK6K5l6ClciDJwEfTWNggjymS+MgZHO02.0bqnauS.z07
l.tB.w7M4gfx2Y4a0SkJHzN2BuTvJqJ16QwWCfdocYEtuKmidN1aePpGh.p0
meeLmzRr7JqKpkePWbzy+LpSZ6Zi5e7xNOaaH81sS9RKzffQRfUiHDpDczei
aNVIroXCIgSgXcq.xEKbMeSNiRVM231mKbqt.k+WptA48Q3b82HHWt9gPYEt
W+P+CkoYtfwLWr..EBy2jjOBU8ce0m3J9DPRBUyrPFGYDgD..jT8An7MS889
gfipLMg+UwJrKBxL7clrIhKsQupXUghNfra8+zI+iN+j2wDmex+PvVUBfqDf
YeGtqBcszmqGx+E60It1WSnVEDg4a0xik60wxDmTwvJia9l4o80emteNILPZ
u1+tJcfXamubsI5wXJ7Qd06y.8dv6SrB4XjdqmvzzeUjmmJI0ZW8Rrorusc8
rzWa1GKC3TxgVstkTpHDop+c40apTCPnvkhzqD8vsS78.0mbMR4zqjoSn525
PuBWksgzpjp9s5u0uprCnZO09KQT1WZ6gzrt8OmsVRbB6tDRxlfh3uO7he9z
0Q+MmQkESMC1bkIzIBV3BxDwQudbTbwMZmdUmBdg4h+gO6MNl.fjV2YFrfiw
HSebjp7TrbLwuO12ejbgtUPEe9Xi4hJShVNF3+qeXXzqihCDRyx4FsjPATqe
mJaYn0akZtDvERcg.fXtYzKG15G+6kFAOJ1Tmsm0haToQJTMGCyqceVYhXiA
g+9B4x4dn2kQXLraZWDd5bhjMRt3NmN0Bv3oOirGPWAXaJS1Xf0VWP01Q.0V
NXZMClp+zztnem4h0DCMTLFSxBfiTtHehtsRH.UaTxUHlTxxEK0FOJ0F2aoq
2zFLkqZiukze0NC1sV45xLR8jUKZTXtLvZghBPKgeYsUWrZSwI0F1MFlBRva
HboNjqYFxJQnZcQ12DwqokZMcsg.KGMUkFIUrpyqRw2GcdM91j2rEHDCEHDx
VcAQH3L2zcUG5hlArnPrk1P4znPXdaaszHOLHP8UzOEFjp1TVgy4W2mSo4.c
fBnIriN.7c.3F10zfTs4FIqYJLqVYbS2bDXR6Oex630rws7RUaVTUyTpYxa0
lAsRe.4YuYmmSOZrTi5dStrjjdHUNSM+kT2LuprDhtLfdYntMmaaNTdfo7z3
nCnUQNp24qw.XGw.agv+OK9WaKgM2y1DFQWeLuMtBxjBoHSqtVkwAFacxXgc
dG2+Y4GlTkZFwmYGIoQErO1fRVpMXSI4g7MylIN08QxKLj3eyVnLjVkcdCTM
fWSI002hnxFDdmC1FDFb9yczT4l1QQUEW3BpPHX7TGvxT9CYjhTk78Iw+b8x
gSphxFFtvjFBNd3Ichx9KNeu7lz4U.xvxIA2xEA1L.TXPx45G9k2WUzBgIeI
hgkwap.NCC+1z.OnMN+PJ0UyPOPvUFK+TvPzMspJnPlV9O3G9Q+yAW2KnZCd
dfImbholRoqKUvI.DlnVHWhIwK.6TEd9L.8Pvn748d6x48EwJ1Tp6LU.ABb2
ffDDkgDLFR9SRskZh5SU8ERV7+1e72n76D.Cjk32+oKGeI5hZgV+Omttn+pq
4Qk1SXEElxRusiOCdTU9V4rV.TJiklIRQtkyDoym4qlInEIMfE0BaWJIhVTp
odVG2Mq6Zp6zDNBxxxZLHh6Ln7XbcLH7oregruPsFUrR5SnWxnGZyzhFs8BQ
mTauDYyhCiYPALq2AELCSqooI5pFDnP175W.627ZQf9pXHkuojMD.m5htIff
liwUUyXWMc9uz8rVa4KZCKZr+yULyLY4qirViIK06TA5jKkd+GTaUtYqGpdH
LsvwJ38J0VyeZA9ErhSCCa50xcy8HUIGnnmdRZKYI46bMIrbMI5arXRJwzBU
1+lRamplTRJ3bi1jwOe3kf86SKUC0JbX6qV3ZwqFOKu5ho6hlbIU9r7tKFqB
M4hwE7d2R9a5vQbqd0t2BqpA+lvDadSzI3MUz08sHqkL32Dzl2TVrRMt2DvF
3ysPXYUxcoWh28jKeRDV7poz4fsoPae0fo9UWLbxZRtBLARvLqvW2I3MQcss
uxneS1zvQnyg3JEYKShFISZ0XFr4P3DYSCY93Ya3cCr9MMV0qnBQ9gEQN0vU
lZEOMEuIlMRH4SPRCWp2lgAo3I3MQrocRflp2Tm8ulh1I6FhadFc0JQjov5O
hUV+AHSAdZiJ3IwhVrsn2nUDBrgmlBKZw1Bdid7KazYflBSbPPqE8fSwqBZ0
qZz3mMhDD3Tfe1JkOVVBZihvIQ4NzF8dyhk8Pqmu8jqrGRVL3EYi0TfIYZwL
ajNmhgUraVvkL55ZSGdAd2kl2y02MYAd2vF3aTkUlrTA+U8ZKUfeKUXeqVPe
atP9Vt.9p83wRAWog86HnJK45m+021TTTj4qj0G.kCI3IGXfSNvflr9.kn4f
jng.jHyeNe7sM6cpE8L07xh0DLj02.L3.fbPA+3PC7wwDziiJfGGcvN1i.cz
pNCkCkngEPOCLnFGV.Mtt5PTMPEquigEAm3nokBg1j08O6NvCsMnC6a.GNIL
bt.KrSj2tfIbRHqBakb8DVuCTvQzit2AF3.CJvAp+XI5RWr2gcsh4CzOKjt5
J39FsjU0f3y9ggsIv8lJBLe.5YMEZUP4MQTX9fuyZBzp.tahHvBAVm8TXGAS
2DQbECZN6Gowl.kq8fja7LPkfgyZx2p3.azDXk.cyB8NVFbaCJv15GCYlBo1
uhTbjxEuMWtRy6a+ue6+OK297uC
-----------end_max5_patcher-----------

Actually, I’d defer to @groma for a more authoratative answer on this: my inkling is that, in practice, it probably doesn’t matter so much, as the NMF normalises everything internally.

If you were going to try and use an ensmble of rank-1 decompositions on the same sound, I’d start by just summing the dictionaries (but I’d also check to make sure that there was some degree of consistency between them, so that summing wasn’t just taking you towards a flat spectrum!)

Hmm, by summing, do you guys literally mean addition? As in, using fluid.bufcompose~ to write all the dicts on top of each other? (wouldn’t that create a proportionally misshapen dictionary?)

And for the “checking” to make sure that there’s some consistency, do you mean “eyeballing it” (literally looking at the buffers), or do you mean something programmatic? (irstats~?)

Beyond that, I’ll see with @groma thinks for how to best approach that and then whip something up that fluid.buftransientslice~s each onset from an arbitrarily lengthed set of training data, to then sum them into dictionaries.

Yes, adding. A dictionary entry is just a bunch of spectral magnitudes. So they should all be non-negative (unless something has gone hilariously wrong), and so should just add constructuively (i.e. no weird cancellation effects). Like I say, I think, having one entry proportionally bigger in magnitude to another at the outset shouldn’t matter, because they get internally normalised. For example, if you look at the dictionary that gets fed into @tremblap’s guitar-pick example, one entry is always huge compared to the other, because it’s made by summing together nine-things-that-aren’t-pick.

By checking I did, indeed, just mean eyeballing :smiley:

1 Like

Sorry to butt in,

So when you bufcompose~ dictionaries does it automatically normalise them when summing or do you have to do that yourself after the fact?

It doesn’t, it just applies the gains it’s given. So, one could scale proportionally on the way in, or just call [buffer~]::normalize afterwards, if you like that sort of thing. One reason for this is that for buffers of things that aren’t time-domain signals, there’s not really a sensible & universal thing to assume that one should normalize to.

3 Likes

this was the second reason why we created that object :wink:

I tried but for some reason vexpr does not behave well with feedbacking its output to the right inlet. I need to investigate that further.

update this patch looks good but your Schmidt trigger code is not doing what I would expect such a trigger to do. First it is stateless, and a ST should be stateful (to know which threshold to change status from). I will dig my vexpr-based schmidt and add it here.

update 2 so after spending so time reading you patch, I wish I could download your files but you deleted the links - imagine if you had put them in the folder made for that, I could have retrieved them :wink: Anyway, the right side of your patch, where you post-process the output of nmfmatch, has a few errors (the trigger is not Schmith) but what matters most is that none of it is important since you take the maximum of the stream at the end, so in effect, just put the maximum object straight in the out of nmfmatch and you’ll get the same results that you currently have.

Yeah I know our schmitts look/act different, but in your example, I couldn’t get it to schmitt properly (I had to go further than the low thresh to get it to turn off (with a low thresh 0.1, I had to go to 0.08 before it would turn off)).

And I’ve encountered some weird vexpr shit too, in The Party Van code, where it would throw up a stack overflow message without being able to tell how/why.

yours does not have a state at all as far as I can tell. mine has a slide before it to smooth (fast raise (1) slower fall (8)) so that might explain this? I was smoothing to get time hysteresis (avoiding double triggers)

I cannot find my old code! I wish Max was more git friendly for that :wink:

Mine does switch, but I guess by ‘state’ you mean, sending that value the whole time?

I thought it was the slide, but I went to the value and waited 5+ seconds, and it wouldn’t flip over.

I think there is a misunderstanding of Schmidt triggers here. It might be me but here goes:

  • when false, there is a given threshold to be true
  • when true, there is another given threshold to be false

I don’t see in your code how the current state changes the threshold. In mine this is what the change message does.

<pre><code>
----------begin_max5_patcher----------
807.3ocwW0raiBCD9L7Tf7Y1Hay+6g8EoppBHNTp.CxX5lpp9tu1FaZRJMPo
jt8.xLLy7My2LdllWss.YMGIc.me6bmik0q1VVJQRAV52s.0oGyqR6TpANT0
P6qAtCe5PCqNkK+PnVRKizQn7TdYCUJGokWtWYdS1S+xyXsvQkzJBu6TEaSY
o0DNg8.gllUQjeCNgyefQx4CQNJJdWfqCFGsKHzON10I.tCJErC5bu11N9KC
NCbB7M8bC93Q744OVRKlx+gWw+Cth+RKYvHALNfrTZAv4doFuYaKe39ywy92
JdFBuo7LJF9ywy7lhBQ7tbVMdyYUDRl0dAicuXeUV6+EXUzUXUi+Cuh++.qV
R4qiPoj+JnISTxIG4C7rSF3ijIBdc17SXr.UehGdrOQ0l.2H9R6cTxE70U6B
WeG3WivPqhvDSFg2NBS68+yD1ebP6lhwvSxX34uTJSgPzMgwLderd3glmw15
qj4OJJAjonLuU0jMLmAGGsZJya1oX33u7NXIs49MXu41DeBwgW8tguyVyglo
DEcr9ElJ8AUkzK++AUPJkeNG00zyxMtTm7Nui5dRGujNtH8t2uLJUZxxvRAR
tzXVj72BfPK.Hus.nEwcaBRRmfmCI3VgDZNjPaERywdwa.P9KsCG8MAxac.M
bENss8YBqSqsBCw.smZXxWibUuVRGdUMvEvHOWZzOPIIkIlxvEiX5YCSkNFN
7qI.0M6ILZeoZvlsL6r0SutXrAULqSYpXXZnbBqJaDIygz9J94DfbkTdSUC6
gRpL10bgY+g9A5jgZo44hUPJaL5pV3D6kfQgxSQvjXn+4VkUbhEHsO0ODqhM
joqtXwDPb4fYPsH5UYO7hh6YIrZ5+0R4yBcerW.NQFCdQ3.e0Ibje.RG9aVX
US55RM672pZQVwgxppwDxZzWBmo25.JXo6KITMkXxezXsKT7Wj6jmNAJsYXi
YQwwBlycxSezLiU3DHJQ0i3o6QjmDhPWXkXG4.IiijIsVZKqosgYtMJLMYT+
dwulzjn5Rg9x4mV9N+1wxphCazWb2kpl4KZqfX0IQNKh401YIr4M6+w1CdBH
-----------end_max5_patcher-----------
</code></pre>

In this example, set the top (on) threshold to 1. and the bottow (off) to 0.5.
wiggle the float at the top a bit between 0 and 2 to set the params (I could code it better for change of values but for now that’ll do to explain)

with these thresh, when you are off, you have to go above 1 to become on. once on, you can wiggle as low as 0.5 and you will stay on. only when you cross under 0.5 will you be off, and then need to go above 1. That makes the range between the thresh a DMZ. This is how Schmidt triggers are working. Does it make sense?

I follow what you mean (I think), but regardless of what I set the thresh’s at, I get the same output from both of our patches:

(actually mine outputs more often, so a change is needed somewhere, but without breaking the list-iness of it)


----------begin_max5_patcher----------
2081.3ocyasziihCD9b5eEHNmIxO.LrR6Hs6dXtrq1C8gUqFMJhj3jlYb.D3
zcOyn4+95G.wPfDmDXmNGRn8q5q9pxkKrc+8Gl4tJ6UZoqyu37QmYy99Cylo
JRVvrp+dl693WWyhKUMykmsaGi5NWWU1ANix4eMmpGC2jTtqymppMOlu9ojz
cKKnq45Ff7QK7m6f88W3G3EFBvDHHBSDkg7V.ze2L.oG1mjJDfRzvpBS1n.R
1pO+NhaijJh2S4zhkzz3ULEZ.GGDML0ihrve7vCxulaoNmReQHsZYwoupTF2
bGVRI+w0OsOgyGjQrgNPgmRGPBTwGng3C7o7ANxsek1DAzhJUsRWm4tMgQel
VTljkZz5Ytw44FEOynKRB5yYpAJbdSQIo5h.MEUPeNot+nlRiKD7.WPBGJTr
j6qAdtGGlrMzhzCIMVKkopBRJiRpvVWlGuV2Yosqt5iLanxaBhhj+D3Aj+3E
BNRlBi9NV15uP2XBY2rbZZRZdAsjlxi4UXuo5MzswGX7kayR4kIeSg.nvD0W
8aqPXuUJ0AE7+shjXViBrqHYSVpDDsrDxhqE2Gcf9Jcy2TYTsHMNumNK7LDz
x.UVJTxCkqhKjFppYN0VJwj8LV6pZ5GitkWUcdRZZGVjmkObkEI6d5L8cUln
x8marU0Tt7Ppt1kBeB9xx3may17XFqZla6g+03zj8wbJOQaBPflJ0QOdpbcQ
Fi0Re007bO0rQ3iul9RxF9SJAY5LHZdRdsSjaiUdSxNZIucY73cksKoj+UMo
aTzgUUygWxo6yYBsncCZEO2bBqYLtVketXcsi2UHhnPc.l0cZzt4FQ7zAWFz
YefXhPuPUfu.vh.wGjeDIvW7ib9a2HhmFUDYTgQjQTjaGL0yr2SCbhpqPshQ
UnnohYgSMy5qhBh7IKH2GaBIukYy2+qhIgmkKMyR49bRQ3EROS8pM2DWhA2D
WB+ehKmdprxqrhIIgpDhtIlD9VlI4NLG1UNCuOGuHUZgPfh0BgWlsfCDQD49
ydh52XN6Dg9xGMVAi7skUFZcB3aAVgIRR6t4DjOVRCPrJEXL41W6D7VfSDuv
PwUuD4Yl.ooEuamVfQ++PKJfbd89R5LNRqrpXF3luGVkACDg0eXU1LLy5r86
oosSvUMToanu9Fjep7Ite9IXj3G3aK9wKDMN7CYj3G7HxOZL3ZoGBwVJXfkc
wgCSAf60E431AvRRG58.UZmr994lxrCEqq8LpMZNsUTwK1xSRa1cjOdLSVGn
ymrx1b0nHvRTHyqQ1voAE91xEvojKfVhBHYJ4BfsVjnIDEpAGZCJfSIJP1hB
vTiBq7KlTKhsdmxPgSGJr16bJmoVSz1EuncCyJ1n2pd3OYnAFFZfoAZj6eNc
Ug0mbfqb6g2rTuU3Ki47hjUG35kHMOJjqZKa2wxVEyp1P1l87nmcz8gif6JO
5osrLQNBMGykwwRXlbR8llPN4Tjp2bEiCQp2WaZUb5tydRUPOrVF91HiKcvc
XaN3tsYE6iUhOn2S0B0CqbqGw2Uwy.vjyyPRzXvydu0341Ge7P7LDpOjXhMG
R7UeFzjfQ7HnCugifdD4yANZZtypAOP5K6BhTtfXX3PDz03BBAtS8AweWZaj
5UaGKkEN4J66cfKbuCWe0I.cZvE7EtsAndTVzjqrqeRX9F91lHinJU441Nou
uKZwMDVEh6Wyw28JO21hFZyZnZS9tA0AMJqRXn6JI2dOHzTQ2LAqHjSyd2Lk
ygxKsUBrcxI8DifsRtyn1unMds5aWP1phvwVE8rUxnQmbsPxPT+5Lbx04oQx
PaT5vQvgRIH3kzQ3XIIzkjDXLjjMABpY36SRPalULFBBXgf7FAAgr0kGbdWd
cv7N2EPoP6bG.6b++N8t+M789q6c9S8V656+TmEPNdyBNrII6Q0kWa4eQSOn
WBq9J10lZVsaaBisNikcxUerdkVWcsMWyv519QGvBTjGDFJ3oEXHlfBTOIdv
22bWJz8AV2IOeuH.R1Tu.DwyW8THB6ikOA5zMzQYAfQZI.hBAd5mDEAExxra
hTBptrdDiabVdQVdVQysVbANpo8GDu5UQ7ljpCU.zZOIlW4YUHps60NycufP
Sp6iomXiw3OOrN9bF.Y9bJ8bYRpzKh1nt3HDTotnF9BQB8vsU2VWpDgq6emS
ScdLNsz4Q59jUYrMGSOxFicCQLf81RaPaKdXicNj.7CC0Ochtz0hG3KDhrsx
K6V.Q+jdjlDCdEMEudsnhV5MVZCTJqWMljd4xxLsETFce2tRBEPWq6.XXn9I
wnfPs66pcs5VDvCRThLLx2iPzcCEoGJ+fl90pWdDeHV0BTDVzQs6CDDzAnkB
jtVRMsgJRzPkxACHH8rwP..5U04QYBwWJYIhHZ+iLb24lXXfL8sRv7qQBKh2
1Hn4NRekyOAyM9xja6w8Q6v2LglTM2YPyeGEVXuGQE13PuuHyK7nDwkQQlN7
xvPd9vw1NrmVVFuiNt1haOhmQrq5XOm9zYhcQBkqnMu2mNsauIWiq8rC6rhl
2X.K7tT1Li7AD5LNZL8rzadxuyNPeG7bnpuX9PRfmdQmF.FIKBNA.rH6kzqF
gGwkeybS7Dgv+3qwWO.AHwZW5PdDLFom6ffPHd7A3GJnza.gJ1CK+nW2Slpx
3Ct+kxXYub0nKTr1MQG4.FBUw27ELp+oY.Z7e.CR1H.HbrTfC6WQK9fHQxqF
9RWQfx76KV5yWoIPynYiB.KzITHQ34eSmqCa8kdUfWP.NpxKlTkTlvdDc69y
5Wgbf+2sd3GO7eXG3Rj.
-----------end_max5_patcher-----------
2 Likes

ok I get your error: put a print at the end of your patch and you will see where the error is from. In effect you have 2 parallel triggers! I will update this post with a corrected version of yours.

update so it is not trivial to switch individual components of a list according to their state. That will need a little more thinking… or some javascript!

2 Likes

At the risk of derailing this thread, I’m still not sure where this isn’t outputting what it should (with a change in place):


----------begin_max5_patcher----------
2163.3ocyasziaaCD9r2eEB57VC9PTjp.M.o8PuzhVzbnnHnvP1lqW0JKIHQ
mroA4+d4CIYJaIaIuTINGrU3CMy22Lb3XxY+7CK7Wm+Bux2668du2hEe9gEK
zMoZXQ8+eg+93W1jFWoGleF+i4q+G+GMcI3uHzMu443rc7llyOHR4BwmJ3lW
su+id9IYhlu7965AVDK17bR1tUk7MByXQjfkfG8vH8WAL0mHzRP6bxNrOIS9
505CrtwjsZ0PpZeWn+wAZTD8HwpF+xCOn93wWGXKJkfv6Ox25eIXfVRT5OVA
.BcxvfzOL.tFF+9au.Jng1f.LYP.cGHD461kNrG10cqz1CLgrjDFvX.LEBhv
TYaFOM0miFWzibVY7dtfWthmEuNUqMfdwLzgFNuzjJw61779DgX30bifNPry
oCHEdY6L9b9.G0ugFZqA7xZnVi0E9Okjx+.urJIOyZzK7iKJrZdg0TTDz+jq
eQrGaaJIyzDnsoR9GRZlOps03RIOHjjvgRMK4+RXf+wWS9VdY1gjVqk1TUqR
ZiRlzVWUDuwLYksqo6iLKS6MAQQpuBC.lnXfijoznuKMey+x2Zqx94E7rjrh
RdEOSDKp081t2xeJ9PpX0S4Yhpj+SqAPoIpu9epVC6sSEFzp+aKShSaAvtxj
s4YJknikP0bi3duGjnwFwFL5QjEWzyjkdFRZYfNqjf7P053RkgpdkSikRtXO
OsaWsyKk+jnt6hjrrSXQQdwvcVlr64KL204xN2eo2stmpUGxL8tR5SHVUE+g
trsHNMsdka2W+KwYI6iEbQhwDf.scZhd7b0lx7zzN30zyG5omsRe7M7OlrU7
rVP1NCxgmTz3D42Zk2lriWI51lHdWU2VpDexP5VMcXc8Z3UB99hTIJ5NfNIR
Xuf0NFWm1uTrttw6JkQT3d.695MCi1HdlfKC5rOPLQXcxFgfkgx+gHQzPh7q
9xB47nhHqNrhLhh7OQm5Y064ANQMcn2wnNTzbwrv4lYqybPlED80wlP58La9
lePtH7hbocVJuNmTDdoxyzrayMwkXvMwkvuRb47SkM4yZXRJSmPzMwjv6YlT
3k5kNwU3843EoSKDBzrFCdc1BNPDQj+25Ep+Wp2NYnuBmwJXDYrrxP6S.uGX
kTYRZuZNAQvJZ.h0o.io29dmf6ANQ9CFJm7VjWXAjgVBtcZAF80gVzJxkw80
vLNx.VcLCb6mCCYv.QXICCY6vLax2umm0MAW8qJaK+k6P9o1m30yOgNhef2W
7S.C4F9g5H9A6P9wnC9izCgNVJXfscwrgo.vq0E43wAjljMzuCTiNU+8yMU4
GJ2z3YzjruGrCPk+vVQRV6oi79i6c5IYjQYalrVDYd4WUKT4Sex.yK2ZNzKv
2XUCNrpAmEUCAFoposcvYx1gfikfXynGjJg2QoEM1y4SKF0pIvbpEQ2Cqowi
16bNsH3w5cpCDNaZAYJAQlqUppDXFmEAMmbAcJw56mKpar4lC7UGO71UliBe
UrPTlr9fvrEo8UgLoircWZ953z5Cjs8LO54Dce3nxMwqd5ozbYNBsWyk00RX
mbRyglPO6Vj54xB68mMsNNa2EuoJX.1HCxXjw0t3N7Xt3tmxK2GqEeXu2pEp
GV4VuhuIwy.vryyPZjK34f6Mdt60GODOCglKIlNlKIdx2As41zczUPytgqf1
g74.WMsva8fWH80cAQZWPLjMDAMoZO.3O2WD+qBsQ5eZqq.Kb1A6a7fK8eEt
95a.57fK3qTsAnd.KZ1Aq6pmIyh99JzhaodZvtq3l5tyyssogwrxhtwxCB4j
cIrvtVxcOCBCUbZlf0DxYY.xrS.bnzwOlA5YT9XkCcDxg3.4DNB4PcfbvQiP
PgNPPnwXf5NntG0wMKYHXDhNvAPDBGgfvtPPihLchjTuDz0jDvURBdMIAckj
tF6wbffBFqKOz0t73uYRdLXVGyActjAyNlwQ8iYvrGZ6j3r8JYylfmTCkJgd
RsSdRcSddMSNb8RdZsRpOsCScicxFuGqHiCaSxemtn+V8q7rCls9aJMwtTy5
cOkjltIOM+rRFsICEeSuskmYyXeuGXIJJ.BYRdZIFhonP8SxGHD6ydzLGXyj
BHAQ.jZnAgHZ.Q+DCgIX0SfSlF5nr.vHiD.QLPf4IYSPorrmlLUp5hbjZUod
Ek4E4ksU64RbT63OH+IqkwaSpuLFPmyx4wZOqRYumVtd96kDZRybr8DaMF+x
gMwWx.nxCViyUIYJuHdKbwQHnFtnV9BQYA3tvsSw3Hcc+sBdl26hyp7dGeex
57zsGSqbLF6VhX.68HsAcs3rV6LiBHLl4oyvxoV7PhTHpwpJRvPp4IyaZVL3
0zT7lMxN5farxFnAaPiNo7xUsYaK3o78mNUJSp5FrCfLl4I4aAg5N2065LsH
P.jpEIKhDPologhLuJRX675Lq.JAh0i.EgkSz39.AgmnnURMcihZ5ppH4.0f
CFRQlUiL..FTOYmrf3eqRSjQz9SU3tKsvvRyLUyg8GNRWj+Jsv1ZKehqOAOZ
8gM21i6iwgucAMsdsyfl+S.rzd6P.aUr.Wk4kdTx3xnHaGdUXn.Bz01g87pp
3cb2ZKt8HdVwtZh8b9SWH1Eko1Q6wde57ocWtGW2UGiyJZWoEiv6RayrxGPh
YbjK8rLG5zOldf27WHU+ZUew7gzv.ylNsJXjpI3Lnfk4eLaxZ3Q8hzt1DOSZ
3O8o3oqf.jbuKSHOJFiLqcPPHD6dE7mK47aPC0rGV8Oy9dpTUbux8W7zz7ON
YsiI26lZhb.YPc7MhjQImmAn0e4PH0f..lq.vg8q4k+rLQxIq9JWQf17Sja8
QzHAZGMyIJXoIgBkFd4eoyzzs9RuJLHLDGU6ESqSJSZOhtc+YyOgbf+l2d3K
O7+.QLd9K
-----------end_max5_patcher-----------

Either way, wouldn’t it be possible to just plop your bit of code in the same zl iter 1 -> zl group chain of my patch?

edit: Nope, nevermind, the change in your patch breaks the zl group-ing.