Use of Android AudioRecord

AudioRecord

The project achieved pcm multi-configuration (sample rate, file format optional) recording and playback tool, users can record audio.

Project code: https: //github.com/worson/AudioRecord.git

Here Insert Picture Description

Recording parameters

Andrews applications, the use AudioRecord can achieve a more flexible configuration of recording, the recording is AudioRecord raw pcm data.
AudioRecord configuration as follows:

AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

audioSource: original sound audio recording, as follows

MediaRecorder.AudioSource.CAMCORDER 
设定录音来源于同方向的相机麦克风相同,若相机无内置相机或无法识别,则使用预设的麦克风
MediaRecorder.AudioSource.DEFAULT  默认音频源
MediaRecorder.AudioSource.MIC
设定录音来源为主麦克风。
MediaRecorder.AudioSource.VOICE_CALL
设定录音来源为语音拨出的语音与对方说话的声音
MediaRecorder.AudioSource.VOICE_COMMUNICATION
摄像头旁边的麦克风
MediaRecorder.AudioSource.VOICE_DOWNLINK
下行声音
MediaRecorder.AudioSource.VOICE_RECOGNITION
语音识别
MediaRecorder.AudioSource.VOICE_UPLINK
上行声音

sampleRateInHz: audio sample rate, per second to the number of audio data collection

channelConfig: recording channels, a single channel is AudioFormat.CHANNEL_CONFIGURATION_MONO, dual channels AudioFormat.CHANNEL_CONFIGURATION_STEREO

audioFormat: the number of bits per audio sampling point, i.e., the accuracy of audio channel selection can AudioFormat.ENCODING_PCM_16BIT i.e. bit pcm 16

bufferSizeInBytes: the total number of audio data written to the buffer, the buffer by obtaining the minimum AudioRecord.getMinBufferSize.

Calculated on the amount of audio data

For a sampling rate of 16k bits 16bit deep recording parameters, the number of byte per second is: 2 * 16000 = 32000, i.e., per minute: the amount of data 32000 * 60 byte / min = 1.875 MB / min of

Recording Process

Creating recorder

public PcmRecorder(int audioSource, int sampleRate, int channelCnt, Context context, RecordListener listener) {
        mListener = listener;
        int channelConfig = channelCnt == 1 ? AudioFormat.CHANNEL_CONFIGURATION_MONO : AudioFormat.CHANNEL_CONFIGURATION_STEREO;
        int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, AUDIO_FORMAT);
        mBufSize = minBufSize;
        int bufferSizeInBytes = minBufSize;
        AILog.i(TAG, "PcmRecorder: bufferSizeInBytes " + bufferSizeInBytes);
        mAudioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, AUDIO_FORMAT, bufferSizeInBytes);
        AILog.d(TAG, "state: " + mAudioRecord.getState());
    }

start recording

Start recording, and create the data read thread

public void start() {
        AILog.d(TAG, "onStartRecord");

        mAudioRecord.startRecording();
        mRecording = true;
        mRecordThread = new RecordThread("RecordThread");
        mRecordThread.start();
        if (mListener != null) {
            mListener.onStartRecord();
        } else {
            AILog.w(TAG, "start: mListener is null");
        }
    }

Reads the audio data

Buffer continue reading sound data, and callback upper layer application processing

class RecordThread extends Thread {

        public RecordThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            AILog.v(TAG, "thread run");
            Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);

            if (mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) {
                AILog.d(TAG, "unInit");
                return;
            }

            byte[] buffer = new byte[mBufSize];
            while (!mStopFlag) {
                int len = mAudioRecord.read(buffer, 0, buffer.length);
                if (len != mBufSize) {
                    AILog.e(TAG, "record read error:" + len);
                }
                if (mListener != null) {
                    mListener.onRecordData(buffer);
                    continue;
                }
            }
            AILog.v(TAG, "thread end");
        }
    }

Stop recording

Stop recording and release resources

public void stop() {
        AILog.d(TAG, "stopRecord");
        mStopFlag = true;
        mRecording = false;
        try {
            mRecordThread.join();
        } catch (InterruptedException e) {
            AILog.d(TAG, "InterruptedException " + e.getMessage());
        } finally {
            if (mListener != null) {
                mListener.onStopRecord();
            } else {
                AILog.d(TAG, "stop: mListener is null");
            }
            mAudioRecord.stop();
            mAudioRecord.release();
        }
        mListener = null;
    }

The upper application call

private void startRecord() {
    AILog.i(TAG, "startRecord: ");
    checkEnvirement();
    if (rb_channel_dual.isChecked()) {
        mRecorder = new PcmRecorder(getAudioSource(), getAudioFrequecy(), 2);
    } else {
        mRecorder = new PcmRecorder(getAudioSource(), getAudioFrequecy(), 1);
    }
    try {
        mOutputStream = new FileOutputStream(mTempRecordFile);
        mRecorder.setRecordListener(mRecordListener);
        mRecorder.start();
        tv_tips.setText("正在录音...");
        bt_recorder.setText("结束录音");
        bt_play.setVisibility(View.INVISIBLE);
        bt_delete.setVisibility(View.INVISIBLE);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        tv_tips.setText("录音启动失败...");
    }

}

private RecordListener mRecordListener = new RecordListener() {
    @Override
    public void onStartRecord() {
        AILog.i(TAG, "onStartRecord: ");
    }

    @Override
    public void onRecordData(byte[] bytes) {
        try {
            mOutputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onStopRecord() {
        AILog.i(TAG, "onStopRecord: ");
        //保存文件
    }
};
Published 10 original articles · won praise 0 · Views 9949

Guess you like

Origin blog.csdn.net/wsx1048/article/details/104107468