Find peak decibel level (or some measure of peak loudness) from audio sample

So a shotgun range opened near my house and I've been tasked by the HOA to do some nuisance analysis. I've got a quick sample of audio and want to find the peak noise levels at the places where the shots are heard. Can anyone help me understand the relative scale (-1 to 1) that AudioData returns? Is this an absolute or relative scale?

Sample:

sbs = Import["https://drive.google.com/uc?export=download&id=0B-No0nABM5N8c1FoNFA5LU42QWc"]
(* Show the whole file: *)
Spectrogram[sbs]
(* Plots the first 2 seconds: *)
ListLinePlot[AudioData[sbs][[All, ;; 200000]], PlotRange -> All]


You can see the file is pretty quiet, which is fine, but I really want to extract the peak noise from those spots around 1, 14, and 16 seconds.

Thank you!

• I couldn't import your file. Oct 25, 2017 at 22:46
• Fixed, thanks for pointing that out... Oct 26, 2017 at 0:14
• Have a look at AudioLoudness, and try AudioLoudness[sbs] // ListLinePlot with different def settings (in particular "Peak", maybe?). Seems like that gives you something useable (although I couldn't tell you what any of it actually means). Oct 26, 2017 at 0:33

2 Answers

This solution requires that you know ahead of time that the shots are at least 0.5 seconds apart and there are 3 shots, but

max500ms =
AudioLocalMeasurements[sbs, "MaxAbs",
PartitionGranularity -> {Quantity[500, "Milli" "Seconds"],
Quantity[500, "Milli" "Seconds"]}
];


returns the maximum absolute values in 0.5 second windows as a TimeSeries which you can plot or take the top 3 values of

v = TakeLargest[max500ms["Values"], 3]
(* {0.0883511, 0.0767541, 0.0689108} *)


Converting to decibel, it looks to be the same as your solution

20 Log10[v]
(* {-21.0758, -22.298, -23.2343} *)


What is missing is the calibration of your equipment. These values only relate to voltage from your equipment, not sound pressure. You must obtain the calibration of your microphone and pre-amplifier, which is probably given in Pascal/Volt. It is also important to know that the standard reference sound pressure is 20.*^-6 Pascal. With the calibration factor cal, the peak sound pressure level (dBSPL) is given by

20 Log10[cal v/20.*^-6]

• That also works great, but provides better information for finally getting dBSPL. Thanks! Nov 1, 2017 at 2:12

Thanks to aardvark2012 for pointing me in the right direction. Here's what I was able to do:

sbs = Import["https://drive.google.com/uc?export=download&id=0B-No0nABM5N8c1FoNFA5LU42QWc"];

(* Get the mean and standard deviation using "Peak" method: *)
sbsmean = Mean[AudioLoudness[sbs, "Peak"]];
sbstddev = StandardDeviation[AudioLoudness[sbs, "Peak"]];

(* Get the peaks out of the data, using the same method *)
sbspeaks = FindPeaks[AudioLoudness[sbs, "Peak"]];

(* Only keep peaks above "numsigma" standard deviations from the mean: *)
(* No doubt there's a faster/better/easier way, but this works: *)
justpeaks = Part[Part[Part[sbspeaks, 2], 1], 1];
justtimes = Part[Part[Part[Part[sbspeaks, 2], 2], 1], 1];
peakdata = {};
numsigma = .5;(* Adjusts sensitivity for peaks *)
thismax = sbsmean + (numsigma sbstddev);
For[i = 1, i <= Length[justpeaks], i++, If[Part[justpeaks, i] >= thismax,    AppendTo[peakdata, {Part[justtimes, i], Part[justpeaks, i]}]]; ]

(* Show the peaks with time and dBFS: *)
Grid[Prepend[peakdata, {"Time (s)", "dBFS"}], Dividers -> All]
ListPlot[{AudioLoudness[sbs, "Peak"], peakdata}, PlotRange -> Full, Joined -> {True, False}, PlotStyle -> {Automatic, {PointSize[0.05]}}, Frame -> True, FrameLabel -> {"Time (s)", "Noise (dBFS)"}, BaseStyle -> 18]


This returns a grid of time and dBFS data, plus the following plot:

Couldn't ask for more! :)