Maximum peak dB value of an audio file

Just Evan's icon

Hello.

I'm trying to figure out how I can get the peak dB value of an audio file, for example loaded into buffer~ ?

The main goal is to analyze a file without playing it (offline), using native objects or cross-platform extensions.

Roman Thilenius's icon

to find the peak value you can either read it out (play the buffer), or abuse the "normalize" function and then compare a single sample between before vs. after.

Just Evan's icon

I'm interested in finding the max peak volume of the file so that in the future I can compensate this manually to 0 dB inside the audio clip.

This is a kind of Normalization of audio clip gain, since the API / LOM does not provide access to set file_path inside the clip, and create_new_clip does not have the end_time property, it overlays the new clip on top of the existing ones.

I have studied a bunch of topics on the forum, but so far I have not found a simple solution on how I could do this. Perhaps you can give a more detailed hint?


I also mentioned that i need to do this without playing the sample, i.e. on the fly, without wasting time playing the file.

Thanks!

florian1947's icon

you should be able to find what you need in mxj buf.Op

Just Evan's icon


This was the first thing I started with, but mxj buf.Op seems a little difficult for me

Roman Thilenius's icon

if you want to know something about a file´s content, you need to open and process it.

somehow it is interesting that the buffer object knows this value when you use the automatic normalisation function, but not show it to the outer world - and info~ and sfinfo~ are to my knowledge also incapable of getting the max.

okay, in a max4live context you do not have an NRT driver option, so let´s discard that. :(

...but what you could still do to save live life time is to upsample the analysis thing using [poly~] and then read the buffer out with 32x the normal speed.

load and play

can´t tell you offhand now how to find running maximum best, it is too warm here.

Source Audio's icon

"I'm interested in finding the max peak volume of the file so that in the future I can compensate this manually to 0 dB inside the audio clip."

I would batch process all files to 0 db, instead of having to analyse and then allways

add gain "in the future".

there are many freeware sample editors that can do that,

or you make one in max

👽'tW∆s ∆lienz👽's icon

^i like SourceAudio's idea(for the most "professional"-quality audio solution)

however, if you make a product for others, it's understandable to give many options for all the levels of user you might run into, so here's how i'd do it, non-realtime but as fast as possible, with gen:

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

(i'm sure it's possible to do in regular Max, probably using 'maximum' but for some reason, gen is much more logical to me than regular Max XD)

Edit: this solution is probably best for smaller files(like under a minute or so in length) as uzi can cause event-scheduler to choke while it fires off the count(you could try to 'defer'/'deferlow' after uzi, but i'm not sure how that might go for the rest of the patch, hopefully just fine with most of the stuff encapsulated in gen but i'm not sure about this, so i leave it to you to try different iterations... let us know what you eventually find that works best for you)

2ndEdit: here's how 'mxj buf.Op' can do it, too(even though i didn't enjoy patching it as much, haha):

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

Hope it can help 🍻

Just Evan's icon

👽'tW∆s ∆lienz👽, Wow, Thank you!

This seems to be what I was looking for, thanks to all for your help!

Sébastien Gay's icon

For my own learning, I tried 👽'TW∆S ∆LIENZ👽's great solution, using regular MAX objects only , and came-up with this (edit : added an [abs 0.] that was missing) :

Max Patch
Copy patch and select New From Clipboard in Max.
Just Evan's icon

This is a great native solution that suits all needs! Thank you so much guys! You are the best!

With trim gain (something like a normalization threshold) at the end this is exactly what I was looking for!

Sébastien Gay's icon

I realized that the patch I proposed didn't work when highest values are located at first or last index.

This one seems to work better :

Max Patch
Copy patch and select New From Clipboard in Max.
Sébastien Gay's icon

Further simplified :

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

Thanks for the exercise !

Source Audio's icon

if you exercise ...

Sébastien Gay's icon

That's unfair !

;-)

Roman Thilenius's icon

...if peek~ is really faster than using the normalize function of the buffer object?

👽'tW∆s ∆lienz👽's icon

...if peek~ is really faster than using the normalize function of the buffer object?

