Integral of a signal using delay buffer: how to get the last X samples from a delay~ buffer?

Julia Merino's icon

Hi, I am implementing a patch to calculate the loudness of an incoming signal for an interactive live performance system. This system will have a parameter to change the duration of the sliding window between 1 and 30 seconds. My first approach was to use average~ however this doesn't work when suddenly changing the time interval from 1s to 10s for instance as I guess the buffer doesn't have access to the samples of the last 10s. For this reason, I've thought of implementing the average calculation by always storing in a delay buffer the last 30 seconds and from there get the last T time samples to calculate the accumulation (integral) and then divide that between T-time samples to get the average.
My question is how to get the last X samples from a delay~ buffer?

Thanks a lot for you help!

Source Audio's icon

record 30 seconds of audio into buffer and read whatever portion of it using peek .
As alternative, you could store average per period, like 10 - 100 ms instead of each sample which would make storage and calculations much more effective

Julia Merino's icon

That's a good shout. However, how could I constantly update the buffer with the new incoming samples?

Source Audio's icon

here is what I woud do :
get average level of 1 second which is your minimum report length
by taking 100 readings and averaging them.
meter~ set to report 10ms interval -> zl.group 100 = 1000 ms

30 average values get inserted into coll , you set how many
last seconds get taken into calculation of average level.

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

Julia Merino's icon

Thank you very much! I ended up using a slightly different approach using zl.stream instead but all seems to be working fine!

Roman Thilenius's icon

if you need to access samples other than the last one, why not use a tapping buffer instead of delay~ ?

i build loudness metering also around average~ because it is actually cheaper than using individual math objects.
no idea why you would like to modulate the window size though. for loudness the mean-sqare is normally measured in chunks of 400 ms with 75% overlap. which is roughly what you get when using average~ with 400, followed by rampsmooth~ with 400, and then snapshot~ the values to be displayed (or accumulated).

alternatively to the rampsmooth+ you could take the analysed 100ms values and interpolate those values over 5 values. (2 in both directions. nowadays done using zl.stream, exactly.)

Julia Merino's icon

Thanks Roman! I actually checked your loudness meter :)
My client wants to be able to adjust the sliding window. I went for taking the avg~ in chunks of 100ms and making a 300-long list (30 seconds) with zl.stream so I could always have access to the last N average samples if the sliding window was increased.

Roman Thilenius's icon