(安卓自学笔记)音量检测的两种方式

首先添加录音权限

<uses-permission android:name="android.permission.RECORD_AUDIO"/>
方式一:MediaRecorder 
private MediaRecorder mediaRecorder;
private boolean isRecording;

设置存储路径

private final String FILE = Environment.getExternalStorageDirectory() + File.separator + "volomeDemo.aac";

初始化mediaRecorder

initMediaRecorder();

public void initMediaRecorder()
    {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setOutputFile(FILE);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        Log.w("madiarecorder","初始化成功");
        try{
            mediaRecorder.prepare();
            mediaRecorder.start();
            isRecording=true;
            Log.w("madiarecorder","已启动");
        }catch(Exception e)
        {
            Log.w("madiarecorder","异常");
        }
    }

利用

mediaRecorder.getMaxAmplitude();

得到当前某一时刻检测到的音量,这个数值通常可以上万

创建一个可视的绘图线程,一会儿实时将音量绘制出来

class Draw_thread extends  Thread
    {
        @Override
        public void run(){
            while(true)
            {
                if (mediaRecorder == null) {
                    initMediaRecorder();
                }
                try{
                    myDraw();
                    Thread.sleep(30);
                }
                catch (Exception e) {
                    Log.w("线程", "异常");
                }
            }
        }
    }

利用

isRecording

记录是否在监听中

重写销毁方法

protected void onDestroy() {
        super.onDestroy();
        if (mediaRecorder!=null&&isRecording) {
            isRecording = false;
            mediaRecorder.stop();
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

方法二:AudioRecord

声明变量

    private AudioRecord audioRecord;
    private int bufferSize;
    private byte[] buffer;

初始化函数

public void initAudioRecord()
    {
        bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO , AudioFormat.ENCODING_PCM_16BIT);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSize);
        audioRecord.startRecording();
        // 用于读取的 buffer
        buffer= new byte[bufferSize];
    }

在绘图线程中获取某一时刻音量,和mediaRecorder.getMaxAmplitude();作用差不多

try {
            int r = audioRecord.read(buffer, 0, bufferSize);
            int v = 0;
            // 将 buffer 内容取出,进行平方和运算
            for (int i = 0; i < buffer.length; i++) {
                // 这里没有做运算的优化,为了更加清晰的展示代码
                v += buffer[i] * buffer[i];
            }
            // 平方和除以数据总长度,得到音量大小。可以获取白噪声值,然后对实际采样进行标准化。
            // 如果想利用这个数值进行操作,建议用 sendMessage 将其抛出,在 Handler 里进行处理。
            double dB = 10*Math.log10(v/(double)r);

得到的db就是当前音量大小

但是这个数值基本只能用来判断有没有声音,

而分别不出来音量大小,所以建议使用第一种方式

绘图函数

            canvas.drawColor(Color.BLACK);//背景
            canvas.drawLine(200,250,200,250-6*(int)dB,paint);//子线程更新UI,如果是监听器等调用的函数,是属于主线程里的!!!
            canvas.drawText(7*(int)dB+"",150,30,paint);

            int maxa=mediaRecorder.getMaxAmplitude();
            if(maxa<1600)
            {
                canvas.drawLine(100,250,100,250-maxa/8,paint);
            }
            else
            {
                canvas.drawLine(100,250,100,50,paint);
                paint.setColor(Color.RED);
                canvas.drawLine(150,250,150,250-maxa/100,paint);
                paint.setColor(Color.GREEN);
            }
            canvas.drawText(maxa+"",30,30,paint);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    iv_audio.setImageBitmap(bitmap);
                }
            });

用了draw和paint展示了一下两种方式的效果

我将第一种方法获得的音量用绿色(小数值时)+红色(大数值时)显示出来
    这个绿色随着声音的增大,变化明显
而第二种方式,基本只要有点声音,绿色就满了
    没声音时数值,还可能为负值
所以第一种好用

猜你喜欢

转载自blog.csdn.net/weixin_40980148/article/details/80370095