asoundrc文件

来源:互联网 发布:国家数据共享交换平台 编辑:程序博客网 时间:2024/05/01 17:49

什么是asoundrc文件?

这里asoundrc文件实际上包含两个文件:“.asoundrc”和“asound.conf”。

”.asoundrc“是一个隐藏文件,是针对个人用户的配置文件,存在于主目录下。asound.conf则是全局的配置文件。


为什么需要asoundrc文件?

事实上,asoundrc文件对ALSA来说,不是必须的配置文件,也就是说,无论它存不存在,都是不影响ALSA的工作的。那么既然这样,它存在的意义是什么呢?使用asoundrc文件可以实现更多对card/device的高级控制。例如在alsa-lib层进行路由和采样率转换,把多块卡合为一块,或者访问多通道卡的多个I/O。


asoundrc文件什么时候被加载的?

asoundrc文件是由/usr/share/alsa/alsa.conf(alsa-lib的)文件加载的:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @hooks [  
  2.         {  
  3.                 func load  
  4.                 files [  
  5.                         "/etc/asound.conf"  
  6.                         "~/.asoundrc"  
  7.                 ]  
  8.                 errors false  
  9.         }  
  10. ]  


默认的plugin

关键子default在alsa-lib中被定义为“hw:0,0”,在asoundrc文件中,使用!default可以替换默认的default,实例如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.!default {  
  2.     type hw  
  3.     card 0  
  4. }  
  5.   
  6. ctl.!default {  
  7.     type hw             
  8.     card 0  
  9. }  


PCM设备的命名

典型的asoundrc文件是从“PCM hw type”开始的,这样就使得应用程序可以使用给定的名字启动一个虚拟声卡(plugin或者slave)。否则,只能使用类似“hw:0,0”或者default来访问设备:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -D hw:0,0 test.wav  

hw:后面的号码分别表示声卡号的设备号,这些号码和/proc/asound/cards中列出的序数是一致的,注意,第一项是从0开始的,0,0就表示第一个声卡上面的第一个设备。但是这样的表示方式,很容易导致混乱,没有使用类似”usb soundcard“之类的字符串让人容易理解。


控制设备

控制设备可以用来控制声卡的各种controls。大部分声卡都包括mixer和mux,即使对一些没有mixer和mux的声卡,也会有一些controls或者使用像JACK的程序控制它们。比如:digital I/O sync indicators, sample clock source switch等。


别名

使用“PCM hw type”可以给设备定义别名,具体语法如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.NAME {  
  2.     type hw               # Kernel PCM  
  3.     card INT/STR          # Card name or number  
  4.     [device] INT          # Device number (default 0)       
  5.     [subdevice] INT       # Subdevice number, -1 first available (default -1)  
  6.     mmap_emulation BOOL   # enable mmap emulation for ro/wo devices  
  7. }  

例如给第一个声卡定义别名的方式如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.primary {  
  2.     type hw  
  3.     card 0  
  4.     device 0  
  5. }  

这样就可以通过primary访问第一个声卡设备:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -D primary test.wav  

插件

Q:什么是插件?

A:在ALSA中,PCM插件用于扩展PCM设备的功能和特性。插件可以自动执行一些类似命名设备,采样率转换,通道间的采样拷贝,写入文件,联合多个设备做multiple inputs/outputs,使用多声道声卡等工作。再使用插件之前,需要首先创建一个虚拟的slave设备。

一个简单的实例如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm_slave.sltest {  
  2.     pcm "hw:1,0"  
  3. }  

上面的实例定义个一个没有任何参数的slave,实际上也就仅仅是给声卡设备定义了一别名而已。对于需要参数的情况,需要注意一点“PCM types”的参数必须定义在slave-definition-block,例如下面个两种方式定义是一致的:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <span style="color:#FF0000;">pcm_slave.sl2 {  
  2.     pcm "hw:1,0"  
  3.     rate 48000  
  4. }</span>  
  5.   
  6. pcm.rate_convert {  
  7.     type rate  
  8.     slave sl2  
  9. }  
或者

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.rate_convert {  
  2.     type rate  
  3.     <span style="color:#FF0000;">slave {  
  4.         pcm "hw:1,0"  
  5.         rate 48000  
  6.     }</span>  
  7. }  
注意,这两种方式中参数定义的位置。

