LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1873|回复: 6

创新笔记本外置pcmcia声卡的自动切换

[复制链接]
发表于 2009-3-16 18:26:58 | 显示全部楼层 |阅读模式
前几日淘了块创新的Audigy2 ZS Notebook声卡,声卡的驱动还算不错,只要内核中开启pcmcia声卡支持为加上emu10k1的模块就好了。但之后设置的问题也来了,目标非常简单,希望声卡插进、拔出的时候,alsa的设置能相应自动变化。

我们可以利用udev来帮我们实现这个目标。

我们需要两个脚本和两个内容略为不同的asound.conf。

先看看两个声卡是啥名字:
  1. ls -l /proc/asound/
复制代码
我的机子上是:
  1. lrwxrwxrwx 1 root root 5 2009-03-16 17:27 Audigy2 -> card2
  2. dr-xr-xr-x 9 root root 0 2009-03-16 17:27 card0
  3. dr-xr-xr-x 5 root root 0 2009-03-16 17:27 card1
  4. dr-xr-xr-x 8 root root 0 2009-03-16 17:27 card2
  5. -r--r--r-- 1 root root 0 2009-03-16 17:27 cards
  6. -r--r--r-- 1 root root 0 2009-03-16 17:27 devices
  7. -r--r--r-- 1 root root 0 2009-03-16 17:27 hwdep
  8. lrwxrwxrwx 1 root root 5 2009-03-16 17:27 I82801DBICH4 -> card0
  9. lrwxrwxrwx 1 root root 5 2009-03-16 17:27 Modem -> card1
  10. dr-xr-xr-x 2 root root 0 2009-03-16 17:27 oss
  11. -r--r--r-- 1 root root 0 2009-03-16 17:27 pcm
  12. dr-xr-xr-x 2 root root 0 2009-03-16 17:27 seq
  13. -r--r--r-- 1 root root 0 2009-03-16 17:27 timers
  14. -r--r--r-- 1 root root 0 2009-03-16 17:27 version
复制代码
其中板载声卡是 I82801DBICH4,外置的pcmcia声卡是Audigy2。要把名字记下,待会我们需要它们。

接下来要写两个asound.conf来指定外置声卡插拔情况下的alsa设置。先
  1. mkdir /etc/alsa
  2. cp /etc/asound.conf   /etc/alsa/asound.ac97
  3. mv /etc/asound.conf  /etc/alsa/asound.audigy2
复制代码
,asound.ac97是没有插外置声卡时用的,asound.audigy2就是外置声卡插上时用的。
然后在asound.ac97中加入:
  1. # onboard
  2. pcm.ac97 {
  3.     type plug
  4.     slave.pcm "dmix"
  5. }
  6. ctl.ac97 {
  7.     type hw
  8.     card I82801DBICH4
  9. }
  10. pcm.!default pcm.ac97
  11. ctl.!default ctl.ac97
复制代码
在asound.audigy2中加入
  1. # pcmcia
  2. pcm.audigy2hw {
  3.     type hw
  4.     card Audigy2
  5. }
  6. pcm.audigy2 {
  7.     type plug
  8.     slave.pcm "audigy2hw"
  9. }
  10. ctl.audigy2 {
  11.     type hw
  12.     card Audigy2
  13. }
  14. # onboard
  15. pcm.ac97 {
  16.     type plug
  17.     slave.pcm "dmix"
  18. }
  19. ctl.ac97 {
  20.     type hw
  21.     card I82801DBICH4
  22. }
  23. pcm.!default pcm.audigy2
  24. ctl.!default ctl.audigy2
复制代码

要注意的是,xxx.ac97中声卡名是我板载声卡的名字,xxx.audigy2则是我外置声卡的名字,你需要替换成你自己的声卡。
这样在不同情况下,我们只要 ln -sf /etc/alsa/asound.xxx /etc/asound.conf就OK了。
接下来我们需要一个脚本在适当的时候改变上面的链接,脚本是从ALSA Wiki上处理usb外接声卡转换的脚本改写而来的,脚本switch_default_sound:
  1. #!/bin/bash
  2. # Name: switch_default_sound
  3. # Last modified: 2009.03.16
  4. # use to switch the asound.conf file
  5. #
  6. # because we hope to restore the sound card levels as well, but udev
  7. # will hang when waiting for this script to finish,
  8. # so we call restore_alsa_sound as daemon, which wait and try to restore
  9. # sound level after udev finish, and alsa make the card ready.
  10. usage(){
  11.     echo usage: `basename $0` [`ls /etc/alsa/ -1 | sed -e 's:/etc/alsa/::g' -e 's/asound.//g'`]
  12. }
  13. if [ -n $1 ] && [ -e /etc/alsa/asound."$1" ];
  14. then
  15.     ln -sf /etc/alsa/asound."$1" /etc/asound.conf
  16.     # we need to call restore_alsa_sound as daemon, so that, we can
  17.     # return to udev, and leave rest to restore_alsa_sound
  18.         restore_alsa_sound "$1" &
  19. else
  20.     usage
  21. fi
