3
$\begingroup$

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!

$\endgroup$
  • $\begingroup$ I couldn't import your file. $\endgroup$ – aardvark2012 Oct 25 '17 at 22:46
  • $\begingroup$ Fixed, thanks for pointing that out... $\endgroup$ – Matt Stein Oct 26 '17 at 0:14
  • 3
    $\begingroup$ 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). $\endgroup$ – aardvark2012 Oct 26 '17 at 0:33
2
$\begingroup$

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]
$\endgroup$
  • $\begingroup$ That also works great, but provides better information for finally getting dBSPL. Thanks! $\endgroup$ – Matt Stein Nov 1 '17 at 2:12
1
$\begingroup$

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: enter image description here

Couldn't ask for more! :)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.