【ALSA】 asound.conf 插件講解

Alsa-lib層,爲不同的驅動提供統一的接口alsa API,簡化了開發人員對於驅動層的調用開發。接口定義地址:

https://www.alsa-project.org/alsa-doc/alsa-lib/

關於asound.conf的配置,可以參考官網解釋:

https://www.alsa-project.org/main/index.php/Asoundrc

詳細的插件講解,官網網址:

https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html

 

1.  什麼是asound.conf
asound.conf配置文件,是alsa-lib的默認配置文件,路徑在 /etc/,可以用來配置alsa庫的一些附加功能。這個文件不是alsa庫運行時所必須的,沒有它alsa庫也可以正常運行。asound.conf允許對聲卡或者設備進行更高級的控制,提供訪問alsa-lib中的pcm插件方法,允許你做更多的複雜的控制,比如可以把聲卡組合成一個或者多聲卡訪問多個I/O。

ps:在usr/local/shar/alsa/中有一個文件叫---alsa.conf,asound.conf 這個文件在調用snd_pcm_open這個api函數時,會被加載同時解析。

 

2. 什麼是插件(plugins)?
在ALSA中,PCM插件擴展了PCM設備的功能和特性。插件可以自動處理諸如:命名設備、採樣率轉換、通道間的採樣複製、寫入文件、爲多個輸入/輸出連接聲卡/設備(不同步採樣)、使用多通道聲卡/設備等工作。

 

3.   Plugin: hw
此插件直接與ALSA內核驅動程序通信,它是一種沒有任何轉換的原始通信。

pcm.name {
    type hw         # Kernel PCM
    card INT/STR        # Card name (string) or number (integer)
    [device INT]        # Device number (default 0)
    [subdevice INT]     # Subdevice number (default -1: first available)
    [sync_ptr_ioctl BOOL]   # Use SYNC_PTR ioctl rather than the direct mmap access for control structures
    [nonblock BOOL]     # Force non-blocking open mode
    [format STR]        # Restrict only to the given format
    [channels INT]      # Restrict only to the given channels
    [rate INT]      # Restrict only to the given rate
    [chmap MAP]     # Override channel maps; MAP is a string array
}


nonblock選項指定設備是否以非阻塞方式打開。注意此選項並不會更改讀/寫訪問的阻塞行爲。隻影響打開設備時的阻塞行爲。如果想保持與舊ALSA版本的兼容性,請關閉此選項。

下面是一個例子:

pcm.!default {
        type hw
        card 0
}
 
ctl.!default {
        type hw           
        card 0
}


名字爲default的聲卡,指向card0,也就是hw:0,0,測試命令:aplay -D default test.wav

hw後面跟的數字是聲卡號和設備號,可以用如下命令查看硬件支持聲卡數:  

cat /proc/asound/cards  或者  ls /dev/dns. (pcm0c (capture), pcm0p (playback))

 

4. Slave 定義
在ALSA中,PCM插件擴展了PCM設備的功能和特性。插件可以自動處理諸如:命名設備、採樣率轉換、通道間的採樣複製、寫入文件、爲多個輸入/輸出連接聲卡/設備(不同步採樣)、使用多通道聲卡/設備等工作。要使用它們,開發者需要創建一個虛擬從屬設備(slave device)。

pcm_slave.NAME {
    pcm STR     # PCM name
    # or
    pcm { }     # PCM definition
    format STR  # Format or "unchanged"
    channels INT    # Count of channels or "unchanged" string
    rate INT    # Rate in Hz or "unchanged" string
    period_time INT # Period time in us or "unchanged" string
    buffer_time INT # Buffer time in us or "unchanged" string
}


一個最簡單的slave用例:

pcm_slave.sltest {
        pcm "hw:1,0"
}


在slave設備配置中加入採樣率轉換:

pcm_slave.sl2 {
        pcm "hw:1,0"
        rate 48000
}
 
pcm.rate_convert {
        type rate
        slave sl2
}


調用這個接口,44.1k的採樣頻率的音頻將會轉換爲48khz輸出。

可以用aplay命令測試創建的虛擬設備: 

aplay -D rate_convert test.wav

上圖的slave配置的另一種方式,兩種方式等同:

pcm.rate_convert {
        type rate
        slave {
                pcm "hw:1,0"
                rate 48000
        }
}


上面的用例用到了 Plugin: Rate

 
4.Plugin: Rate
這個插件可以轉換採樣率,但是輸入輸出格式必須爲線型。

pcm.name {
    type rate               # Rate PCM
        slave STR               # Slave name
        # or
        slave {                 # Slave definition
                pcm STR         # Slave PCM name
                # or
                pcm { }         # Slave PCM definition
                rate INT        # Slave rate
                [format STR]    # Slave format
        }
    converter STR           # optional
    # or
    converter [ STR1 STR2 ... ] # optional
                # Converter type, default is taken from
                # defaults.pcm.rate_converter
    # or
    converter {     # optional
        name STR    # Convertor type
        xxx yyy     # optional convertor-specific configuration
    }
}


 
5. Plugin: Route & Volume
此插件可以轉換聲道數和應用聲音。轉換聲音這個我沒有很明白,官網也沒有給出具體的用例。

pcm.name {
        type route              # Route & Volume conversion PCM
        slave STR               # Slave name
        # or
        slave {                 # Slave definition
                pcm STR         # Slave PCM name
                # or
                pcm { }         # Slave PCM definition
                [format STR]    # Slave format
                [channels INT]  # Slave channels
        }
        ttable {                # Transfer table (bi-dimensional compound of cchannels * schannels numbers)
                CCHANNEL {
                        SCHANNEL REAL   # route value (0.0 - 1.0)
                }
        }
}


