第一部分 AudioTrack分析
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資料到音訊裝置中去。我們拭目以待。
相關文章
- 如何分析付費使用者,第一部分—RFM分析
- Statspack報告分析—第一部分:資料庫資訊資料庫
- CCTF部分賽題分析
- cuttag分析流程(部分存疑)
- ThreadLocal部分原始碼分析thread原始碼
- 01- Dify部分介面分析
- 第一部分翻譯
- Android音訊開發之AudioTrack實時播放Android音訊
- VS上使用Nuget部分分析
- DPTP實驗部分原始碼分析原始碼
- Android 音視訊開發 - 使用AudioTrack播放音訊Android音訊
- MediaPlayer和AudioTrack播放Audio的區別與聯絡
- [譯] Erlang 之禪第一部分
- WebGL基礎教程:第一部分Web
- 第一部分機器學習(一):導論機器學習
- GCD 深入理解:第一部分GC
- Android基礎第一天易忘部分Android
- 第一部分 並行問題並行
- 第一部分 學習使用ZeroMQMQ
- Google的Logo(第一部分)Go
- Nutch入門教程,第一部分
- 《閱讀筆記 - 第一部分》筆記
- 資料分析的三大組成部分
- OkHttp深入分析——基礎認知部分HTTP
- 資料結構與演算法分析(java語言描述) 部分課後習題答案 第一章資料結構演算法Java
- [譯] 是的,重新設計(第一部分)
- 第一部分:Twisted理論基礎
- 用Javascript打造粒子引擎(第一部分)JavaScript
- 第一部分:適應性計算
- 兩個viewport的故事(第一部分)View
- 某團mtgsig(逆向)第一部分
- 第一部分 入門|第一章 Django Python實戰DjangoPython
- Django來敲門~第一部分【3. 建立第一個專案】Django
- 第一講 複雜度分析複雜度
- 前端優化感想以及[譯]redux 教程 第一部分(共四部分前端優化Redux
- [譯] 用 Java 創造你的第一個區塊鏈-第一部分Java區塊鏈
- C++ 探索之旅 | 第一部分第一課:什麼是 C++C++
- Django來敲門~第一部分【4. 建立第一個模組應用】Django