1. 程式人生 > >Android 音視頻深入 二 AudioTrack播放pcm(附源碼下載)

Android 音視頻深入 二 AudioTrack播放pcm(附源碼下載)

實例 固定 回放 chan pla ng- stream 需要 大小

本篇項目地址,名字是錄音和播放PCM,求star
https://github.com/979451341/Audio-and-video-learning-materials

1.AudioTrack官方說明
AudioTrack允許PCM音頻緩沖器流到音頻接收器進行回放。這是通過“推”的數據對象的信號使用 write(byte[], int, int) and write(short[], int, int) 方法。
一個信號可以在兩種模式下運行:靜態或流。
在流模式中,應用程序寫一個連續的數據流的信號,采用write()方法。這些都是封閉和返回時,數據已經從java層轉移到本地層排隊等候播放。在播放音頻數據塊時,流模式最為有用:

由於播放聲音的持續時間太大而不適合於記憶,因為音頻數據的特性(采樣率高)
在處理適合於內存的短聲音時,應該選擇靜態模式,並且需要以最小的延遲進行播放。因此,靜態模式更適合於經常播放的UI和遊戲聲音,並且可能開銷最小。
在創作中,一個聲道對象初始化其相關音頻緩沖區。這個緩沖區的大小,規定在施工過程中,確定多長時間的信號可以跑出來的數據之前玩。
使用靜態模式的信號,這是聲音的大小,可以發揮它的最大尺寸。
對於流模式,數據將被寫入音頻接收器,其大小小於或等於總緩沖區大小。信號不是終點,從而允許子類,但不推薦使用。

2.AudioTrack何如創建和配置

static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)

public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
        int bufferSizeInBytes, int mode)

sampleRateInHz:采集率,有8000、20100等,一般來說越高音質越好,但文件體積就越大

streamType:音頻流的類型,STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC, STREAM_ALARM, and STREAM_NOTIFICATION,這個參數和Android中的AudioManager有關系,涉及到手機上的音頻管理策略。

channelConfig:聲道,單聲道CHANNEL_OUT_MONO 和雙聲道 CHANNEL_OUT_STEREO

audioFormat:采樣點大小,只有ENCODING_PCM_16BIT 和 ENCODING_PCM_8BIT兩種選擇,意思是一個采集點16bit或8bit

bufferSizeInBytes:AudioTrack一次所能接收最小的聲音資源大小,通過getMinBufferSize函數獲取,

mode:有MODE_STATIC和MODE_STREAM兩種分類。
STREAM的意思是由用戶在應用程序通過write方式把數據一次一次得寫到audiotrack中,效率低。
而STATIC的意思是一開始創建的時候,就把音頻數據放到一個固定的buffer,然後直接傳給audiotrack,只有讀取一次,這種方法對於鈴聲等內存占用較小,延時要求較高的聲音來說很適用。
3.AudioTrack使用

其實這個和AudioRecord一樣的道理,因為是播放,所以播放文件存在,直接讀取文件,通過流的形式一次一次的讀取數據,同時播放

首先創建AudioTrack
bufferSize = AudioTrack.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);

    // 實例AudioTrack
    track = new AudioTrack(AudioManager.STREAM_MUSIC,
            8000,
            AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSize,
            AudioTrack.MODE_STREAM);

接著

track.play()

然後循環讀取數據,讀完了就stop(),自己中斷的話就停止循環

            track.play();
            //writeToFileHead();
            while (isStart) {
                if (null != track&&dis.available() > 0) {

                    int i = 0;

                    while (dis.available() > 0 && i < buffer.length){
                        buffer[i] = dis.readShort();
                        i++;
                    }

                    track.write(buffer,0,buffer.length);

                }
            }
            track.stop();

需要註意的是資源的及時釋放

        if (track != null) {
            if (track.getState() == AudioRecord.STATE_INITIALIZED) {
                track.stop();
            }
            if (track != null) {
                track.release();
            }
        }
        if (dis != null) {
            dis.close();
        }

4.AudioRecord和AudioTrack的對比

兩者的功能剛好相反,一個產生pcm一個讀取pcm,而運作的過程非常相似,都對流情有獨鐘,都是一次吃不了這麽多,慢慢的吃,

            mRecorder.startRecording();
            //writeToFileHead();
            while (isStart) {
                if (null != mRecorder) {
                    bytesRecord = mRecorder.read(tempBuffer, 0, bufferSize);
                    if (bytesRecord == AudioRecord.ERROR_INVALID_OPERATION || bytesRecord == AudioRecord.ERROR_BAD_VALUE) {
                        continue;
                    }
                    if (bytesRecord != 0 && bytesRecord != -1) {
                        //在此可以對錄制音頻的數據進行二次處理 比如變聲,壓縮,降噪,增益等操作
                        //我們這裏直接將pcm音頻原數據寫入文件 這裏可以直接發送至服務器 對方采用AudioTrack進行播放原數據
                        dos.write(tempBuffer, 0, bytesRecord);
                    } else {
                        break;
                    }
                }
            }

就連資源釋放都相似

        if (mRecorder != null) {
            if (mRecorder.getState() == AudioRecord.STATE_INITIALIZED) {
                mRecorder.stop();
            }
            if (mRecorder != null) {
                mRecorder.release();
            }
        }
        if (dos != null) {
            dos.flush();
            dos.close();
        }

完整的代碼請看文章首部項目地址

Android 音視頻深入 二 AudioTrack播放pcm(附源碼下載)