android Audio 詳解( 二 )
android Audio 詳解( 二 )
2018年01月04日 15:57:45 韓半仙 閱讀數:302更多
個人分類: linux驅動
2 tinyalsa
tinyalsa是Google在Android 4.0之後推的基於alsa核心的使用者層音訊介面。在Android 4.0之前還一直是使用這alsa-lib介面。Google之所以推出tinyalsa,可能是因為alsa使用了GPL許可證的緣故,也有可能是因為alsa-lib的庫過於複雜繁瑣而大部分功能在Android平臺沒有實際實用意義卻依然佔用屈指可數的記憶體空間。Google在Android4.0之後推出了tinyalsa 。
tinyalsa的原始碼位於 external/tinyalsa/目錄下。
tinyalsa的原始碼包括兩部分,tinyalsa庫檔案和小工具。
tinyalsa庫檔案的原始碼有兩個,是mixer.c pcm.c。其中mixer.c提供了控制介面。pcm.c提供了PCM播放、錄音的介面。
tinyalsa工具包括了四個檔案,tinyplay.c、tinycap.c、tinymix.c、tinypcminfo.c。每個檔案對應一個可執行檔案。tinyplay 是一個簡單的播放器,可以播放WAV檔案。tinycap是一個簡單的錄音程式,可以進行錄音並儲存到一個wav檔案中。tinymix用於配置control,例如切換音訊通道等等。tinypcminfo獲取PCM的引數的示例,例如取樣率的範圍、通道數的範圍等等。
2.1 PCM播放錄音說明。
重要的資料結構
struct pcm_config {
unsigned int channels;
unsigned int rate;
unsigned int period_size;
unsigned int period_count;
enum pcm_format format;
/* Values to use for the ALSA start, stop and silence thresholds. Setting
* any one of these values to 0 will cause the default tinyalsa values to be
* used instead. Tinyalsa defaults are as follows.
*
* start_threshold : period_count * period_size
* stop_threshold : period_count * period_size
* silence_threshold : 0
*/
unsigned int start_threshold;
unsigned int stop_threshold;
unsigned int silence_threshold;
/* Minimum number of frames available before pcm_mmap_write() will actually
* write into the kernel buffer. Only used if the stream is opened in mmap mode
* (pcm_open() called with PCM_MMAP flag set). Use 0 for default.
*/
int avail_min;
};
.channels :通道數
.rate : 取樣率
.period_size : 每次傳輸的資料長度。值越小,時延越小,cpu佔用就越高。
.period_count: 緩衝區period的個數。緩衝區越多,發生XRUN的機會就越少。
.format : 定義資料格式,如資料寬度
.start_threshold : 緩衝區的資料超過該值時,硬體開始啟動資料傳輸。
.stop_threshold : 緩衝區空閒區大於該值時,硬體停止傳輸。預設情況下,這個數 為整個緩衝區的大小,即整個緩衝區空了,就停止傳輸。
.avail_min : 緩衝區空閒區大於該值時,pcm_mmap_write()往緩衝寫資料。
播放和錄音的呼叫可以參考tinyplay.c、tinycap.c裡面的示例。
2.1 mix使用說明。
2.1.1 開啟mixer裝置
struct mixer *mixer = mixer_open(card);
card是一個整型的變數。是音效卡的控制器的編號。mixer_open會開啟controlCX,card就是對應X的數值。
我們在/dev/snd/目錄下用ls命令就可以看到相關的音效卡裝置。
2.1.2 mixer的讀寫
首先獲得mixer_ctl的指標。
mixer_ctl ctl =mixer_get_ctl_by_name(mixer, name);
引數name就是control的名稱,就是要和我們前面介紹的snd_kcontrol_new結構中name相匹配。
也可以通過id來得到mixer_ctl的指標。
mixer_ctl ctl =mixer_get_ctl(mixer, id);
這個id和驅動中新增control的順序是一樣的,例如第一個control的id是0,第二個是1...
設定control的值。
mixer_ctl_set_value(ctl, index, value);
前面講過control的名稱相同,則通過index來區分,這個index就是和snd_kcontrol_new結構中index相匹配的。如果沒有同名的control,那麼index就直接設為0。value為要設定的值。
讀control的值
mixer_ctl_get_value(ctl, index);
詳細的程式碼可以參考tinymix.c。