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

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

。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函数,将音量变化动态的画出来。具体代码不全贴出来的,主要讲一下这个思想。 如果有人需要可以直接留言给我, 可以发给大伙。