android主副MIC录音

最近在做一个项目,要求给主副MIC分别录音,然后再单独播放主副MIC录制的音频文件,再网上找了许久,没有找到合适的就自己琢磨了一下AudioRecord和AudioTrack,然后曲线救国实现了改功能,以下就是全部代码了。

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import static java.lang.Daemons.start;
import static java.lang.Daemons.stop;


public class AudioRecoderUtils {
    String TAG = "AudioRecoder";
    private boolean isRecording = false;
    private boolean isPlay = false;

    byte[] mBuffer = new byte[10485760];
    Handler mHandler = new Handler(Looper.myLooper()) {
    };
    static int mBufferCount = 0;
    AudioRecord audioRecord;
    AudioTrack mAudioTrack;
    //16K采集率
    int frequency = 16000;
    //录音通道--立体音录音
    int channel = AudioFormat.CHANNEL_IN_STEREO;
    //16Bit
    int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
    AudioManager mAudioManager;

    public AudioRecoderUtils() {

    }

    public boolean getPlay(){
        return isPlay;
    }

//停止录音
    public void StopRecord() {
        isRecording = false;
        if(audioRecord != null){
            audioRecord.release();
        }
    }

    private AudioManager.OnAudioFocusChangeListener mAudioFocusChange = new AudioManager.OnAudioFocusChangeListener() {
        @Override
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_LOSS:
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    break;
                case AudioManager.AUDIOFOCUS_GAIN:
                    start();
                    break;
            }
        }
    };

//申请音频焦点
    private void beforePlay(Context context) {
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mAudioManager.requestAudioFocus(mAudioFocusChange, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    }

//退出释放
    public void releaseAudioManager(){
        if (audioRecord != null) {
            audioRecord.release();
        }
        if (mAudioTrack != null) {
            mAudioTrack.release();
        }
        if(mAudioManager != null){
            mAudioManager.abandonAudioFocus(mAudioFocusChange);
        }
    }

//开始录音
    public void StartRecord(Context context) {
    	new Thread(new Runnable() {
        	public void run() {
        		mBufferCount = 0;
        		isPlay = false;
       		 beforePlay();
        		int bufferSize = AudioRecord.getMinBufferSize(frequency, channel, audioEncoding);
        		if (audioRecord != null) {
            		audioRecord.release();
       			 }
        		long count = 0;
       			 long start = System.currentTimeMillis();
        		audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, frequency, 			channel, audioEncoding, bufferSize);
        		isRecording = true;
        audioRecord.startRecording();
        while (isRecording) {
            int n = audioRecord.read(mBuffer, mBufferCount, 12000);
            if (n > 0) {
                mBufferCount += n;
                long cc = Math.round(((double) (System.currentTimeMillis() - start)) / 1000.0d);
                if (cc != count) {
                    count = cc;
                }
            } else if (n < 0) {

            }
        }
                    }
        }).start();
        new Thread(new Runnable() {
            public void run() {
                savePCM(mBuffer, mBufferCount, "stereo.pcm");
            }
        }).start();
    }
/**
//播放音频 --- 在这里把主副MIC录制的数据单独提取出来,因为是用的CHANNEL_IN_STEREO,
//注意,因为把数据区分出来了所以在new AudioTrack的时候要用CHANNEL_IN_MONO单通道播放
//如果要播放录制的原音可以就要用CHANNEL_IN_STEREO,直接用
//mAudioTrack.write(mBuffer, 0, mBufferCount);                         
//  mAudioTrack.play();
*/
    public void PlayRecord(boolean isLeft) {
        if (mAudioTrack != null) {
            mAudioTrack.release();
        }
        isPlay = true;
        mAudioTrack = new AudioTrack(3, 16000, 4, 2, mBuffer.length, 0);
        if (isLeft) {
            new Thread(new Runnable() {
                public void run() {
                    byte[] bsleft = new byte[(mBufferCount / 2)];
                    int i = 0;
                    while (i < mBufferCount - 1 && (i / 2) + 1 < mBufferCount / 2) {
                        bsleft[i / 2] = mBuffer[i];
                        bsleft[(i / 2) + 1] = mBuffer[i + 1];
                        i += 4;
                    }
                    savePCM(bsleft, bsleft.length, "left.pcm");
                    if (mAudioTrack != null) {
                        try {
                            mAudioTrack.write(bsleft, 0, bsleft.length);
                            mAudioTrack.play();
                        } catch (Exception e) {
                            isPlay = false;
                        }
                    } else {
                        isPlay = false;
                    }
                }
            }).start();
        } else {
            new Thread(new Runnable() {
                public void run() {
                    byte[] bsright = new byte[(mBufferCount / 2)];
                    int j = 2;
                    while (j < mBufferCount - 1 && (j / 2) + 1 < mBufferCount / 2) {
                        bsright[(j / 2) - 1] = mBuffer[j];
                        bsright[j / 2] = mBuffer[j + 1];
                        bsright[(j / 2) + 1] = 0;
                        j += 4;
                    }
                    savePCM(bsright, bsright.length, "right.pcm");
                    if (mAudioTrack != null) {
                        try {
                            mAudioTrack.write(bsright, 0, bsright.length);
                            mAudioTrack.play();
                        } catch (Exception e) {
                        }
                    } else {
                    }
                }
            }).start();
        }

    }

//把录制的音频以PCM的格式写入存储里面
    public String savePCM(byte[] data, int count, String name) {
        Log.d(TAG, "开始写入 count = " + count);
        String str = null;
        if (count <= 0) {
            return str;
        }
        try {
            File path = new File(Environment.getExternalStorageDirectory() + "/record/");
            if (!path.exists())
                path.mkdirs();
            File fout = new File(Environment.getExternalStorageDirectory() + "/record/" + name);
            OutputStream out = new FileOutputStream(fout);
            out.write(data, 0, count);
            out.close();
            Log.d(TAG, "写入成功");
            return fout.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "写入失败");
            return str;
        }
    }
}

PlayRecord可以分别播放左右MIC的录音音频,在播放之后自动保存了一个PCM文件在内置存储里面,
所以要记得加SD卡存储权限和录音权限

<uses-permission android:name="android.permission.RECORD_AUDIO" />

一边录音一边播放

    public void StartRecord() {
        mBufferCount = 0;
        beforePlay(this);
        int bufferSize = AudioRecord.getMinBufferSize(frequency, channel, audioEncoding);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, frequency, channel, audioEncoding, bufferSize);
        mAudioTrack = new AudioTrack(3, frequency, channel, audioEncoding, mBuffer.length, 0);
        isRecording = true;
        audioRecord.startRecording();
        while (isRecording) {
            int n = audioRecord.read(mBuffer, mBufferCount, 12000);
            mAudioTrack.write(mBuffer, 0, mBuffer.length);
            if (n > 0) {
                mAudioTrack.play();
                mBufferCount += n;
            }
        }
    }
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值