上述步骤完成后,就可以使用下面的方式使用定义的虚拟设备:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -D rate_convert test.wav  
进行采样率转换可以使用更复杂的plug。语法如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. type plug               # Format adjusted PCM  
  2. slave STR               # Slave name (see pcm_slave)  
  3. # or  
  4. slave {                 # Slave definition  
  5.     pcm STR         # Slave PCM name  
  6.     # or  
  7.     pcm { }         # Slave PCM definition  
  8.     [format STR]    # Slave format (default nearest) or "unchanged"  
  9.     [channels INT]  # Slave channels (default nearest) or "unchanged"  
  10.     [rate INT]      # Slave rate (default nearest) or "unchanged"  
  11. }  
  12. route_policy STR    # route policy for automatic ttable generation  
  13.                         # STR can be 'default', 'average', 'copy', 'duplicate'  
  14.                        # average: result is average of input channels  
  15.                         # copy: only first channels are copied to destination  
  16.                         # duplicate: duplicate first set of channels  
  17.                        # default: copy policy, except for mono capture - sum  
  18. ttable {               # Transfer table (bidimensional compound of   
  19.                        # cchannels * schannels numbers)  
  20.     CCHANNEL {  
  21.         SCHANNEL REAL     # route value (0.0 ... 1.0)  
  22.     }  
  23. }  
具体实例如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm_slave.sl3 {  
  2.     pcm "hw:1,0"  
  3.     format S16_LE  
  4.     channels 1  
  5.     rate 16000  
  6. }  
  7.   
  8. pcm.complex_convert {  
  9.     type plug  
  10.     slave sl3  
  11. }  
定义完成后就可以使用了:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -vD complex_convert test.wav  

当播放test.wav的时候,就会转换为S16_LE,一个通道和16kHz的采样率进行播放。如果只是使用-v选项,你就能看到测试文件的原始设置

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -v test.wav  

软件混音

软件混音是指在同一个设备上面同时播放多个音频文件。在linux环境下,有很多方法可以实现软件混音。通常它需要一个server程序,例如ARTSD,ESD,JACK等等。这么多的server软件,很容易让人搞混淆。

dmix

现在ALSA有一个叫做dmix的本地插件,通过使用指定的语法,它可以让实现软件混音变的非常简单,而用户也不用再额外安装其他的软件。

dmix插件默认是和default插件时绑定在一起的,也就是说,使用本地ALSA支持的设备,都会共享这个设备,但是实际上很多设备并没有使用这一个功能。它是在/usr/share/alsa/alsa.conf文件中定义的:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.!default {  
  2.     type plug  
  3.     slave.pcm "dmixer"  
  4. }  
  5.   
  6. pcm.dmixer  {  
  7.     type dmix  
  8.     ipc_key 1024  
  9.     slave {  
  10.         pcm "hw:1,0"  
  11.         period_time 0  
  12.         period_size 1024  
  13.         buffer_size 4096  
  14.         rate 44100  
  15.     }  
  16.     bindings {  
  17.         0 0  
  18.         1 1  
  19.     }  
  20. }  
  21.   
  22. ctl.dmixer {  
  23.     type hw  
  24.     card 0  
  25. }  

如果用户想自己给dmix插件定义名字,直接改变!default就可以了。

可以在多个终端上面同时使用下面的指令测试:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -f cd -D default test.wav  
注意:

默认的采样率是48000Hz,可以使用下面的方法改变它:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -D"plug:'dmix:RATE=44100'" test.wav  
另一个实例(采样率44100Hz,hw:1,0作为输出设备)

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. An example command for dmix plugin to use 44100Hz sample-rate and hw:1,0 output device:   
默认的定义:

SLAVE="hw:0,0",RATE=48000
dmix不是基于C/S模型的,它是直接把数据写到声卡的的DMA缓冲区,它对同时可以运行的实例数目也是没有限制的。

dsnoop

dmix是用户混音多个输出音频流的,如果需要混合多个输入音频流,则可以使用dsnoop插件。

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.mixin {  
  2.     type dsnoop  
  3.     ipc_key 5978293 # must be unique for all dmix plugins!!!!  
  4.     ipc_key_add_uid yes  
  5.     slave {  
  6.         pcm "hw:0,0"  
  7.         channels 2  
  8.         period_size 1024  
  9.         buffer_size 4096  
  10.         rate 44100  
  11.         periods 0   
  12.         period_time 0  
  13.     }  
  14.     bindings {  
  15.         0 0  
  16.         0 1  
  17.     }  
  18. }  

JACK plugin

This plugin allows the user to connect applications that support alsa natively to the JACK daemon.

为了编译和安装jack,首先需要进入src/pcm/ext目录,然后执行“make jack”和“make install-jack”指令。

另外需要在.asoundrc文件中添加下面的内容:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pcm.jackplug {  
  2.     type plug  
  3.     slave { pcm "jack" }  
  4. }  
  5.   
  6. pcm.jack {  
  7.     type jack  
  8.     playback_ports {  
  9.         0 alsa_pcm:playback_1  
  10.         1 alsa_pcm:playback_2  
  11.     }  
  12.     capture_ports {  
  13.         0 alsa_pcm:capture_1  
  14.         1 alsa_pcm:capture_2  
  15.     }  
  16. }  