复制代码
这个脚本除了完成asound.conf的链接工作外,还将调用restore_alsa_sound完成音量重置的工作(我还用它重启mpd)。因为udev在调用switch_default_sound的时候是停在那里等它返回的,而在udev完成设备添加前alsa是得不到声卡信息的,音量恢复就无法完成,而我们在switch_default_sound中用while来等,这样udev就死等在那里了。为了避免这样的问题,我们需要用daemon的形式调用restore_alsa_sound,把剩下的工作交给它。
  1. #!/usr/bin/env python
  2. # Name: restore_alsa_sound
  3. # Last Modified: 2009.03.16
  4. # use to retore the alsa sound level
  5. from sys import argv
  6. from os import system as os_system
  7. from time import sleep
  8. if argv[1] == "audigy2":
  9.     retry = 0
  10.     while ( retry <= 10):
  11.         if os_system ("alsactl restore Audigy2") == 0:
  12.             break
  13.         sleep(0.5)
  14. os_system ("/etc/init.d/mpd restart")
复制代码

注意, alsactl restore
Audigy2中的Audigy2是我外置声卡的名字,你得换成你自己的。另外,如果你没有用mpd的话,就把最后一行去掉。

接着,把switch_default_sound和restore_alsa_sound放到 /usr/local/sbin下,并chmod 755 它。

最后,我们需要让udev在插入和拔出声卡的时候调用switch_default_sound,就大功告成了。所以,我们要写一个udev的rule为我们服务。

先用lspci找到声卡的PCI_ID
  1. lspci  -nn
复制代码
比如我的是
  1. 02:00.0 Multimedia audio controller [0401]: Creative Labs SB0400 Audigy2 Value [1102:0008]
复制代码
,其中1102:0008就是了。
接着,我们需要找出相应的udev信息。先把udev的信息导到文件udev.txt中
  1. udevadm info --export-db > udev.txt
复制代码
然后找出1102:0008
  1. grep -C10 1102:0008 udev.txt
复制代码
在我的电脑上结果是:
  1. E: PCI_SLOT_NAME=0000:01:0a.0
  2. E: MODALIAS=pci:v00001180d00000476sv000010CFsd00001254bc06sc07i00
  3. P: /devices/pci0000:00/0000:00:1e.0/0000:01:0a.0/0000:02:00.0
  4. E: UDEV_LOG=3
  5. E: DEVPATH=/devices/pci0000:00/0000:00:1e.0/0000:01:0a.0/0000:02:00.0
  6. E: DRIVER=EMU10K1_Audigy
  7. E: PHYSDEVBUS=pci
  8. E: PHYSDEVDRIVER=EMU10K1_Audigy
  9. E: PCI_CLASS=40100
  10. E: PCI_ID=1102:0008
  11. E: PCI_SUBSYS_ID=1102:2001
  12. E: PCI_SLOT_NAME=0000:02:00.0
  13. E: MODALIAS=pci:v00001102d00000008sv00001102sd00002001bc04sc01i00
  14. P: /devices/pci0000:00/0000:00:1e.0/0000:01:0a.1
  15. E: UDEV_LOG=3
  16. E: DEVPATH=/devices/pci0000:00/0000:00:1e.0/0000:01:0a.1
  17. E: DRIVER=yenta_cardbus
  18. E: PHYSDEVBUS=pci
  19. E: PHYSDEVDRIVER=yenta_cardbus
复制代码
从中可以看到声卡的PCI_SUBSYS_ID是1102:2001。现在我们就有了足够的信息来写udev的rules了。

在/etc/udev/rules.d下建立一个文件75-alsa_conf.rules
  1. # udev rules file for my Audigy2 ZS Notebook devices (for udev 0.98 version)
  2. # call /usr/local/sbin/switch_default_sound to change the link
  3. # of /etc/asound.conf
  4. #
  5. #
  6. ENV{PCI_ID}=="1102:0008", ENV{PCI_SUBSYS_ID}=="1102:2001",ACTION=="add", RUN+="/usr/local/sbin/switch_default_sound audigy2"
  7. ENV{PCI_ID}=="1102:0008", ENV{PCI_SUBSYS_ID}=="1102:2001",ACTION=="remove", RUN+="/usr/local/sbin/switch_default_sound ac97"
复制代码

在这个rules中,我们要求udev在PCI_ID为1102:0008且PCI_SUBSYS_ID为1102:2001的设备(就是处置的那块声卡)要被插入时,即ACTION为add时,调用"/usr/local/sbin/switch_default_sound audigy2",在声卡被移除时,即ACTION为remove时调用"/usr/local/sbin/switch_default_sound ac97"。

但为了能有效地restore声音,你需要在第一次插入声卡并设置好音量后手动运行一下alsactl store Audigy2。
另外,插拔声卡的时候要确认你没有在放音乐哦
发表于 2009-3-18 14:06:30 | 显示全部楼层
好贴!支持!
前段时间我也买了块 Audigy2 ZS Notebook , 哈哈
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-18 20:33:34 | 显示全部楼层
谢谢支持
创新的声卡果然是不错,在高中的时候就十分垂涎创新的声卡,结果到了现在才买了第一块创新的声卡
回复 支持 反对

使用道具 举报

发表于 2009-3-19 15:43:59 | 显示全部楼层
唔~~
刚好可以从这里学点udev的东东!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-20 01:39:18 | 显示全部楼层
udev我是现用现学
回复 支持 反对

使用道具 举报

发表于 2009-3-20 09:28:12 | 显示全部楼层
acevery 又一精华贴,支持
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-20 09:35:59 | 显示全部楼层
Post by axlrose;1963425
acevery 又一精华贴,支持


谢谢!
经验和大家一起分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表