java - Android AudioRecord - 如何获得一分钟的平均音量

标签 java android audio record

我有一个我构建的 AudioRecord 功能,在录制的一分钟内,我想获得以分贝为单位的平均音量。我不知道该怎么做。我什至无法确定 AudioRecord 对象是否为我提供了缓冲区数组中的完整记录数据。

这是我目前得到的代码,有人可以帮我修改一下吗?我试图找到一种在线方式,但我还没有找到任何东西。

Runnable mrHandlerRunnable = new Runnable() {
            @Override
            public void run() {
                ar.stop();
                short[] buffer = new short[minSize];
                Log.d("LEN: " , ""+buffer.length);
                ar.read(buffer, 0, minSize);
                int max = Integer.MIN_VALUE;
                int min = Integer.MAX_VALUE;
                Double avg = 0.0;
                for (short s : buffer)
                {
                    if (Math.abs(s) > max)
                    {
                        max = Math.abs(s);
                    }
                    if (Math.abs(s) < min)
                    {
                        min = Math.abs(s);
                    }
                    avg = avg+Math.abs(s);
                }
                avg = avg/buffer.length;

                ar.startRecording();

            }
        };
        mrHandler.postDelayed(mrHandlerRunnable, 60000);

最佳答案

试试这个:

public class NoiseRecorder 
{

private final String TAG = SoundOfTheCityConstants.TAG;
public static double REFERENCE = 0.00002;

public double getNoiseLevel() throws NoValidNoiseLevelException
{
    Logging.e(TAG, "start new recording process");
    int bufferSize = AudioRecord.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_DEFAULT,AudioFormat.ENCODING_PCM_16BIT);
    //making the buffer bigger....
    bufferSize=bufferSize*4;
    AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            44100, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, bufferSize);

    short data [] = new short[bufferSize];
    double average = 0.0;
    recorder.startRecording();
    //recording data;
    recorder.read(data, 0, bufferSize);

    recorder.stop();
    Logging.e(TAG, "stop");
    for (short s : data)
    {
        if(s>0)
        {
            average += Math.abs(s);
        }
        else
        {
            bufferSize--;
        }
    }
    //x=max;
    double x = average/bufferSize;
    Logging.e(TAG, ""+x);
    recorder.release();
    Logging.d(TAG, "getNoiseLevel() ");
    double db=0;
    if (x==0){
        NoValidNoiseLevelException e = new NoValidNoiseLevelException(x);
        throw e;
    }
    // calculating the pascal pressure based on the idea that the max amplitude (between 0 and 32767) is 
    // relative to the pressure
    double pressure = x/51805.5336; //the value 51805.5336 can be derived from asuming that x=32767=0.6325 Pa and x=1 = 0.00002 Pa (the reference value)
    Logging.d(TAG, "x="+pressure +" Pa");
    db = (20 * Math.log10(pressure/REFERENCE));
    Logging.d(TAG, "db="+db);
    if(db>0)
    {
        return db;
    }
    NoValidNoiseLevelException e = new NoValidNoiseLevelException(x);
    throw e;
}
}

这会计算 4 秒样本中音频的平均振幅。一旦获得平均振幅,它就会被转换为 db。希望对您有所帮助。

关于java - Android AudioRecord - 如何获得一分钟的平均音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41798097/

相关文章:

java - 安卓通知延迟

java - 防止 Tika 使用 TNEFParser

android - Firebase:如何在 Android 应用中设置默认通知 channel ?

java - 调用异步任务类不起作用

java - Android 中的实时音频处理

c++ - 实时音频应用,提升性能

java - 定时器循环或替代方案?

java - App Engine 数据存储 - 查询枚举字段

android - 使用 Robolectric 模拟 HttpResponse

ios - SKScene中的AVAudio Player错误