使用实例如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. aplay -Djackplug somefile  
  2. arecord -Djackplug somefile  
虚拟的多通道设备

用户可以使用两个或者更多ALSA设备,模拟一个多通道的虚拟设备。

将下面的内容拷贝到asoundrc文件中:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. # create a virtual four-channel device with two sound devices:  
  2. # This is in fact two interleaved stereo streams in  
  3. # different memory locations, so JACK will complain that it  
  4. # cannot get mmap-based access. see below.  
  5.   
  6. pcm.multi {  
  7.         type multi;  
  8.         slaves.a.pcm "hw:0,0";  
  9.         slaves.a.channels 2;  
  10.         slaves.b.pcm "hw:1,0";  
  11.         slaves.b.channels 2;  
  12.         bindings.0.slave a;  
  13.         bindings.0.channel 0;  
  14.         bindings.1.slave a;  
  15.         bindings.1.channel 1;  
  16.         bindings.2.slave b;  
  17.         bindings.2.channel 0;  
  18.         bindings.3.slave b;  
  19.         bindings.3.channel 1;  
  20. }  
  21.   
  22. # JACK will be unhappy if there is no mixer to talk to, so we set  
  23. # this to card 0. This could be any device but 0 is easy.   
  24.   
  25. ctl.multi {  
  26.         type hw;  
  27.         card 0;  
  28. }  
  29.   
  30. # This creates a 4 channel interleaved pcm stream based on  
  31. # the multi device. JACK will work with this one.  
  32.   
  33. pcm.ttable {  
  34.         type route;  
  35.         slave.pcm "multi";  
  36.         slave.channels 4;  
  37.         ttable.0.0 1;  
  38.         ttable.1.1 1;  
  39.         ttable.2.2 1;  
  40.         ttable.3.3 1;  
  41. }  
  42. # see above.  
  43. ctl.ttable {  
  44.         type hw;  
  45.         card 0;  
  46. }  
可以使用下面的命令测试上面配置的效果

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. arecord -f S16_LE -r 44100 -c 4 -D multi | aplay -f S16_LE -r 44100 -c 4 -D multi  
如果用jack测试,则可以使用下面的命令:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. jackd [-a] -R [-v] -d alsa -d ttable [-p 1024]  

Bindings

