【问题标题】:Decibel Sound Meter for Android适用于 Android 的分贝声级计
【发布时间】:2012-03-07 08:04:23
【问题描述】:

我是 Android 的新手,并希望编写一个应用程序来测量分贝声级。这个想法是,当声音达到一定水平时,用户会收到警报。就是这样。谁能帮我解决这个问题。我可以使用 HTML5/Javascript 做到这一点吗?任何帮助将不胜感激。

【问题讨论】:

    标签: android audio native decibel


    【解决方案1】:

    取自Android Media Player Decibel Reading

    对于基于原生 android/java 的 MediaRecorder 分贝计算:

    mRecorder = new MediaRecorder();
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mRecorder.setOutputFile("/dev/null"); 
    mRecorder.prepare();
    mRecorder.start();
       public double getAmplitude() {
                if (mRecorder != null)
                        return  (mRecorder.getMaxAmplitude());
                else
                        return 0;
    
        }
    

    计算Db值:

      powerDb = 20 * log10(getAmplitude() / referenceAmp);
    

    参考:http://en.wikipedia.org/wiki/Decibel#Field_quantities

    不确定您是否可以在 Android 上的 HTML5 中执行此操作

    【讨论】:

    • 什么是参考放大器?
    • 7 年后没有人知道什么是 referenceAmp :)
    【解决方案2】:

    这段代码对我有用:

    import android.app.Activity;
    import android.media.MediaRecorder;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.Log;
    import android.widget.TextView;
    
    public class Noise extends Activity {
    
        TextView mStatusView;
        MediaRecorder mRecorder;
        Thread runner;
        private static double mEMA = 0.0;
        static final private double EMA_FILTER = 0.6;
    
        final Runnable updater = new Runnable(){
    
            public void run(){          
                updateTv();
            };
        };
        final Handler mHandler = new Handler();
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.noiselevel);
            mStatusView = (TextView) findViewById(R.id.status);
    
    
            if (runner == null)
            { 
                runner = new Thread(){
                    public void run()
                    {
                        while (runner != null)
                        {
                            try
                            {
                                Thread.sleep(1000);
                                Log.i("Noise", "Tock");
                            } catch (InterruptedException e) { };
                            mHandler.post(updater);
                        }
                    }
                };
                runner.start();
                Log.d("Noise", "start runner()");
            }
        }
    
        public void onResume()
        {
            super.onResume();
            startRecorder();
        }
    
        public void onPause()
        {
            super.onPause();
            stopRecorder();
        }
    
        public void startRecorder(){
            if (mRecorder == null)
            {
                mRecorder = new MediaRecorder();
                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                mRecorder.setOutputFile("/dev/null"); 
                try
                {           
                    mRecorder.prepare();
                }catch (java.io.IOException ioe) {
                    android.util.Log.e("[Monkey]", "IOException: " + android.util.Log.getStackTraceString(ioe));
    
                }catch (java.lang.SecurityException e) {
                    android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
                }
                try
                {           
                    mRecorder.start();
                }catch (java.lang.SecurityException e) {
                    android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
                }
    
                //mEMA = 0.0;
            }
    
        }
        public void stopRecorder() {
            if (mRecorder != null) {
                mRecorder.stop();       
                mRecorder.release();
                mRecorder = null;
            }
        }
    
        public void updateTv(){
            mStatusView.setText(Double.toString((getAmplitudeEMA())) + " dB");
        }
        public double soundDb(double ampl){
            return  20 * Math.log10(getAmplitudeEMA() / ampl);
        }
        public double getAmplitude() {
            if (mRecorder != null)
                return  (mRecorder.getMaxAmplitude());
            else
                return 0;
    
        }
        public double getAmplitudeEMA() {
            double amp =  getAmplitude();
            mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
            return mEMA;
        }
    
    }
    

    【讨论】:

    • Patrick,当您调用 soundDb(double ampl) 时,您如何确定参数?这个基准值是纠正分贝转换的关键
    • 我使用 ampl = 10exp(-7)。您可以尝试其他值并将您的结果与其他声级应用程序进行比较。因此,您选择工作最好的人
    【解决方案3】:

    我认为您需要澄清“分贝”的含义。有几种不同类型的 dB,它们的含义完全不同。 Soham 为您提供的示例计算相对于参考幅度的峰值 dB,原始文章建议使用最大数字值 1.0。这意味着对于 16 位音频捕获,您将获得的值将介于 -96dB 和 0dB 之间。

    我怀疑您想要做的是测量声压级(语音约为 50dB 的范围,喷气机头顶 120dB)。这实际上称为'db (SPL)'。除非您有某种方法可以针对特定的功率水平校准您的设备,否则您将无法在您的设备上执行此操作。

    您还需要进一步考虑。一是您是否需要峰值或 RMS 功率电平(瞬时事件的峰值,音乐等连续声音的 RMS)。您还需要知道如何关闭设备上的任何自动增益控制,因为这会使任何测量变得毫无意义。

    【讨论】:

      猜你喜欢
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 2014-06-09
      • 2017-01-09
      相关资源
      最近更新 更多