Android音頻開(kāi)發(fā)之AudioRecord/Track

AudioRecord采集的是原始音頻數(shù)據(jù),一般的音頻播放器無(wú)法直接播放PCM未編碼的原始數(shù)據(jù)
/**

  • Audio:采集原始(未編碼)的數(shù)據(jù)(PCM)
  • AudioTrack:播放未編碼的PCM原始音頻數(shù)據(jù)
  • Audio主要是實(shí)現(xiàn)邊錄邊播(AudioRecord+AudioTrack)以及對(duì)音頻的實(shí)時(shí)處理(如會(huì)說(shuō)話的湯姆貓、語(yǔ)音)
  • 優(yōu)點(diǎn):語(yǔ)音的實(shí)時(shí)處理,可以用代碼實(shí)現(xiàn)各種音頻的封裝
  • 缺點(diǎn):輸出是PCM語(yǔ)音數(shù)據(jù),如果保存成音頻文件,是不能夠被播放器播放的,所以必須先寫(xiě)代碼實(shí)現(xiàn)數(shù)據(jù)編碼以及壓縮
    */
實(shí)現(xiàn):
public class MyAudio {

    /**
     * 采集音頻數(shù)據(jù):
     * 1:配置參數(shù),初始化音頻緩沖區(qū)
     * 2:采集數(shù)據(jù)
     * 3:從緩沖區(qū)讀取音頻數(shù)據(jù)
     * 4:停止采集,釋放資源
     */
    //采集緩沖區(qū)的大小
    private int receiveBufSize;
    //播放緩沖區(qū)的大小
    private int playBufSize;
    //采樣率
    private static final int SAMPLE_RATE_HZ = 44100;
    //采集通道數(shù)
    private static final int CHANNEL_IN_COUNT = AudioFormat.CHANNEL_IN_MONO;
    //播放通道數(shù)
    private static final int CHANNEL_OUT_COUNT = AudioFormat.CHANNEL_OUT_MONO;
    //位數(shù)
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    private AudioRecord audioRecord;
    private AudioTrack audioTrack;

    public MyAudio() {
        receiveBufSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_IN_COUNT, AUDIO_FORMAT);
        playBufSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_OUT_COUNT, AUDIO_FORMAT);


    }

    private boolean isRecording = false;

    public void startRecord() {
        isRecording = true;

        if (audioRecord == null)
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    SAMPLE_RATE_HZ, CHANNEL_IN_COUNT, AUDIO_FORMAT, receiveBufSize);
        if (audioTrack == null)
            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE_HZ,
                    CHANNEL_OUT_COUNT, AUDIO_FORMAT, playBufSize, AudioTrack.MODE_STREAM);

        new RecodeThread().start();
    }

    public void stopRecord() {
        isRecording = false;
        //結(jié)束播放和采集
        audioTrack.stop();
        audioRecord.stop();
    }

    class RecodeThread extends Thread {

        @Override
        public void run() {

            byte[] buffer = new byte[receiveBufSize];
            audioRecord.startRecording();
            audioTrack.play();

            while (isRecording) {
                //從音頻緩沖區(qū)讀取音頻數(shù)據(jù)
                audioRecord.read(buffer, 0, receiveBufSize);

                //播放聲音
                audioTrack.write(buffer, 0, receiveBufSize);
            }

        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容