【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
}
发布了9 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/sssuperqiqi/article/details/97033472
今日推荐