Open mcourteaux opened 2 years ago
Hi @mcourteaux , since I am not very familiar with this topic I tried to apply your feedback and the wikipedia information to noise_meter, but I would greatly appreciate your comments on this. When I was testing the dB numbers end up making a lot more sense than what was calculated previously.
double RMS = 0.0;
for (var volume in volumes) {
RMS += pow(volume, 2);
}
RMS = sqrt(RMS / volumes.length);
var dB = log(RMS / 0.00002).abs() / log10e;
The 0.00002 in this case is for the reference sound pressure mentioned in the article you sent.
There are several issues:
volumes
should be referred to as waveform
or something.pow()
is super slow. Just multiply the value with itself to compute the squared value. log10e
has a weird name. If log()
takes the natural logarithm (i.e., ln()
), then you want to convert to log10 by dividing by log(10)
. So your constant could be named log10
or ln10
or loge10
if you will.abs()
value call is really wrong. If you are struggling with negative values, that is totally normal: a negative value just tells you how many decibels the volume is below the reference value (which could mean "below the level humans can hear"). If you like to get rid of negative values, just put them to zero using max(0, ...)
.RMS = 0.0;
for (sample in audio_waveform) {
RMS += sample * sample;
}
RMS = sqrt(RMS / audio_waveform.length);
var dB = log(RMS / 20e-6) / log(10);
This noise_meter plugin does truly weird things. https://github.com/cph-cachet/flutter-plugins/blob/0a3b5e450755692cb900d70e06630caddf6c4ee9/packages/noise_meter/lib/noise_meter.dart#L13-L27
First it sorts an array (why?) then proceeds to use the largest and the smallest samples (which would probably be close to the same, just with opposite signs), and then takes the mean, which should be close to zero. Then zero is multiplied by a giant number, to then apply the formula of decibel scale on the wrong input. None of this makes sense. Depending on the randomness of the signal, half of the samples produced for "meanDecibel" will be NaN, due to negative mean value.
Looking at the formula for dB scale for audio, you need the RMS energy of the signal:
Taking a minimum and a maximum single frame is insensible, and takes O(n*log(n)) time for no reason. If you would be interested in a "mean" volume and a "maximum" volume, then you should time-bin the audio samples and apply the RMS formula on those bins. You just cannot apply the decibel formula on a single sample.