基于Media Recorder的分贝计数值异常偏高问题求助
Hey there! Let's break down why your decibel meter is showing those wonky 0-30000 values in quiet environments instead of the expected 30-40 dB.
The Core Problem
You're making a classic mix-up: you’re displaying raw audio amplitude values instead of calculated decibels. Your getAmplitudeEMA() method returns smoothed raw sound wave intensity (a direct sample from the microphone), not the logarithmic decibel scale you need for a functional meter.
Why This Happens
- MediaRecorder’s raw amplitude ranges from 0 to 32767 (since Android uses 16-bit audio sampling, where 32767 is the maximum possible value). That 0-30000 you’re seeing is totally valid for quiet settings—just not the dB measurement you expect.
- Decibels aren’t a direct linear measurement; they’re a logarithmic comparison to a reference sound level (usually the quietest sound humans can hear, ~20 micro帕). You need a specific formula to convert raw amplitude to this scale.
How to Implement the Correct soundDB() Method
Here’s a properly calibrated implementation to fix your readings, including smoothing and edge-case handling:
// Your existing EMA smoothing for amplitude is fine—keep this private double emaAmplitude = 0; private final double alpha = 0.8; // Adjust for smoother/faster response private double getAmplitudeEMA() { double rawAmp = mediaRecorder.getMaxAmplitude(); emaAmplitude = alpha * emaAmplitude + (1 - alpha) * rawAmp; return emaAmplitude; } // This is the method you should call for decibel readings public double soundDB() { double smoothedAmplitude = getAmplitudeEMA(); // Avoid log10(0) which will throw an error if (smoothedAmplitude <= 0) { return 0; } // Step 1: Calculate dB relative to maximum possible amplitude (32767 = 0 dBFS) double dbFS = 20 * Math.log10(smoothedAmplitude / 32767.0); // Step 2: Convert dBFS to real-world sound pressure level (SPL) // dBFS 0 = maximum microphone input; quiet rooms are ~-90 dBFS // Adjust this offset to calibrate your device to show 30-40 dB in quiet settings double splOffset = 90; return dbFS + splOffset; }
Quick Calibration Tip
If the reading still isn’t landing in the 30-40 dB range for quiet environments:
- Run your app in a silent room and note the raw
getAmplitudeEMA()value (e.g., let’s say it’s 120). - Replace the dB calculation with this calibrated version:
double quietReferenceAmplitude = 120; // Your measured quiet raw amplitude return 20 * Math.log10(smoothedAmplitude / quietReferenceAmplitude);
The Final Fix
Wherever you’re displaying the decibel value in your UI, swap out calls to getAmplitudeEMA() with soundDB(). That’s the missing piece—you were showing raw amplitude instead of the converted decibel reading.
内容的提问来源于stack exchange,提问作者Gyllenhaal Luke

