it’s not derailing, it is actually important for us to know where problem occur in your creative coding.
with change now your code works (and we only get difference because you put >= for the on-thresh - but where your code will fail is at the use of change for a list - you need to check the change for each component separately…
I’m sad to tell you it is not working as a Schmidt trigger completely - during the DMZ you are lacking values hence not outputting! so if one your list is in DMZ state, all the other are paralysed. Try it - make all input high, then put input 2 in a value between the thresh, then try to make input 1 low - it won’t budge. If you print the output of the p listSchmidt you will see you have no update because inside you do not get 4 values…
It seems like this should be possible without having to go to js at the current data output rate (which I worry would jam the scheduler, since it’s always in the low priority thread).
I guess it’s trivial with a finite/known list length as you can just unpack -> schmitt -> pack all the bits, but having something that doesn’t care about list length would be good.
actually it doesn’t work. I mean, the only reason to have a Schmidt trigger is that hysteresis. Otherwise just do a simple comparison and you’re sorted!
I meant that there is a special status between the 2 thresh…
So I’m building a thing that will train off an arbitrary amount of hits (per classifier), and I’m wondering if there’s a (computational) difference between these two approaches:
1a. Run fluid.buftransientslice~ on a buffer and get the transients.
1b. Take 30ms chunks of audio from each transient point and fluid.bufcompose~ them all into a single buffer. 1c. Once this process is done, run fluid.bufnmf~ on each slice of the buffer separately. 1d. Sum all of those dicts together into another buffer.
1e. Add the summed total to a single seed dict for fluid.nmfmatch~.
2a. Run fluid.buftransientslice~ on a buffer and get the transients.
2b. Take 30ms chunks of audio from each transient point and fluid.bufcompose~ them all into a single buffer. 2c. Once this process is done, run fluid.bufnmf~ on each the entire contents of that concatenated buffer (which only contains 30ms “transients”)
2d. Add the summed total to a single seed dict for fluid.nmfmatch~.
Basically, does it matter if I analyze each transient separately, and then sum their dicts, or if I just analyze all the transients at the same time to make a dict. (the latter is just a smaller/tidier patch)
Well, the short answer is that I’m not sure. I had wondered whether the longer decomposition in (2) would be much slower, but I think NMF scales linearly with the FFT size & number of frames (but quadtratically with the rank). I’d be inclined just try a small example and see (the scaling will definitely be different though).
That said: I’m not sure what useful work 1b is doing. Can you not BufNMF the segments directly out of the original buffer?
1a. Run fluid.buftransientslice~ on a buffer and get the transients.
1b. Process 30ms chunks using fluid.bufnmf~ to get a @filterbuf output.
1c. Concatenate each @filterbuf buffer into a long buffer.
1d. Sum each @filterbuf back into a single buffer.
In reading/writing it out now (I was in the middle of patching, and brain was pointing in different directions when I wrote this post) I can see that I can just keep summing the output of fluid.bufnmf~ “in place” on the combined buffer.
So there’s no need for an actual/extra “summing” step. I can just stack the outputs as I go.
A further thing to try is not summing the dicts into a new buffer, but to leave each dict in place and run (after the first time) with @filterupdate 2: this will use the dict as a seed but also update it as it adapts to the new input.
In this case I’ll have an arbitrary amount of dicts, as I’m trying to feed it longer training data (i.e. a recording with 10-20 hits at different dynamics), so I’ll have a whole bunch of dicts. Or do you mean having a dict-per-channel, and then feeding that one as a seed?
Wouldn’t it be @filterupdate 1 that allows it to update? (I thought 2 was the fixed seed one).
So if I follow you correctly, you’re suggesting:
Doing the whole fluid.transientslice~ -> fluid.bufnmf~ to create a dict out of each individual transient.
Use fluid.bufcompose~ to stack all those together into a multi-channel buffer (one channel per dict).
Running fluid.bufnmf~ with @filterupdate 1 on ALL the transients (should I window them? should it just be the transients? or should it be on the “raw” audio).
Taking the output of that fluid.bufnmf~ instead of a “summed” version of all the dicts from step #2.
Uh, yeah. Probably safe to say you know the interface better than I by now
I’d perhaps got confused by what you’re trying to do. I thought you were trying to generate a single dictionary entry from an ensmeble of different candidate hits. If each transient in your original is meant to map to a distinct dictionary entry, then the filterupdate thing is a red herring.
I’m trying to step up the process from earlier in the thread.
So I have 4 distinct sounds I’m trying to train it on. Earlier in the thread each one was being trained on individual example hits (from your suggestion to not wash out too much detail). Now I want to try stepping it back up so each classifier/dict is being trained off multiple candidate hits.
So 10-20 hits on drumA, turning into the best representative dict for drumA. (then rinse/repeating for drumB-D)
So with that in mind, should I not do the filterupdate 1 thing, and instead just sum them in place?
lol, it complains at me for everything I make too, since they are all “similar”.
So with that being said, back to these questions from step #3:
Running fluid.bufnmf~ with @filterupdate 1 on ALL the transients (should I window them? should it just be the transients? or should it be on the “raw” audio).
I would try running it on each identified segment from transientslice~ + 30ms, one by one with @filterupdate 1. Not sure what windowing would ential, a fade? I wouldn’t, given that they won’t have fades IRL.
Do you mean taking each single dict (say 15 of them), and then running fluid.bufnmf~ with @filterupdate 1 on a buffer of concatenated transients 15 times? (and THEN summing all that together)
Yeah, I meant a fade since an audio file of 30ms chunks of audio will have discontinuities not present in the originals (hence on whether it should happen on the unsliced audio, or a buffer of concatenated transients).
Hi guys, sorry I haven’t been following this conversation and it’s gotten a bit long. So I’m not sure I get the questions right, but here some random bits:
NMF is a learning process, it starts from random, so there is no notion of mathematical equivalence, but it is possible to arive to similar results in different ways.
The dictionary elements will be normalized (each one with respect to itself) for each iteration of the training. NMFMatch also trains and does that. The activations will have to compensate for that, so they will represent the actual scales of each detected component corresponding to the input spectra. The dictionary elements only care about the relative scale of each frequency bin.
Given this behavior, I expect the easiest thing would be to process mixtures and sequences. Rank-1 NMF has also been used, but I don’t think it should be thought as equivalent. While the result of NMF looks linear, the learning process is not, and as I said it starts from random. I would not normalize or average the dictionaries outside the algorithm.
I can see how using rank 1 can be practical for training it in a supervised setting. However always keep in mind that the amount of trainig examples also makes a huge difference. Every time you do the “same” gesture, there will be small differences. If you tell the algorithm there is only one, it will have to “compress” all the examples into one. Same when you tell it there are 4, but then it will have to work harder because it may have to compress also mixtures of those…
On the other hand, skipping silence or unwanted sounds is generally good.
So initially I was running bufnmf~ on a chunk of audio that included multiples of the “same” hit. After some discussion on here this got reduced to using buftransientslice~ to find the peak in an audio clip with one transient, and only running bufnmf~ on the transient + 30ms (also testing +50ms), to get a more accurate representation of the transient part of the sound, to match against.
This led to some somewhat working matching. Not perfect, but at least in the ballpark.
So now I’m trying to broaden the training for the classifiers by giving it multiple examples of each individual hit (still by finding the transients via buftransientslice~).
Where this has diverged is that I wasn’t sure whether to take the @rank 1 dicts created from each hit and sum them (which you’re saying I shouldn’t do that outside of the algorithm, because the scaling will be off?). With @weefuzzy (and @tremblap a while back) suggesting that I then retrain it with @filterupdate 1 enabled.
So with all of that being said, in order to best train robust classifiers, should I run it on “raw” audio (lots of different attacks, with decays/space between) or just on the transient + 30ms?
If so, how should I go about summing these if I have multiple versions of each classifier? (or did you mean something different by average)
Do you think that running @filterupdate 1 on the source audio again will be useful?
If so, should it be on just the transients or the “raw” audio again.
edit: so when using fluid.bufcompose~ to “sum” a bunch of dicts, I end up with dicts that have values > 1 in them yes? (as in, the waveform~ display will appear to be super clipped)
I’ll try to find the patronise flag in the pref and lower it to ‘kind daddy’ instead of ‘self-righteous uncle’
update: sorted to new values:
Number of posts a user has to make in a row in a topic before being reminded about too many sequential replies = 20 instead of 2
Number of posts a user has to make to the same person in the same topic before being warned. = 20 instead of 3