Keep a running average of the last N samples

willyc's icon

Hello,

I want to keep a running average of the last N samples (or X milliseconds) of an audio stream. The patch below demonstrates exactly what I'd like to do in Max terms, but I can't seem to make a satisfactory solution with MSP objects. There is a proposed solution using [+=~] but as indicated in the patch it is not without creating a potential problem....

Any ideas or externals that might help? I want to remain entirely in the signal domain if possible....

Cheers
Will

Max Patch
Copy patch and select New From Clipboard in Max.

Tim Lloyd's icon

Maybe you've already tried this and it isn't quite what you mean, but couldn't you just adjust the interval time of the average~ object? It's default mode with an argument of 44100 seems to do the same thing as your example patch.

willyc's icon

That would only provide the average amplitude (of the previous seconds audio) once a second.

I want to know the average of the last X ms of audio every single sample....

MIB's icon

I haven't used it personally, but there is an object out there (ircam??) called [accumulate~]. it might do what you need or at least get you closer...

Tim Lloyd's icon

I think you're referring to the CNMAT accumulate~ object, which very similar to the new +=~. It still has the 32-bit float accuracy limitation that +=~ has, so after about 6 mins at 44100sr, your patch would become inaccurate.

I do get what you're saying that you need now, but I'm not sure how to go about doing it.

ComfortableInClouds's icon

actually, average~ does exactly what you are looking for. That is, the oldest value leaves the buffer as the newest sample value enters and then the average is recalculated, at every single sample. Thus giving a continuously updated average value. what you described is the avg~ object, not average~.

Using the CNMAT accumulate~ external, you can create a memoryless system to analyze the instantaneous energy in a signal. Look at the leaky-integrator example provided in the accumulate~ help file if you're interested.

Tim Lloyd's icon

I nearly suggested that example, but couldn't think how to go about changing the number of samples that the integrator "averages" over.

willyc's icon

Thanks for all the suggestions. It looks like [average~] actually does exactly what I want.

Looking at the helpfile for it reveals it produces a signal output. The reference manual states a float output, hence my initial reluctance in using it. Cheers

brunatius's icon

Has anyone implemented a different type of average other than equal weights? I've been looking for an exponential average where the most recent elements are weighted higher than the rest. I wonder if it's feasible to implement in gen~.

Floating Point's icon

that would be very simple to implement in gen, as what you are describing is a single-sample delay (history) with attenuation (*) feeding back into itself (ie iir filter). it probably exists in an example patch

Wetterberg's icon

yeah, just an echo with feedback, really.