Pre-processing for (Training for real-time NMF)

The IR question(s) are about cleaning up the noisy audio from the fancy drum trigger, not the dicts. The dicts, as far as I can tell are fine.

Basically this. What’s the step for going from noise to FIR with HIRT?

Actually I crossed my threads!

My last comment was referring to the discussion from the Training for real-time NMF thread.

Basically the problem of being able to grab the correct frame from the output of fluid.nmfmatch~ to compare against. At the moment none of what I have actually works. I’m just building good (theoretical) dicts so that I can improve the likelihood of getting accurate matching from fluid.nmfmatch~, but since I have no way of assessing the improvements, I’m just shooting in the dark.

You did tease that you had some ideas for this, if I understood you right.

my last hypo on this was to no clean them - you should process what you get!

That’s a good question for @a.harker and would be a good 3rd example for the video you are doing now.

So my idea is super simple: to take the (amazing) attack detector I have done in time domain, and take that to grab the next out from nmfmatch. That should give you an array of RANK values. Check the index of the largest number, and that should tell you which one it is more likely to be. It might be that you have to wait the 2nd nmfmatch out after the attack detector since it is so quick.

Does it make sense?

I can give that a spin too. It’s just really really noisy, so I imagine(d) that that would unfavorably skew the dict creation and matching (using up some of the precious 33bins on garbage information).

I’m doing that in my patch now. I added a variable delay in there (10ms seems to work ok), but it doesn’t really work. The best working version was something @jamesbradbury got working using fluid.transientslice~, which is slower than the fast onset detection. But in what I have now, it’s correct only through random chance. (some dicts do match more consistently than others)

What I was hoping for with the “onset flag” feature request was to remove the slop of trying to line up a parallel onset detection algorithm with the deluge coming from nmfmatch.

The idea of onsetflag is a potential good one, but not on the dev radar.

Another option I had in mind is to get the fast attack I had, use it to trigger a s&h to the address of a circular buffer, then send that to bufnmf~ - that would be sample accurate trigger of the process, and the ‘fake’ real time would give you activations (from trained non-updating dicts) and that would be great I think. And fast (although still in message slop)

another audio domain is to use your dicts are filters in pfft (like in bufnmf helpfile) and run fast (and exclusive) attack detectors on the RANK (very well defined) filters. You would then get only the (short) fft delay + env…

so you have 2 other options here you can try. let us know how far you get

1 Like

