第一部分 AudioTrack分析

weixin_34402408發表於2016-10-21

AudioTrack(Java層)

JAVA的AudioTrack類的程式碼在:
framework/base/media/java/android/media/AudioTrack.java中。

AudioTrack API的使用例子

先看看使用例子,然後跟進去分析。至於AudioTrack的其他使用方法和說明,需要大家自己去看API文件了。

//根據取樣率,取樣精度,單雙聲道來得到frame的大小。
int bufsize = AudioTrack.getMinBufferSize(8000,//每秒8K個點
  AudioFormat.CHANNEL_CONFIGURATION_STEREO,//雙聲道
AudioFormat.ENCODING_PCM_16BIT);//一個取樣點16位元-2個位元組
//注意,按照數字音訊的知識,這個算出來的是一秒鐘buffer的大小。


//建立AudioTrack
AudioTrack trackplayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
  AudioFormat.CHANNEL_CONFIGURATION_ STEREO,
  AudioFormat.ENCODING_PCM_16BIT,
  bufsize,
AudioTrack.MODE_STREAM);//
trackplayer.play() ;//開始
trackplayer.write(bytes_pkg, 0, bytes_pkg.length) ;//往track中寫資料
….
trackplayer.stop();//停止播放
trackplayer.release();//釋放底層資源。

建構函式

public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
            int bufferSizeInBytes, int mode)
    throws IllegalArgumentException {
        this(streamType, sampleRateInHz, channelConfig, audioFormat,
                bufferSizeInBytes, mode, AudioSystem.AUDIO_SESSION_ALLOCATE);
    }

2 StreamType
這個在構造AudioTrack的第一個引數中使用。這個引數和Android中的AudioManager有關係,涉及到手機上的音訊管理策略。
Android將系統的聲音分為以下幾類常見的(未寫全):

l STREAM_ALARM:警告聲
l STREAM_MUSCI:音樂聲,例如music等
l STREAM_RING:鈴聲
l STREAM_SYSTEM:系統聲音
l STREAM_VOCIE_CALL:電話聲音

為什麼要分這麼多呢?以前在桌上型電腦上開發的時候很少知道有這麼多的聲音型別,不過仔細思考下,發現這樣做是有道理的。例如你在聽music的時候接到電話,這個時候music播放肯定會停止,此時你只能聽到電話,如果你調節音量的話,這個調節肯定只對電話起作用。當電話打完了,再回到music,你肯定不用再調節音量了。
其實系統將這幾種聲音的資料分開管理,所以,這個引數對AudioTrack來說,它的含義就是告訴系統,我現在想使用的是哪種型別的聲音,這樣系統就可以對應管理他們了。

getMinBufferSize()

getMinBufSize函式完了後,我們得到一個滿足最小要求的緩衝區大小。這樣使用者分配緩衝區就有了依據。下面就需要建立AudioTrack物件了

AudioTrack總結

通過這一次的分析,我自己覺得有以下幾個點:

  • l AudioTrack的工作原理,尤其是資料的傳遞這一塊,做了比較細緻的分析,包括共享記憶體,跨程式的同步等,也能解釋不少疑惑了。
  • l 看起來,最重要的工作是在AudioFlinger中做的。通過AudioTrack的介紹,我們給後續深入分析AudioFlinger提供了一個切入點
  • 工作原理和流程嘛,再說一次好了,JAVA層就看最前面那個例子吧,實在沒什麼說的。
  • l AudioTrack被new出來,然後set了一堆資訊,同時會通過Binder機制呼叫另外一端的AudioFlinger,得到IAudioTrack物件,通過它和AudioFlinger互動。
  • l 呼叫start函式後,會啟動一個執行緒專門做回撥處理,程式碼裡邊也會有那種資料拷貝的回撥,但是JNI層的回撥函式實際並沒有往裡邊寫資料,大家只要看write就可以了
  • l 使用者一次次得write,那AudioTrack無非就是把資料memcpy到共享buffer中咯
  • l 可想而知,AudioFlinger那一定有一個執行緒在memcpy資料到音訊裝置中去。我們拭目以待。

相關文章