Return RMS volume of an mp3?

I've been looking for this for 2 days, and found a few command line tools to retrieve the level of an mp3, but nothing I can easily return a value from. I'm starting to think I need to invoke sox, have it write to a temp.txt, and then read the data back in.... but that's really ugly.

So here's the scenario, I have a few thousand mp3 files and I want to sort them, put ones that are at a lower RMS volume level in a different directory.

Anybody know of a library that can do that?

Dealing with mp3 files is generally more difficult than open formats or simpler formats like PCM WAV.

Since you're just doing some one-time file organization, calling into a command-line tool is probably fine. I might also suggest using something like Python for a task like this, or even some bash scripting.

That being said, there are C/C++ libraries you can use. One such library is mpg123, which is somewhat annoying to search for since it's also the name of the audio player built on top of it, but it should have the capability to read in an mp3 file and decode it to a waveform which you can then get the average/rms amplitude from.

https://fossies.org/linux/mpg123/doc/examples/mpg123_to_out123.c
You can probably find more examples if you search for mpg123.h or mpg123_read.
Last edited on
I found this command line approach.
1
2
3
4
5
$ ffmpeg -i music.mp3 -af "volumedetect" -f null /dev/null 2>&1 | grep volumedetect
[Parsed_volumedetect_0 @ 0x600b9cf85f40] n_samples: 247022304
[Parsed_volumedetect_0 @ 0x600b9cf85f40] mean_volume: -9.2 dB
[Parsed_volumedetect_0 @ 0x600b9cf85f40] max_volume: 0.0 dB
[Parsed_volumedetect_0 @ 0x600b9cf85f40] histogram_0db: 2904237

Where mean_volume is the RMS value.

Those are both excellent places to start! I'll look intompg123.h and.... I "think" ffmpeg might have something similar, I'm pretty sure it was ffmpeg I used years ago to get file length for an mp3 player I wrote that "mixed" tracks.

Thank you both
Just to follow up, this ended ugly but it's being used infrequently and for personal use so whatever works I guess:

system("ffmpeg -i SampleBytes/44.mp3 -filter:a volumedetect -f null - 2>test.txt");

then I used:
getline() to pull it in from test.txt
erase() to remove unwanted characters from the string
stod() to convert it to a double

FWIW, I'm not a pro developer, or a student, just a green self taught homebody.

Thank you guys again for the help!
Registered users can post here. Sign in or register to post.