6. Automatic conversion plugin
這個插件可以轉換channels、rate和format,可以理解爲是rate和Route & Volume的集合體。

pcm.name {
        type plug               # Automatic conversion PCM
        slave STR               # Slave name
        # or
        slave {                 # Slave definition
                pcm STR         # Slave PCM name
                # or
                pcm { }         # Slave PCM definition
        [format STR]    # Slave format (default nearest) or "unchanged"
        [channels INT]  # Slave channels (default nearest) or "unchanged"
        [rate INT]  # Slave rate (default nearest) or "unchanged"
        }
    route_policy STR    # route policy for automatic ttable generation
                # STR can be 'default', 'average', 'copy', 'duplicate'
                # average: result is average of input channels
                # copy: only first channels are copied to destination
                # duplicate: duplicate first set of channels
                # default: copy policy, except for mono capture - sum
    ttable {        # Transfer table (bi-dimensional compound of cchannels * schannels numbers)
        CCHANNEL {
            SCHANNEL REAL   # route value (0.0 - 1.0)
        }
    }
    rate_converter STR  # type of rate converter
    # or
    rate_converter [ STR1 STR2 ... ]
                # type of rate converter
                # default value is taken from defaults.pcm.rate_converter
}


 看一下小例子:

pcm.nfbtout {
        type plug
        slave {
                pcm "hw:1,0"
                rate 8000
                channels 2
        }
}


 

7. Plugin: dmix
       有了一個本地的alsa插件,叫做dmix(直接混合)插件。它允許軟件混合在一個易於使用的語法中,而不需要先安裝/理解一個新的應用程序。但是需要注意的一點:The resolution for 32-bit mixing is only 24-bit. The low significant byte is filled with zeros. The extra 8 bits are used for the saturation.

注意,dmix插件不是基於客戶機/服務器架構,而是直接寫入聲卡的dma緩衝區。一次可以運行的實例數量沒有限制。

pcm.name {
    type dmix       # Direct mix
    ipc_key INT     # unique IPC key
    ipc_key_add_uid BOOL    # add current uid to unique IPC key
    ipc_perm INT        # IPC permissions (octal, default 0600)
    hw_ptr_alignment STR    # Slave application and hw pointer alignment type
                # STR can be one of the below strings :
                # no
                # roundup
                # rounddown
                # auto (default)
    slave STR
    # or
    slave {         # Slave definition
        pcm STR     # slave PCM name
        # or
        pcm { }     # slave PCM definition
        format STR  # format definition
        rate INT    # rate definition
        channels INT
        period_time INT # in usec
        # or
        period_size INT # in bytes
        buffer_time INT # in usec
        # or
        buffer_size INT # in bytes
        periods INT # when buffer_size or buffer_time is not specified
    }
    bindings {      # note: this is client independent!!!
        N INT       # maps slave channel to client channel N
    }
    slowptr BOOL        # slow but more precise pointer updates
}


ipc_key必須是整數形式的唯一ipc key。對於每個不同的dmix定義,這個數字必須是唯一的,因爲共享內存是用這個key創建的。當ipc_key_add_uid設置爲true時,uid值將添加到ipc_key設置中。這樣可以避免同一個IPC密鑰與不同用戶同時發生衝突。

hw_ptr_alignment這個配置默認是auto,其他配置可以去上面貼的第三個網址中瞭解。

注意,dmix插件本身只支持單個配置。也就是說,它只支持固定rate(默認48000)、format(s16)、channels(2)和period_time (125000)。對於使用其它配置,開發者必須在從PCM定義中明確設置該值。

一個用例:

pcm.dmix_44 {
    type dmix
    ipc_key 321456  # any unique value
    ipc_key_add_uid true
    slave {
        pcm "hw:0"
        format S32_LE
        rate 44100
    }
}


可以利用這個配置的聲卡播放一個48k 的音頻:aplay -Dplug:dmix_44 foo_48k.wav

對於使用OSS仿真設備的dmix插件,必須將period和buffer sizes設置爲2的冪次方。例如:

pcm.dmixoss {
    type dmix
    ipc_key 321456  # any unique value
    ipc_key_add_uid true
    slave {
        pcm "hw:0"
        period_time 0
        period_size 1024  # must be power of 2
        buffer_size 8192  # ditto
    }
}


period_time必須爲0,對於帶有多通道IO的聲卡,添加綁定也非常有用。(官網中的這句,我不是很明白),綁定的用例:

pcm.dmixoss {
    ...
    bindings {
        0 0   # map from 0 to 0
        1 1   # map from 1 to 1
    }
}

 

8. Plugin: dsnoop
          此插件將一個capture流拆分爲多個。它的工作方式與dmix插件相反,從多個客戶端同時讀取共享捕獲緩衝區。以下參數的含義與dmix插件幾乎相同。

pcm.name {
    type dsnoop     # Direct snoop
    ipc_key INT     # unique IPC key
    ipc_key_add_uid BOOL    # add current uid to unique IPC key
    ipc_perm INT        # IPC permissions (octal, default 0600)
    slave STR
    # or
    slave {         # Slave definition
        pcm STR     # slave PCM name
        # or
        pcm { }     # slave PCM definition
        format STR  # format definition
        rate INT    # rate definition
        channels INT
        period_time INT # in usec
        # or
        period_size INT # in bytes
        buffer_time INT # in usec
        # or
        buffer_size INT # in bytes
        periods INT # when buffer_size or buffer_time is not specified
    }
    bindings {      # note: this is client independent!!!
        N INT       # maps slave channel to client channel N
    }
    slowptr BOOL        # slow but more precise pointer updates
}


 

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