no(and it's actually 'uzi' that determines 'fast'), but this isn't even important to you, yourself, Roman, as you're well aware since you posted the slowest solution possible in this thread:

to find the peak value you can either read it out (play the buffer)

^that's also the worst solution i've ever seen you post on these forums, Roman 🤮

but the OP didn't ask for 'faster', that's just a subjective view of what's best. they asked for how to do it, and the solutions that myself and Sébastien Gay and others have given(thank you, Source, Sebastien, and Florian! 🫶), allow Evan to figure it out further on their own. furthermore, if people want to question the help given, they should post patches that prove what they're saying.

Roman Thilenius's icon

^that's also the worst solution i've ever seen you post on these forums, Roman 🤮

oh, that is easy to beat, i have been posting msp "solutions" in the gen~ forum before, or adding pictures of a non-working "solution" to the wrong thread.

but seriously, i wonder why he was not simply using the function included in buffer~ itself for the gain makup. peek~/peak is what you do in max 4.x, where buffer~ can not do it...

👽'tW∆s ∆lienz👽's icon

haha, i actually like this:

i have been posting msp "solutions" in the gen~ forum before

and as for your last question:

i wonder why he was not simply using the function included in buffer~ itself for the gain makup

i think it's just a matter of learning how it's done, so that it can be worked with in different contexts. if Evan has access to a quick/non-realtime way for getting peakamp from a collection of samples, they can also adjust this(later in their learning) to work with data op in gen~ or other areas where there is no built-in normalize function.

but sorry i was so defensive, i got 4 hours of sleep the past two nights arguing with neighbors about their noise and smoke invading my home at night, i'm becoming a grumpy old man.

Just Evan's icon

By the way guys, since all these methods pass a bunch of messages, how can I limit the output to one / last one so as not to load the system?

Sébastien Gay's icon

Adding [change] so as to avoid repetition of the same value ?

Roman Thilenius's icon

and note that the main brake block here is the console itself, which will later in the program not be present - hopefully.

(so when speed testing uzi driven things, definitely close the max window!)

TFL's icon

Only one output, combining some of your various suggestions:

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

Just Evan's icon

TFL,

Excellent! Thank you!

Just Evan's icon

By the way, I noticed that all the previous options seem to accept the maximum amplitude of the first channel (I’m not sure), which, with a difference in channels, could lead to an output of 0 dB.

Here is my solution to this problem, now we compare both channels and select the loudest one.

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

Sébastien Gay's icon

Correct. Starting from TFL's proposal (but adding the famous [abs 0.] that I forgot earlier), shouldn't this solution work ?

Max Patch
Copy patch and select New From Clipboard in Max.
Just Evan's icon

Hm... It seems to work pretty accurately! Cool!

Thank you!

TFL's icon

...and what if we have to deal with an unknown number of channels?

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



👽'tW∆s ∆lienz👽's icon

^beautiful! 🙌 (except it didn't work at first try, so i changed 'gate' to be open right away with arguments of '1 1')

...and was inspired to add RMS, because in my experience, i like to have a compressor and limiter at the output, and simply raise overall gain at playback/output(no need to change contents of buffer~ in such a case) according to something more like 'perceived loudness':

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

but for more ideal 'perceived loudness', in case anyone wants to take a shot at LUFS,

here ya go:


Source Audio's icon

Is this a joke ?

Roman Thilenius's icon

since someone posted a video on facebook where he claimed that you had to normalize all tracks in your DAW, more and more people try to do that. for well, for no good reason.

other might have a better reason. last but not least... it is not illegal.

but for more ideal 'perceived loudness', in case anyone wants to take a shot at LUFS

haha, raja, i came to about the same conclusion: in opposite to "normalization" of your tracks or sample collections, which is an unusal task, it can sometimes actually make sense to do this for LUFS.

p.s.:

back in classic MacOS i even had to make my own "peak" object, because [peak] was int-only.
except for the [if], which can be replaced by the cheaper [split], sebastien´s peak patch is quite lean. only [peak 0.] is better of course.