alsa相關的配置文件 .

在根文件系統下,alsa相關的配置文件有:

在/system/usr/share/alsa目錄下:

  1. ├── alsa.conf  
  2. ├── cards  
  3. │   └── aliases.conf  
  4. └── pcm  
  5.     ├── center_lfe.conf  
  6.     ├── default.conf  
  7.     ├── dmix.conf  
  8.     ├── dpl.conf  
  9.     ├── dsnoop.conf  
  10.     ├── front.conf  
  11.     ├── iec958.conf  
  12.     ├── modem.conf  
  13.     ├── rear.conf  
  14.     ├── side.conf  
  15.     ├── surround40.conf  
  16.     ├── surround41.conf  
  17.     ├── surround50.conf  
  18.     ├── surround51.conf  
  19.     └── surround71.conf  
  1. ├── alsa.conf  
  2. ├── cards  
  3. │   └── aliases.conf  
  4. └── pcm  
  5.     ├── center_lfe.conf  
  6.     ├── default.conf  
  7.     ├── dmix.conf  
  8.     ├── dpl.conf  
  9.     ├── dsnoop.conf  
  10.     ├── front.conf  
  11.     ├── iec958.conf  
  12.     ├── modem.conf  
  13.     ├── rear.conf  
  14.     ├── side.conf  
  15.     ├── surround40.conf  
  16.     ├── surround41.conf  
  17.     ├── surround50.conf  
  18.     ├── surround51.conf  
  19.     └── surround71.conf  
  1. ├── alsa.conf  
  2. ├── cards  
  3. │   └── aliases.conf  
  4. └── pcm  
  5.     ├── center_lfe.conf  
  6.     ├── default.conf  
  7.     ├── dmix.conf  
  8.     ├── dpl.conf  
  9.     ├── dsnoop.conf  
  10.     ├── front.conf  
  11.     ├── iec958.conf  
  12.     ├── modem.conf  
  13.     ├── rear.conf  
  14.     ├── side.conf  
  15.     ├── surround40.conf  
  16.     ├── surround41.conf  
  17.     ├── surround50.conf  
  18.     ├── surround51.conf  
  19.     └── surround71.conf  
 

/system/etc/asound.state

 

這些配置文件是如何工作的?

alsa-lib是如何解析這些腳本的?

上層app是如何實現不同需要中的通道選擇,音量調整等???比如手機使用過程中打電話/錄音/藍牙耳機輸入/外放喇叭輸入.......

 

下面分別分析這些配置腳本。

+++++++++++++++++++++++++++++++++++++++++++++++

 

【/system/etc/asound.state】

asound.state用來控制音頻通道的初始設置。使用方法:

1 使用alsa_ctl store來將當前音頻的初始設置導出爲asound.state文件。

2 修改文件內容:設置播放/錄製的通道,增益等。

3 使用alsa_ctl restore 重新加載修改過的配置。

4 在init.rc中添加一行,用於系統啓動是自動加載此配置:

  1. service asound_conf /system/bin/alsa_ctl restore  
  2.     oneshot  
  1. service asound_conf /system/bin/alsa_ctl restore  
  2.     oneshot  
  1. service asound_conf /system/bin/alsa_ctl restore  
  2.     oneshot  
 

asound.state中的信息是抽取在驅動裏面註冊的snd_controls的信息。

 

 

 

 

【/system/usr/share/alsa/alsa.conf】

 

這裏主要參考整理 http://hi.baidu.com/zmjdx/blog/item/35d570347a36e947241f1475.html

 

ALSA的配置文件alsa.conf定義了一些簡單的語法,通過這些語法記錄了alsa環境變量。

 

該文件開頭處包含了用戶可以配置的hook.

用戶自定義的配置信息可以保存在/etc/asound.conf或~/.asoundrc裏,當然也可以自己定義的位置。

我們感興趣的是,alsa lib是如何解析這些配置的。

 

