1. 程式人生 > >DAPM之三:audio paths與asound.conf

DAPM之三:audio paths與asound.conf

  其實asound.conf真跟dapm沒多大關係,之所以把它也納入dapm系列之一,是為了考慮到知識的連貫性。在<DAPM之二:AUDIO PATHS與dapm kcontrol>提到:通過配置好asound.conf,上層則可開啟asound.conf中定義的虛擬裝置,而自動選擇相應的音訊通道。這是asound.conf很重要的一個作用,從這方面來說,並不是跟dapm完全沒關係。

一、認識asound.conf

做alsa的基本都能體會到alsa-lib的複雜與強大,而alsa-lib的強大正是從asound.conf與.asoundrc等配置檔案體現出來。alsa驅動開發只是一個方面,而真正想隨心所欲的配置音訊裝置,asound.conf與.asoundrc的掌握是必不可少的。所幸,這方面的資料還是比較豐富,所需瞭解的知識點基本都能從官網上找到文件甚至example。

二、配置audio path

  1. This plugin is used to call some 'hook' function when this plugin is opened, modified or closed. Typically, it is used to change control values for a certain state specially for the PCM (see the example below).  
  2. # Hook arguments definition
  3. hook_args.NAME {  
  4.         ...                     # Arbitrary arguments  
  5. }  
  6. # PCM hook type
  7. pcm_hook_type.NAME {  
  8.         [lib STR]               # Library file (default libasound.so)  
  9.         [install STR]           # Install function (default _snd_pcm_hook_NAME_install)  
  10. }  
  11. # PCM hook definition
  12. pcm_hook.NAME {  
  13.         type STR                # PCM Hook type (see pcm_hook_type)  
  14.         [args STR]              # Arguments for install function (see hook_args)  
  15.         # or
  16.         [args { }]              # Arguments for install function  
  17. }  
  18. # PCM hook plugin
  19. pcm.NAME {  
  20.         type hooks              # PCM with hooks  
  21.         slave STR               # Slave name  
  22.         # or
  23.         slave {                 # Slave definition  
  24.                 pcm STR         # Slave PCM name  
  25.                 # or
  26.                 pcm { }         # Slave PCM definition  
  27.         }  
  28.         hooks {  
  29.                 ID STR          # Hook name (see pcm_hook)  
  30.                 # or
  31.                 ID { }          # Hook definition (see pcm_hook)  
  32.         }  
  33. }  
  34. Example:  
  35.         hooks.0 {  
  36.                 type ctl_elems  
  37.                 hook_args [  
  38.                         {  
  39.                                 name "Wave Surround Playback Volume"
  40.                                 preserve true
  41.                                 locktrue
  42.                                 optional true
  43.                                 value [ 0 0 ]  
  44.                         }  
  45.                         {  
  46.                                 name "EMU10K1 PCM Send Volume"
  47.                                 index { @func private_pcm_subdevice }  
  48.                                 locktrue
  49.                                 value [ 0 0 0 0 0 0 255 0 0 0 0 255 ]  
  50.                         }  
  51.                 ]  
  52.         }  
  53. Here, the controls "Wave Surround Playback Volume" and "EMU10K1 PCM Send Volume" are set to the given values when this pcm is accessed. Since these controls take multi-dimensional values, the value field is written as an array. When preserve istrue, the old values are saved and restored when the pcm is closed. The lock means that the control is locked during this pcm is opened, and cannot be changed by others. When optional isset, no error is returned but ignored even if the specified control doesn't exist.  

我們可以定義一個名為NAME的hook plugin,在這個plugin中,我們可以操作之前提到的dapm kcontrol,達到音訊通道切換的目的。另外注意:

When preserve is true, the old values are saved and restored when the pcm is closed.  當preserve設定為true時,則該pcm關閉時,kcontrol會恢復到之前的值.
The lock means that the control is locked during this pcm is opened, and cannot be changed by others.  當lock設定為true時,則在該pcm開啟期間,kcontrol的值不會被其他的pcm改變.
When optional is set, no error is returned but ignored even if the specified control doesn't exist. 當optional設定為true時,則指定的kcontrol不存在時不會返回錯誤.

  1. pcm.AndroidPlayback_Speaker_normal {  
  2.     type hooks   
  3.     slave.pcm {   
  4.         type hw   
  5.         card 0   
  6.         device 0   
  7.     }   
  8.     hooks.0 {   
  9.         type ctl_elems   
  10.         hook_args [  
  11.             {   
  12.                 name 'Left Input PGA Switch'
  13.                 value true
  14.             }  
  15.             {   
  16.                 name 'Left Input PGA LINPUT1 Switch'
  17.                 preserve true
  18.                 locktrue
  19.                 value true
  20.             }  
  21.             {   
  22.                 name 'Left Input Mixer Input PGA Switch'
  23.                 preserve true
  24.                 locktrue
  25.                 value true
  26.             }  
  27.             {   
  28.                 name 'Left Output Mixer Left Input Mixer Switch'
  29.                 preserve true
  30.                 locktrue
  31.                 value true
  32.             }  
  33.             {   
  34.                 name 'LINEOUT1 Switch'
  35.                 value true
  36.             }  
  37.         ]   
  38.     }  
  39. }  

把這個asound.conf放到/etc目錄下,再啟動Android可以做這個測試,應該可以聽到Linein輸入的錄音訊號直接在SPK上輸出。

Android的三種模式:normal、ringtone和incall,這些模式的音訊通道切換也是可以通過這樣配置asound.conf實現的。