上面创建虚拟多通道设备时,使用了Bindings。下面的一个实例说明了怎么使用Bindings:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. # This is for two RME Hammerfall cards. They have been conceptually split into rows  
  2. # and will be mapped to ALSA channels 0-27: with channels 0-7 and 16-23 on rme9652_0 and channels 8-15 on  
  3. # rme9652_1, and finally channels 24-25 of both cards, used as two stereo channels, mapped to ALSA channels 24-27 (while the others are mono).  
  4.   
  5. # eg. ALSA channels on card1 = rme9652_0                            
  6. #     | 0  1  2  3  4  5  6  7       |    
  7. #     | 8  9  10 11 12 13 14 15      |  
  8. #     |                         24 25|  
  9. #  
  10. #     ALSA channels on card2 = rme9652_1  
  11. #     | 16 17 18 19 20 21 22 23      |  
  12. #     |                         26 27|  
  13.   
  14.   
  15.   
  16. pcm_slave.rme9652_s {  
  17.     pcm rme9652_0  
  18. }  
  19. pcm.rme9652_1 {  
  20.     type hw  
  21.     card 1  
  22. }  
  23. ctl.rme9652_1 {  
  24.     type hw  
  25.     card 1  
  26. }  
  27. pcm.rme9652_0 {  
  28.     type hw  
  29.     card 0  
  30. }  
  31. ctl.rme9652_0 {  
  32.     type hw  
  33.     card 0  
  34. }  
  35. ctl.rme9652_48 {  
  36.     type hw  
  37.     card 0  
  38. }  
  39. pcm.rme9652_48 {  
  40.     type multi;  
  41.     slaves.a.pcm rme9652_0;  
  42.     slaves.a.channels 26;  
  43.     slaves.b.pcm rme9652_1;  
  44.     slaves.b.channels 26;  
  45.   
  46.     # Use rme9652_0 ch 0-7 mapped to ALSA ch 0-7  
  47.   
  48.     bindings.0.slave a;  
  49.     bindings.0.channel 0;  
  50.     bindings.1.slave a;  
  51.     bindings.1.channel 1;  
  52.     bindings.2.slave a;  
  53.     bindings.2.channel 2;  
  54.     bindings.3.slave a;  
  55.     bindings.3.channel 3;  
  56.     bindings.4.slave a;  
  57.     bindings.4.channel 4;  
  58.     bindings.5.slave a;  
  59.     bindings.5.channel 5;  
  60.     bindings.6.slave a;  
  61.     bindings.6.channel 6;  
  62.     bindings.7.slave a;  
  63.     bindings.7.channel 7;  
  64.   
  65.     # Use rme9652_0 ch 16-23 mapped to ALSA ch 8-15  
  66.   
  67.     bindings.8.slave a;  
  68.     bindings.8.channel 16;  
  69.     bindings.9.slave a;  
  70.     bindings.9.channel 17;  
  71.     bindings.10.slave a;  
  72.     bindings.10.channel 18;  
  73.     bindings.11.slave a;  
  74.     bindings.11.channel 19;  
  75.     bindings.12.slave a;  
  76.     bindings.12.channel 20;  
  77.     bindings.13.slave a;  
  78.     bindings.13.channel 21;  
  79.     bindings.14.slave a;  
  80.     bindings.14.channel 22;  
  81.     bindings.15.slave a;  
  82.     bindings.15.channel 23;  
  83.   
  84.     # Use rme9652_1 ch 8-15 mapped to ALSA ch 16-23  
  85.   
  86.     bindings.16.slave b;  
  87.     bindings.16.channel 8;  
  88.     bindings.17.slave b;  
  89.     bindings.17.channel 9;  
  90.     bindings.18.slave b;  
  91.     bindings.18.channel 10;  
  92.     bindings.19.slave b;  
  93.     bindings.19.channel 11;  
  94.     bindings.20.slave b;  
  95.     bindings.20.channel 12;  
  96.     bindings.21.slave b;  
  97.     bindings.21.channel 13;  
  98.     bindings.22.slave b;  
  99.     bindings.22.channel 14;  
  100.     bindings.23.slave b;  
  101.     bindings.23.channel 15;  
  102.   
  103.     # stereo channels: slave a+b ch 24-25 mapped to ALSA ch 24-27  
  104.   
  105.     bindings.24.slave a;  
  106.     bindings.24.channel 24;  
  107.     bindings.25.slave a;  
  108.     bindings.25.channel 25;  
  109.     bindings.26.slave b;  
  110.     bindings.26.channel 24;  
  111.     bindings.27.slave b;  
  112.     bindings.27.channel 25;  
  113. }  
上面的例子中,第一个声卡使用了18个物理信道,第二个声卡使用了10个物理信道(18 (a) + 10 (b))。在/proc/asound/cardX目录下面会存在类似于pcmYc (capture)和pcmYp (playback)的目录,其中Y就就对于声卡X所具有的物理信道数。

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. type multi;  
  2. slaves.a.pcm rme9652_0;  
  3. slaves.a.channels 26;  
上面部分的意思是,给rme9652_0取个别名a,并且指定可以使用的信道数目位26.这个可以使用的信道数目最多不能超过物理设备具有的最大的信道数目。bindings是从第一个可以使用的设备开始的,例如pcm0c pcm0p,然后逐个递增。

The first card for this file has 18 physical pcm devices. Nine of them are capture devices ie. pcm0c pcm1c pcm2c... pcm8c, each with corresponding playback channels ie. pcm0p pcm1p pcm2p ... pcm8p. The second card has 10 physical pcm devices ie. pcm0c pcm1c pcm2c ... pcm9c.

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. bindings.0.slave a;  
  2. bindings.0.channel 0;  
  3. bindings.1.slave a;  
  4. bindings.1.channel 1;  

The first binding points to the first available pcm device on the card represented as "a". The second binding points to the second available pcm device on "a" and so on up to the last one available. We then assign a channel number to the binding so that the channels on the new virtual "soundcard" we have created are easy for us to access.

Another way of saying it is:

address of.the first channel on my new soundcard.using my real soundcard called "a";make this address of.the first channel on my new soundcard.be the first pcm device on my new soundcard;
address of.the second channel on my new soundcard.using my real soundcard called "a";make this address of.the second channel on my real soundcard.be the second pcm device on my new soundcard;

Referenced applications

  • aRTsd - the aRTs sound server was the basis of desktop sound for KDE 3.
  • ESD - the Enlightened Sound Daemon mixes several audio streams for playback by a single audio device.
  • Ecasound - a commandline multitrack recorder and editor with various GUI apps.
  • JACK - Jack Audio Connection Kit. If you don't know this app you don't know JACK.
http://www.alsa-project.org/main/index.php/Asoundrc
0 0