1. 程式人生 > >android Audio 詳解( 二 )

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。