首先我們可以從使用alsa lib時,最先的入口函數snd_pcm_open處開始說起:

  1. int snd_pcm_open(snd_pcm_t **pcmp, const char *name,  
  2. snd_pcm_stream_t stream, int mode)  
  3. {  
  4. int err;  
  5. assert(pcmp && name);  
  6. err = snd_config_update();  
  7. if (err < 0)  
  8. return err;  
  9. return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);  
  10. }  
  1. int snd_pcm_open(snd_pcm_t **pcmp, const char *name,  
  2. snd_pcm_stream_t stream, int mode)  
  3. {  
  4. int err;  
  5. assert(pcmp && name);  
  6. err = snd_config_update();  
  7. if (err < 0)  
  8. return err;  
  9. return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);  
  10. }  
  1. int snd_pcm_open(snd_pcm_t **pcmp, const char *name,  
  2. snd_pcm_stream_t stream, int mode)  
  3. {  
  4. int err;  
  5. assert(pcmp && name);  
  6. err = snd_config_update();  
  7. if (err < 0)  
  8. return err;  
  9. return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);  
  10. }  
 

其中調用了函數snd_config_update(),這個函數就是加載alsa的配置文件中配置信息的。

這個函數直接調用了 snd_config_update_r,見下面函數註釋:

  1. /**  
  2.  * /brief Updates a configuration tree by rereading the configuration files (if needed). 
  3.  * /param _top Address of the handle to the top level node. 
  4.  * /param _update Address of a pointer to private update information. 
  5.  * /param cfgs A list of configuration file names, delimited with ':'. 
  6.  *             If /p cfgs is set to /c NULL, the default global configuration 
  7.  *             file is used ("/usr/share/alsa/alsa.conf"). 
  8.  * /return A non-negative value if successful, otherwise a negative error code. 
  9.  * /retval 0 No action is needed. 
  10.  * /retval 1 The configuration tree has been rebuilt. 
  11.  * 
  12.  * The global configuration files are specified in the environment variable 
  13.  * /c ALSA_CONFIG_PATH. 
  14.  * 
  15.  * /warning If the configuration tree is reread, all string pointers and 
  16.  * configuration node handles previously obtained from this tree become invalid. 
  17.  */  
  18. int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, const char *cfgs)  
  19. {  
  20. int err;  
  21. const char *configs, *c;  
  22. unsigned int k;  
  23. size_t l;  
  24. snd_config_update_t *local;  
  25. snd_config_update_t *update;  
  26. snd_config_t *top;  
  27. assert(_top && _update);  
  28. top = *_top;  
  29. update = *_update;  
  30. configs = cfgs;  
  31. if (!configs) {  
  32. configs = getenv(ALSA_CONFIG_PATH_VAR);  
  33. if (!configs || !*configs)  
  34. configs = ALSA_CONFIG_PATH_DEFAULT;  
  35. }  
  36. //...............   
  37. }  
  1. /**  
  2.  * /brief Updates a configuration tree by rereading the configuration files (if needed). 
  3.  * /param _top Address of the handle to the top level node. 
  4.  * /param _update Address of a pointer to private update information. 
  5.  * /param cfgs A list of configuration file names, delimited with ':'. 
  6.  *             If /p cfgs is set to /c NULL, the default global configuration 
  7.  *             file is used ("/usr/share/alsa/alsa.conf"). 
  8.  * /return A non-negative value if successful, otherwise a negative error code. 
  9.  * /retval 0 No action is needed. 
  10.  * /retval 1 The configuration tree has been rebuilt. 
  11.  * 
  12.  * The global configuration files are specified in the environment variable 
  13.  * /c ALSA_CONFIG_PATH. 
  14.  * 
  15.  * /warning If the configuration tree is reread, all string pointers and 
  16.  * configuration node handles previously obtained from this tree become invalid. 
  17.  */  
  18. int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, const char *cfgs)  
  19. {  
  20. int err;  
  21. const char *configs, *c;  
  22. unsigned int k;  
  23. size_t l;  
  24. snd_config_update_t *local;  
  25. snd_config_update_t *update;  
  26. snd_config_t *top;  
  27. assert(_top && _update);  
  28. top = *_top;  
  29. update = *_update;  
  30. configs = cfgs;  
  31. if (!configs) {  
  32. configs = getenv(ALSA_CONFIG_PATH_VAR);  
  33. if (!configs || !*configs)  
  34. configs = ALSA_CONFIG_PATH_DEFAULT;  
  35. }  
  36. //...............   
  37. }  
  1. /**  
  2.  * /brief Updates a configuration tree by rereading the configuration files (if needed). 
  3.  * /param _top Address of the handle to the top level node. 
  4.  * /param _update Address of a pointer to private update information. 
  5.  * /param cfgs A list of configuration file names, delimited with ':'. 
  6.  *             If /p cfgs is set to /c NULL, the default global configuration 
  7.  *             file is used ("/usr/share/alsa/alsa.conf"). 
  8.  * /return A non-negative value if successful, otherwise a negative error code. 
  9.  * /retval 0 No action is needed. 
  10.  * /retval 1 The configuration tree has been rebuilt. 
  11.  * 
  12.  * The global configuration files are specified in the environment variable 
  13.  * /c ALSA_CONFIG_PATH. 
  14.  * 
  15.  * /warning If the configuration tree is reread, all string pointers and 
  16.  * configuration node handles previously obtained from this tree become invalid. 
  17.  */  
  18. int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, const char *cfgs)  
  19. {  
  20. int err;  
  21. const char *configs, *c;  
  22. unsigned int k;  
  23. size_t l;  
  24. snd_config_update_t *local;  
  25. snd_config_update_t *update;  
  26. snd_config_t *top;  
  27. assert(_top && _update);  
  28. top = *_top;  
  29. update = *_update;  
  30. configs = cfgs;  
  31. if (!configs) {  
  32. configs = getenv(ALSA_CONFIG_PATH_VAR);  
  33. if (!configs || !*configs)  
  34. configs = ALSA_CONFIG_PATH_DEFAULT;  
  35. }  
  36. //...............   
  37. }  
 