I understand the idea (basically the same as your “fake” real-time descriptor analysis. Works really well in context. However, I don’t really understand how to implement that with bufnmf~, which as far as I can tell, just spits out a bang. So I understand the onset detection, and using that to feed a fixed amount of time (now - n milliseconds), but in doing so, how do I determine the activations?

This one I understand less, so I can start with the other one.

you provide it with a buffer for the activations. when you get a bang you know it is ready to be polled.

Hmm. So having two bufnmf~s. One for the actual analyzing of the “real time” audio and then a second one to just report activations? Or rather, write activations to a buffer, which would then get uzi/peek'd to determine which rank had the most activations?

Do one of the examples in the helpfiles do something like this? Having a quick look (traveling at the moment) but not spotting anything.

that’s the one.

Not exactly: the nmfmatch example listfunnel -> unpack -> gate is in the right direction, but RT version and not what you really want.

The example of JIT_NMF (formerly known as BecauseIcan on this forum and the plenary) in the new shiny ‘example’ folder is more in line. you would not trigger fixed values, nor with the count~, but with a sah~ and change~ to get the address of what you want to analyse. Then the bang after bufnmf~ would trigger a list-ification of the destination activation buffer, to find who’s the boss… but before doing this second bit, I would just look at the activations, to see if you find a consistent lag for instance. Once that first part work, then it could be fun…


I suddenly see a sexy example coming together, like

  1. my DC updating from 3 steep bandpass on drums to train (bd, sn, hat)
  2. then attack detection sending to the thing I said above
  3. then post processing the activations

Would you be excited by that? It looks like a fun addition for me…

1 Like

I’ll respond more properly once I’m done traveling, but that would be super useful and amazing!

I can send the training audio files I made for drums drums once I’m back too.

I will probably try to find a more generalisable example, for fun. It’s cooking…

1 Like

adapted the amplitude based attack detector to be spitting its sample accurate click with a time hysteresis in gen~ - next is the nmf process, but I thought I’d share this recyclable code snippets


----------begin_max5_patcher----------
3128.3oc6cs0biaaE9Y6eEbzCYrascItvaMcyj1mxi88rY7.IBIyrTjZHg7Z
2cV8au3BIEuSPIRYkzlchjV.Bfy46bEWH1uc6MKVF+FMcgwe23WMt4luc6M2
HKRTvMY+8aVrk71pPRp7wVrkllR1PW7fpNF8MlrbfkkIHuzT16gTYw4kDumE
RYr22QUC1hEF+VVUQ62FDwqT1+vrB2QXqdIHZyyIzULUSr7bdx7ACG.V7kko
3SH7IyhNJvWNjwK+8GsQKN16pwV18.Qge+1aEe7flbbD8q7trACu5ERzQbPG
N9AiEAQr7uZm+Acy+1PWAKai0f+sbam+Q4ceBMkFwHrf3nxPri6SVbH1xRz4
lYeX7aSGpkFQ1k9RL6fwXTVVGFSXiWiIGwfRNwwtWDyb10XRIubXDLcZvlHR
334ZG.Rpf.jLOxoOtFOcL8p3saoB065bMijvL3j2i6BIuujr5KciA5ZJ3gxz
9keAxrEL6Px50NSZdBLofqVtmwhix6yWj1xk3AwirJNLNQQplOgvdlvGZ4Gf
RzaSrfK8i4bbX.GvJgFs5VogOkBzGl2cgzMjUuWg3x6xkaJQu.kQuiqKDYI9
E1wzx0sJ0pqbx0CJ7m.bwhuf8JlvEho0wQrHxVEb7OSBHgF+q3P+7pSh2G4S
kMzVzi4idBuILZxyzHxREVZdJ9.APrzQAx0qNQOctBXFor3cFqBojjw3Rf2H
grV0tQKN7TgNf1HAmY60mmAfc6VMvILBJWPxCDXZfw.SyKgmQKI+iLkxTObu
7u0rGO3ud3hy4PYz.aPubNd147cwegdvHHZ2dllACP8vaHI6frkw6bP8xano
KVvkf2rsFAuAmcdKkFNp71VxSQVFeZzJrYQNxbUg5M0MHX5bUwh2rIbLY0eR
oxmyc7vJhuTNhvcHVKhKpeHtIzTc490qoIYJz73fixckJu8GxTDFe7prTXcU
o4Y1aprye7JexpCZZR2ilsHuBgOXKzvomOgdq5L8bZHmzLHFow6SVQMHQ9Fh
D0O+jzwp.r.UzlgRR24+gSRG7gljNNW.gyEP8jjt80RR5pY.hvv5D8InvrTh
JzhLweMf90WCRCVFDFvduhfc85TZFM7nDudDUBoBiW8EpueBYS5pj3vvx7mT
Ig8BGX17R4xUHwKMafphWaVwxMai8qfcKiS7oIUPybQiOcabpPX7Dmk2QXmV
pkl8n9nVrn743Ajd2D93Z0gVQNJjjMYq63helyN6EAcMpn7NSodZrJNNzfr2
OHNgv3N71tiKk26SMVRRo9FDFir5KF9b0zUr3joJ4bvfHHFpRuq+4kY0QxNU
5ektvMEHC2bMfqJQSR4lQkdZtXX2tREeSolHfyeW4vw4ghhBhTEgJJJgJLUT
s2pnTRBmKEH39DEp8lc9zJDcCW+MIZePgrUJXuMuCKBUhTlXdpzeAPfzZ2CU
JUIg4fxrqjdJW3riFwSYoj2iJU6SWS1GxdV3EKM3+HIQYm2R8qIqnc13pt.y
4vEaRB7iiDDQEzVTb9vwchoLbrJyLxmHhrqkFyk9bjoiJS4L49zkjDoeKklJ
LuRFWiuZUEsKjtlkU8tfnnZnHKdW2UlDr4kdZ6xXdka6quk0j979HUsOyMcY
OmRdsJZyHggY1xU692HQAa4Vvr.kHfmaZdkM7oBpVyqsTiOWOdE8qA9Lk64x
JC7GOXWtRzhBorevFZJqZYLhxu1wRZ34fWz97PNOynb+Obtn5CTYaYJaTV1q
Wkxq48S4YnvhqUxnKeTc4mBxS.2QrvQNpIkZl+Yg5acu8t0FpxI1Upl7bSqS
bA7THdqjOhrX.YtKNQjoRbgpwF1PiNX7y96SjNLDSOyZXDbnv.mNLq18B.pw
N8TGm85FlaLVGCMTEj5LDQWgIp071BWzQHitCaLbnitBeTIDRsvHPOEBhj9a
sUq9G1plhK22fe.SHJpjps4SdOT5CP8F0VzGMh.oSTnAiDoYzndhHoWToAhL
MXzoAiPMPTpgiTMXzJMhXoSTqwD4pmnWCFAq+nX8GIq+nY8FQqqnZsGYqamh
CGgq8nb08oT2mdi5arHG9TQKdn5yzNM1+wRXPW2EyBtMqxNbsCT6AMPMIIjo
zTSlUaigsGeBcrvWUZZ2dB5MFQV3X0rKW7KAo7Y.8tgxz8NtRz8+3mS9bz+V
LMdi73j2I2Di75D+evZi6Tsw3e7I9j59gevPcZItKHBbuwm9jA39uIeXV1iw
KQ0Z12EeQCSoFk5kexv7di5sH6GOZbG2o7eKmZtub+7Yl3SNqB3OedmIG9eb
QYdtHshpoVbtpiMR0nZ5FAQEKl9LnpNB0Q3wz4fsoKVd0nGPU5iGU4TyXf0d
Mu6Fyvcc5JZCzv8CZl8.ZUiAGFDMjCSIIKdt9QT0p8loIk4EwnISvCTvSIpH
6kesfeLxVosQKqOU5CLB5ydP5qTkGqYdmbAOYAw5JsV7mSXVEEakRseb5Syv
BImlQ1By2bUmZrMacOKCzkAB4Lru37GZ.L4jswwyr0X.xI.w.Npn31CAYfdl
X1DBYU2ampXVBMzf8BeVHuXLwqF.m8gh8lE60w96LPdLst20Cm.SWNOmYbjr
LMGGuirTDjgq9c+zBoXaSIjh8fmOjZcMfn8XLym2RZ5AtQk4ouFKOnwps.6G
yAHOIlCTKRfS6K1hdPti4oh4vKjV7iHyoUkE45J8IhTKVU1mmnF6UuSfGwyE
7Y4c9vm0UO7YMWvmG37gO6qd3ydlfOb1IP5rfO2qd3yYtfO092ddvm20N7M0
t9v1OUJtA9LvN7Uup2TG0Ea8TofFmE14bsicvoG6LOFw3rvtq9HFfYA6vGOv
pmN1c0mrxDCcVP0tNp1cMuyA5vWCP25vXdmeJq+R8iC7ouxCpygP1rjw8Al3
NW3gQ.l8b5EaaJcU52jsDI0a+mDQfCTk38THBr9iqHHcU7N5gxTXh7sBN6nC
Hr3qajqgqjAVxhr2IB0KEQ1wCAz24voZHzOjU64ubXNNIMP8NIMVtEGAcqSd
wcfm7pSbgN8R+zACslg3jCyHjZYKsxROv5LVBMH9JGkUqA7A4VPXNKnMRSkZ
jblSdfy.sAldW4vcZXfOUh1y0owa.3VrtvP4KoUwAa+zWe3qcz9wOBuz4HLx
T8FQgNCD107JGgIrX+kG9HNUotPkdrixIs64fxf+OJOf2ho.kg+wv2r33eI+
3iHXXtVc1lPaBOG.GcsqVuL8CUoFf59LOoIFitJxu6Cblyb6jx6w+YMyYjye
Rm47ipsg+QzzO44b7eDSeFCtLSeVxCyg8solGAhri.pU9mcdrl.58BmbRuWO
GeW3ZbZGOBnscJBKAqCe5A63jCBqdxA6UnNVZvSSZP7VSMaDADpIU3MiDgbZ
m5IOlSABPWsBwFGOeTAVSpPgZf4hLrFEY.mK8ScoB7bZjnv4gIBqYlHf53tv
YNIB7XLTmKcSjtTgSS+JE2LBfOVRSL4htHMy4gzbzU1gmQYmz2oNFSn4zh1Q
2.NtyY.GWyQ4i8hpsnMsAMuz1XtfwnHecRZXvEWfpKo41zBsfzfyCoAGCoMa
ViHcoBPmTQVg4u44KDuCv9OqdWnelvXIAK2yTShoD4LtaThMgwKIgYuMsESv
uuqWhiuot2djdyt9bj7a0oVotMcpCeY2oNCjnX+ugX42TNULBabO9n6Ha4pw
HKt4uyClcxiDBpwHgZmGQm0Hi0XfsJYUb5fooNij6TLR.MUX.MASy4WLB5PN
dIFZ3bXl.v5x0mqYhVtB.v1EsvKvPimCQKvVmg1ZBrbjiDXHGdSw.4oAKAAS
vHAAWJvSNRCAd.6KkCNT6VAf42KSMxqUCPUVA0tkeDiZsa0mZ2lOMuEe5916
o9s1iLmIU1K0xDoHGmsj2rKtNOxunapBIMuVLO9g4SVUtqMkO4yAQBdr7Qz6
3Gku9LIqVQipdIg5JdLWjGDXKu9MM8bMwYs51ioAJ1qEdSqmX1hsbpOH2+SY
wcEFtzt.zNKWgjvPjETd4DgbfVX4ufNXKvTSVU928ktjEqCBCKHuxI7luaEK
1jP7CJcjqUbCn.gs4+myCs9qxW8RplAya1wKB0l+pYyxaEzyD3IkjnLIo3W7
h.0ZEIZS18UjSoqEtcIw6hSJtXmdB4U776YwELZwD7JljvHzE6S7U05POoX4
qENMztjzB1J+JwEyQIj2IqYway2u8+V.qWxI
-----------end_max5_patcher-----------
1 Like

paging @jamesbradbury and @groma and @rodrigo.constanzo and @weefuzzy here, a.k.a the koolkidz :wink:

I’d like to train on basic bass drum, snare and hat, and for the purpose of this, I’d like each of those to be basic classic synths so we can get parametric variations on them. Where would be your go-to cliché of synth source of code if you did not want to lose ages reinventing the wheel?

1 Like

There are some nice SC snippets in sccode.org, the search seems to be broken, but you can use the tags.

1 Like

I had no idea that you could do @ttributes for gen params…cool!

Fuck yeah! Excited to see where this goes.

Would also love to see a detailed account of your approaches (even when/where they fail) ala the piano example.

If you want a robust and varied training set, wouldn’t it be better to use a bunch of different attacks from generic sample libraries? (ala Logic, Komplete, etc…)

I would think that recorded acoustic drums would have more complex and varied spectra than (even sophisticated-ly) synthesized ones.

Would also be good to see it trained/tested on something a bit more homogenous (toms, or ride/hats), as kick/snare/hat are so different in spectra that it there’s probably all sorts of (far simpler) techniques for differentiating from them.

But hell yeah!

ok I have one failing perfectly right now (untrained and unupdating) I will share this afternoon when I get back to this.

that does not exist. What we want is a robust classifier, and the spectrum covered by the ‘bass drum’ class is way too wide and culturally driven, crossing over to snare mid way (i.e. a funk fat snare will be lower than a metal bass drum!)

so I’m trying to make a ‘training’ mechanism that is quick, and reliable on a specific set. This is fun.

1 Like

Yeah that’d be great to see, though I meant for the “finished” version once it ends up in a help file.

Sorry, I didn’t mean having a “generic training set”, I meant having a whole bunch of examples that you can test/compare with. Individually. So having a set of 10+ (acoustic) bass drums, 10+ (acoustic) snares, and 10+ (acoustic) hats, that were all different enough to push the algorithm, but not as straightforward in spectra and envelope as simply making an 808 kick a lower/higher pitch (to use a stupidly simple example).

Soon @weefuzzy will take ownership of the ‘help files’ and this type of examples will most probably be elsewhere (teaching, examples, web, example folder, who knows)

this is actually hard to detect for an algo, hence me pushing this bit - easy to modulate, hard to identify :wink:

1 Like

#evilmaniaicalcacklling

that many 'i’s? That must be miainiaiciail :wink: