AudioRecord

AudioRecord简介

1.AudioRecord与MediaRecorder一样用来录制音频的
2.AudioRecord可以对录制的数据进行实时的处理,比如降噪,除杂,或者将音频进行实时传输,比如IP电话,对讲功能等操作。
3.AudioRecord比MediaRecorder更接近底层,录制的音频是PCM格式的,只能用AudioTraker进行播放,或者将PCM数据转换成amr,wav等格式播放。

AudioRecord使用

AudioRecord以pulling方式通过read()方法对缓冲区的数据进行轮询,来实时的获取缓冲区的数据。
下面来看如何使用:

// 读取数据流  返回int,读取到的字节数
public int read (byte[] audioData, int offsetInBytes, int sizeInBytes)
public int read (float[] audioData, int offsetInFloats, int sizeInFloats, int readMode)
public int read (ByteBuffer audioBuffer, int sizeInBytes, int readMode)

// 构造方法
public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

    audioSource:VOICE_CALL,VOICE_COMMUNICATION。。。。
    sampleRateInHz  44100,22050,16000
    channelConfig   CHANNEL_IN_MONO and CHANNEL_IN_STEREO

    audioFormat ENCODING_PCM_8BIT ENCODING_PCM_16BIT ENCODING_PCM_FLOAT.
    bufferSizeInBytes   由getMinBufferSize(int, int, int)决定


// 获取成功创建AudioRecord 的最小缓冲区的大小
public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)

AudioTrack

说了录音,那么播放就得说到AudioTrack,专门用来播放PCM数据.

下面是录制与播放的代码,时间太晚了,还没有测试。

package com.asia.pcm2amr;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import android.annotation.TargetApi;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class AudioTest {

    static String mPath = Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/AAA/";
    private AudioRecord mAudioRecord;
    private AudioTrack mAudioTrack;
    private boolean mIsAudioing = false;
    private boolean mIsPlaying = false;
    private int mMinBufferSize;
    private int mRecordTime = 20;
    private int mFileCount = 10;
    private static AudioTest mAudioTest;

    public static AudioTest getInstance() {

        if (mAudioTest == null) {

            mAudioTest = new AudioTest();
        }
        return mAudioTest;
    }

    public void createObject(int sampleRateInHz) {
        int audioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
        int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
        int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

        mMinBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,
                channelConfig, audioEncoding);

        int bufferSizeInBytes = mMinBufferSize * 2;
        mAudioRecord = new AudioRecord(audioSource, sampleRateInHz,
                channelConfig, audioEncoding, bufferSizeInBytes);

        int playBufSize = AudioTrack.getMinBufferSize(sampleRateInHz,
                channelConfig, audioEncoding);
        mAudioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
                sampleRateInHz, channelConfig, audioEncoding, playBufSize,
                AudioTrack.MODE_STREAM, mAudioRecord.getAudioSessionId());
    }

    public boolean isInitSucces() {

        boolean initRecorder = mAudioRecord != null
                && mAudioRecord.getState() == AudioRecord.STATE_INITIALIZED;
        boolean initPlayer = mAudioTrack != null
                && mAudioTrack.getState() == AudioTrack.STATE_INITIALIZED;
        return initRecorder && initPlayer;
    }

    public void startAudio() {

        mIsAudioing = true;
        new AudioThread(++mFileCount + ".pcm").start();
    }

    public void stopAudio() {

        mIsAudioing = false;
        if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {

            mAudioRecord.stop();
        }
    }

    public void startPlayer() {

        mIsPlaying = true;
        new PlayThread().start();
    }

    public void stopPlayer() {

        mIsPlaying = false;
        if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {

            mAudioTrack.stop();
        }
    }

    /**
     * 结束录音与播放
     */
    public void stopVoice() {

        stopAudio();
        stopPlayer();

        mAudioRecord.release();
        mAudioRecord = null;
        mAudioTrack.release();
        mAudioTrack = null;
    }

    private class PlayThread extends Thread {

        public void run() {

            try {
                android.os.Process
                        .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
            } catch (Exception e) {
            }

            try { 
                File file = new File(mPath, 15 + ".pcm");
                FileInputStream inputStream = new FileInputStream(file);

                byte[] audioData = new byte[mMinBufferSize];
                mAudioTrack.play();
                while (mIsPlaying) {

                    // 数据源
                    int read = inputStream.read(audioData, 0, mMinBufferSize);
                    mAudioTrack.write(audioData, 0, read);
                }

                inputStream.close();
                mAudioTrack.stop();
            } catch (Exception e) {

            }
        }
    }

    private class AudioThread extends Thread {

        String fileName;

        public AudioThread(String fileName) {

            this.fileName = fileName;
        }

        @Override
        public void run() {

            try {
                android.os.Process
                        .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
            } catch (Exception e) {
            }

            try {
                mAudioRecord.startRecording();
                byte[] buffer = new byte[mMinBufferSize];

                File file = new File(mPath, "" + fileName);

                FileOutputStream outputStream = new FileOutputStream(file);

                while (mIsAudioing) {

                    int read = mAudioRecord.read(buffer, 0, mMinBufferSize);
                    for (int i = 0; i < read; i++) {
                        byte b = buffer[i];
                        // 写到文件
                        outputStream.write(buffer, 0, read);
                    }
                }

                mAudioRecord.stop();
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }
}
### AudioRecord介绍 AudioRecord是Android音频开发的核心类,专用于从音频输入设备(如麦克风)实时采集原始PCM音频数据,位于android.media.AudioRecord包中,与MediaRecorder一样可用来录制音频。它比MediaRecorder更接近底层,能对录制的数据进行实时处理,如降噪、除杂或实时传输,适用于语音识别、实时通信、音频分析等场景。其关键特性包括获取原始PCM数据、低延迟、灵活配置以及可在后台运行 [^1][^2]。 ### AudioRecord使用方法 #### 构造方法 ```java AudioRecord record = new AudioRecord( int audioSource, // 音频源(如麦克风) int sampleRateInHz, // 采样率(Hz) int channelConfig, // 声道配置(单声道/立体声) int audioFormat, // 位深度(如ENCODING_PCM_16BIT) int bufferSizeInBytes // 缓冲区大小(需≥最小缓冲区) ); ``` #### 开始录音 通过`audioRecord.startRecording();`来开始录音 [^3]。 #### 结束录音 通过`audioRecord.stop();`来结束录音。注意结束录音后,需释放资源:`audioRecord.release(); audioRecord = null;` [^3]。 ### 示例代码 ```java import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; public class AudioRecordExample { private static final int SAMPLE_RATE = 44100; private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO; private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; private AudioRecord audioRecord; private int bufferSize; public void startRecording() { // 计算最小缓冲区大小 bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT); // 创建AudioRecord实例 audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSize ); // 开始录音 audioRecord.startRecording(); // 读取音频数据 byte[] buffer = new byte[bufferSize]; while (isRecording()) { int bytesRead = audioRecord.read(buffer, 0, bufferSize); // 处理音频数据 processAudioData(buffer, bytesRead); } } public void stopRecording() { if (audioRecord != null) { // 停止录音 audioRecord.stop(); // 释放资源 audioRecord.release(); audioRecord = null; } } private boolean isRecording() { // 这里可以根据实际情况添加停止录音的条件 return true; } private void processAudioData(byte[] buffer, int bytesRead) { // 处理音频数据的逻辑 } } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值