參數一和二:snd_config, snd_config_global_update 都是全局變量,定義在conf.c中。

第三個參數cfgs,是包含配置文件名的字符串,snd_config_update調用它時沒有傳遞該參數,所以爲空。

 

snd_config_udpate_r首先分析第三個參數cfgs,如果爲空,就獲取系統環境變量ALSA_CONFIG_PATH_VAR值,如果還是爲空,就取ALSA_CONFIG_PATH_DEFAULT.

  1. /** The name of the default files used by #snd_config_update. */  
  2. #define ALSA_CONFIG_PATH_DEFAULT ALSA_CONFIG_DIR "/alsa.conf"   
  3. #define ALSA_CONFIG_DIR "/usr/share/alsa"  
  1. /** The name of the default files used by #snd_config_update. */  
  2. #define ALSA_CONFIG_PATH_DEFAULT ALSA_CONFIG_DIR "/alsa.conf"   
  3. #define ALSA_CONFIG_DIR "/usr/share/alsa"  
  1. /** The name of the default files used by #snd_config_update. */  
  2. #define ALSA_CONFIG_PATH_DEFAULT ALSA_CONFIG_DIR "/alsa.conf"   
  3. #define ALSA_CONFIG_DIR "/usr/share/alsa"  
 

然後提取cfgs裏的文件名。

注意cfgs可以包含多個文件名,以:或空格分開。並把每個文件的文件信息保存在snd_config_update_t變量local中,其成員count記錄了有多少個文件,finfo則是對應的文件信息鏈表。

 

接下來分析第二個參數update,如果該參數值爲空(前面提到過,最開始是爲空),就重新去讀配置文件,否則與local變量比較,如果發現不一樣(配置文件被修改過),也會跳轉到重讀配置文件的代碼。

重新讀取配置文件的代碼主要做三件事:

第一,以第一個參數snd_config_t * top爲參數調用snd_config_top(top);

第二,打開local中保存的每一個配置文件,並調用 snd_config_load(top,in),其中in是snd_input_t類型,是alsa內部定義的結構,代表輸入流; 

第三,snd_config_hooks(top,NULL);

發佈了0 篇原創文章 · 獲贊 17 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章