Android 实时获取麦克风录音的音量大小

    前几天做一个关于录音并获取音量大小的模块,今天写一个demo和大家分享。如果有各位有更好的方法可以留言提醒我,谢谢。

    首先录音功能很容易实现,通过audiorecord或者mediarecorder都可以实现,如果要获取录音音量的大小,用audiorecord更加方便。实现录音功能可以大致分为几个步骤。一 初始化录音设备audiorecord。 二 ,开启一个线程实现录音功能。 三 获取录音的音频流对它的大小进行分析。四 将大小传递至主线程使UI做出相应的改变。

    首先初始化audiorecord AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes) ,初始化需要五个参数,audiosource 是指录制源在此我们选择麦克风:MediaRecorder.AudioSource.MIC。  sampleRateInHz 默认采样频率,以赫兹为单位,官方文档说44100 为目前所有设备兼容,但是如果用模拟器测试的话会有问题,所以有的也用8000。  channelConfig ,  描述音频通道设置 CHANNEL_IN_MONO保证能在所有设备上工作。audioFormat 音频流的格式,分为16bit 或8bit目前都支持的是ENCODING_PCM_16BIT.  bufferSizeInBytes 在录制过程中,音频数据写入缓冲区的总数(字节)。 从缓冲区读取的新音频数据总会小于此值. 这个值一般通过getMinBufferSize来获取。getMinBufferSize的参数可以参照audiorecord的构造函数。在oncreate中执行一下代码。

try {
                mMinibuffer = AudioRecord.getMinBufferSize(sampleRates,
                                AudioFormat.CHANNEL_IN_MONO,
                                AudioFormat.ENCODING_PCM_16BIT);
                if(mMinibuffer != AudioRecord.ERROR_BAD_VALUE){
                        mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                      sampleRates[i],
                                      AudioFormat.CHANNEL_IN_MONO,
                                      AudioFormat.ENCODING_PCM_16BIT,
                                      mMinibuffer);
                }
            } catch (IllegalArgumentException e) {
                ;
            }

这是audiorecord的初始化,下面可以实现录音

public class RecordThread extends Thread{
        private boolean mIsRun = false;
        public RecordThread(){
            super();
        }
        public void run(){
            super.run();
            MainActivity.this.mRecord.startRecording();
            byte[]  byte_buffer = new byte[mMinibuffer];
            mIsRun = true;
            while(mIsRun){
                int r = mRecord.read(byte_buffer,0,mMinibuffer);
                int mShortArrayLenght = r/2;
                short[] short_buffer = new short[mShortArrayLenght];
                short_buffer = byteArrayToShortArray(byte_buffer,mShortArrayLenght);
                int max =  0;
                if(r > 0){
                    for(int i=0; i<mShortArrayLenght; i++){
                        if(Math.abs(short_buffer[i]) > max){
                            max = Math.abs(short_buffer[i]);
                        }
                    }
                    Bundle mBundle = new Bundle();
                    mBundle.putInt(mSendData, max);
                    Message Msg = new Message();
                    Msg.what = RECORDSTATE;
                    Msg.setData(mBundle);
                    mHandler.sendMessage(Msg);
                }
            }
            MainActivity.this.mRecord.stop();
            mHandler.sendEmptyMessage(NULLBUFFER);
        }

        public void stopRecord(){
            mIsRun = false;
        }
    }

这里是写一个线程实现录音功能。byte_buffer  保存录制的音频流,因为每次录制次数很多,我暂时将每次录音的最大值当作这次录音的音量,然后通过handler将最大值返回给主线程。如果需要停止这个线程可以通过调用这个线程函数 stopRecord(); 然后我们通过每次得到的音量值,可以通过view的ondraw函数,将音量变化动态的画出来。具体代码不全贴出来的,主要讲一下这个思想。 如果有人需要可以直接留言给我, 可以发给大伙。

好的,针对你的问题,我可以给出以下方案: 1. 写音频文件 使用AudioRecord录制音频数据后,可以将数据写入音频文件中,可以通过以下步骤实现: 1)创建一个FileOutputStream对象,用于指定音频文件的存储路径和名称; 2)创建一个byte数组,用于存储录音数据; 3)在AudioRecord的回调函数中,将录音数据写入byte数组; 4)将byte数组写入FileOutputStream中。 示例代码如下: ``` //设置音频源(麦克风) int audioSource = MediaRecorder.AudioSource.MIC; //设置采样率 int sampleRate = 44100; //设置音频通道(单声道) int channelConfig = AudioFormat.CHANNEL_IN_MONO; //设置音频编码(PCM编码) int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //计算缓冲区大小 int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); //创建AudioRecord对象 AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSize); //创建一个byte数组,用于存储录音数据 byte[] buffer = new byte[bufferSize]; //创建一个FileOutputStream对象,用于指定音频文件的存储路径和名称 FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "audio.pcm")); //开始录音 audioRecord.startRecording(); //循环读取录音数据并写入文件 while (isRecording) { int len = audioRecord.read(buffer, 0, bufferSize); fos.write(buffer, 0, len); } //停止录音 audioRecord.stop(); //关闭FileOutputStream fos.close(); ``` 2. 获取实时麦克风音量大小 使用AudioRecord录制音频数据后,可以通过计算音量大小获取麦克风实时音量大小,可以通过以下步骤实现: 1)定义一个计算音量大小的方法getVolumeLevel(),用于计算音量大小; 2)在AudioRecord的回调函数中,调用getVolumeLevel()方法获取实时音量大小。 示例代码如下: ``` //定义一个计算音量大小的方法 public int getVolumeLevel(byte[] audioData) { int sum = 0; //将byte数组转换为short数组 short[] shorts = new short[audioData.length / 2]; ByteBuffer.wrap(audioData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts); //计算音量大小 for (short s : shorts) { sum += Math.abs(s); } return sum / shorts.length; } //创建一个byte数组,用于存储录音数据 byte[] buffer = new byte[bufferSize]; //开始录音 audioRecord.startRecording(); //循环读取录音数据并计算音量大小 while (isRecording) { int len = audioRecord.read(buffer, 0, bufferSize); int volumeLevel = getVolumeLevel(buffer); } //停止录音 audioRecord.stop(); ``` 以上就是实现Android AudioRecord写音频文件和获取实时麦克风音量大小的方法,希望可以帮助到你。如果有任何问题或不足之处,欢迎指出。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值