Andrew Huang 转载请注明作者和网址.
一般嵌入式系统只一个声音硬件作输出,所以大部分操作都采用默认的声卡即可操作。因此没有注意多网卡切换的问题,但是引入USB 声卡后,在嵌入式系统形成N个声卡,这样如果自动选定的缺省声卡,如何在应用程序切换声卡变成很现实的问题。
因为设计关系统OSS是无法进行多声卡的操作,只有ALSA才支持.
这个文章对于多声卡的操作描述很详细
对于ALSA多声卡操作我重点关注如下几个问题.
1.如何象LINUX的图形界面显示系统的所有声卡的列表?
2.如何选定某一个声卡为缺省输出?
3.如果在应用程序选定某一个非缺省的声卡来播放声音?
查看alsa声卡列表的功能,可以查看aplay -l 的实现.这个命令就是用来实现
一.测试环境
测试环境:mini6410 , Linux 2.6.28.6. 内核增加use auido
1.1.编译内核
增加USB Audio选项
1.2 编译 alsa-lib/alsa-utils
编译alsa库最好编译两次:
第一次把alsa的配置文件放入output目录以便发布.
./configure --host=arm-linux --prefix=$PWD/../../output/arm-linux --enable-static --enable-shared --disable-python --with-plugindir=/usr/local/lib/alsa_lib |
如果是mini6410则需要把缺省的设备结点目录/dev/snd 改成 /dev
./configure --host=arm-linux --prefix=$PWD/../../output/arm-linux --enable-static --enable-shared --disable-python --with-plugindir=/usr/local/lib/alsa_lib --with-alsa-devdir=/dev
make
make install
第二次让缺省库使用时去找/usr/local/share/alsa,
make clean
./configure --host=arm-linux --prefix=$PWD/../../output/arm-linux --enable-static --enable-shared --disable-python --with-configdir=/usr/local/share/alsa --datarootdir=$PWD/../../output/arm-linux/share
--with-alsa-devdir=/dev #红色是mini6410要加的
make
make install
这一次为解决运行时提示配置文件
ALSA lib pcm.c:2145:(snd_pcm_open_noupdate) Unknown PCM default
aplay: main:546: audio open error: No such file or directory
编译alsa-utils 进行测试
./configure --host=arm-linux --prefix=$PWD/../../output/arm-linux --enable-static --enable-shared --with-configdir=/usr/local/share --with-libiconv-prefix=$PWD/../../output/arm-linux CFLAGS="-I$PWD/../../output/arm-linux/include" LDFLAGS="-L$PWD/../../output/arm-linux/lib -lasound -liconv" --disable-alsamixer --disable-xmlto
1.3 拷贝alsa配置文件到在开发板
在开发板上创建
mkdir -p /usr/local/share/alsa/
cp -rfa $PWD/../../output/arm-linux/share/alsa/* /usr/local/share/alsa
运行aplay -l 会有如下结果,可以看到AC97和USB 声卡
[root@FriendlyARM bin]# ./run.sh
/mnt/nfs/obt9808_sw/output/arm-linux/lib
**** List of PLAYBACK Hardware Devices ****
card 0: SMDK6400 [SMDK6400], device 0: AC97 HiFi AC97 HiFi-AC97-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: U0x4b40x307 [USB Device 0x4b4:0x307], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
二.应用程序多声卡操作
测试音源,可以从如下网址下载wav文件进行测试
这里有一些标准的电话铃声下载
以下是用默认声卡.
export LD_LIBRARY_PATH=/mnt/nfs/output/arm-linux/lib;./aplay ringback.wav
指定第二块声卡播放,用-D参数,设备名来自-l的查询
方法1:用名字指定
export LD_LIBRARY_PATH=/mnt/nfs/obt9808_sw/output/arm-li
nux/lib;./aplay east123.wav -D default:CARD=U0x4b40x307
方法2:用声卡编号指定:
export LD_LIBRARY_PATH=/mnt/nfs/obt9808_sw/output/arm-linux/lib;./aplay east123.wav -D plughw:1,0
arecord -D default:CARD=U0x4b40x307 -d 20 -c 2 -t wav -r 8000 -f "Signed 16 bit Little Endian" 4.wav
rec -d default:CARD=U0x4b40x307 -c 2 -r 8000 -t wav -s w 8.wav
madplay测试
./configure --host=arm-linux --prefix=$PWD/../../output/arm-linux --with-alsa --with-libiconv-prefix=$PWD/../../output/arm-linux --enable-shared --enable-static CPPFLAGS="-I$PWD/../../output/arm-linux/include" LDFLAGS="-L$PWD/../../output/arm-linux/lib -lasound " --with-libiconv-prefix="$PWD/../../output/arm-linux/"
增加多声卡支持
分析其代码,在alsa下有专门的处理init初始化代码。这里打开音频设备中,虽然有init->path,但是在alsa总是初始化为空,因此alsa总是打开缺省设备用。
static
int init(struct audio_init *init)
{
int err;
if (init->path)
err = snd_pcm_open(&alsa_handle, init->path, SND_PCM_STREAM_PLAYBACK, 0);
else
err = snd_pcm_open(&alsa_handle, defaultdev, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
audio_error=snd_strerror(err);
return -1;
}
return 0;
}
|
模仿 audio_sun.c 增加一个用环境变量来修改声卡的的名字,红色声卡是
static
int init(struct audio_init *init)
{
int err;
if (init->path == 0) //add by Andrew Huang
init->path = getenv("AUDIODEV");
printf("hxy %s:init->path %s\n",__FUNCTION__,init->path);
if (init->path)
err = snd_pcm_open(&alsa_handle, init->path, SND_PCM_STREAM_PLAYBACK, 0);
else
err = snd_pcm_open(&alsa_handle, defaultdev, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
audio_error=snd_strerror(err);
return -1;
}
return 0;
}
|
测试结果,可以从第二块声卡播放出来
export AUDIODEV=plughw:1,0;export LD_LIBRARY_PATH=/mnt/n
fs/obt9808_sw/output/arm-linux/lib;./madplay 1.mp3
mplayer 的测试
mplayer运行时指定声卡的参数,可以参考这几篇文章
oss模式测试
./configure --prefix=$PWD/../../output/arm-linux --cc=arm-linux-gcc --ar=arm-linux-ar \
--ranlib=arm-linux-ranlib --disable-gui --disable-alsa \
--target=arm-armv4-linux --host-cc=gcc --disable-freetype\
--enable-fbdev --disable-mencoder --disable-sdl --disable-live --disable-dvdread \
--disable-libdvdcss-internal --disable-x11 --enable-cross-compile --disable-mp3lib \
--enable-mad --with-extraincdir="$PWD/../../output/arm-linux/include " --with-extralibdir="$PWD/../../output/arm-linux/lib " \
--disable-dvdnav --disable-dvdread-internal --disable-jpeg --disable-tga \
--disable-dvbhead --disable-pnm --disable-tv --disable-ivtv \
--disable-fontconfig --disable-xanim --disable-win32dll --disable-armv5te --disable-armv6
以下是测试成功的oss指令
export LD_LIBRARY_PATH=/mnt/nfs/obt9808_sw/output/arm-l
inux/lib; ./mplayer -vo null -ac mad -ao oss:/dev/dsp1 1.mp3
alsa模式:
以下是生成mplayer的Makefile,注意打开alsa,并且要关掉oss,否则会指定失败.
./configure --prefix=$PWD/../../output/arm-linux --cc=arm-linux-gcc --ar=arm-linux-ar --ranlib=arm-linux-ranlib --disable-gui --enable-alsa --disable-ossaudio --target=arm-armv4-linux --host-cc=gcc --disable-freetype --enable-fbdev --disable-mencoder --disable-sdl --disable-live --disable-dvdread --disable-libdvdcss-internal --disable-x11 --enable-cross-compile --disable-mp3lib --enable-mad --with-extraincdir="$PWD/../../output/arm-linux/include " --with-extralibdir="$PWD/../../output/arm-linux/lib " --disable-dvdnav --disable-dvdread-internal --disable-jpeg --disable-tga --disable-dvbhead --disable-pnm --disable-tv --disable-ivtv --disable-fontconfig --disable-xanim --disable-win32dll --disable-armv5te --disable-armv6
测试成功alsa指令:
export LD_LIBRARY_PATH=/mnt/nfs/obt9808_sw/output/arm-l
inux/lib; ./mplayer -vo null -ao alsa:noblock:device=plughw=1,0 1.mp3
但还有一个更简单方法是也是修改mplayer插件的目录的libmad库源码来象madplay一样播放多声卡声音
SDL的音乐库的测试
sdl主要用SDL_mix来播放音乐.它也依赖SDL库,因此要求SDL支持多声卡支持.
必须注意两点: 1.SDL必须打开alsa支持
2. SDL_mixer必须使用libmad库,这样可以用AUDIODEV环境变量指定.
SDL的生成脚本:
./configure --prefix=$PWD/../../output/arm-linux --disable-video-nanox --disable-video-qtopia --disable-video-photon --disable-video-ggi --disable-video-svga --disable-video-aalib --disable-video-dummy --disable-video-dga --disable-arts --disable-esd --enable-alsa --disable-video-x11 --disable-nasm --enable-joystick --enable-input-tslib --enable-video-fbcon --host=arm-linux --build=i386 CPPFLAGS="-I$PWD/../../output/arm-linux/include" LDFLAGS="-L$PWD/../../output/arm-linux/lib -lts -liconv" --with-alsa-prefix=$PWD/../../output/arm-linux
SDL_mixer的生成脚本:
./configure --enable-music-mp3-mad-gpl --enable-music-mp3=no --host=arm-linux --prefix=$PWD/../../output/arm-linux --with-sdl-prefix=$PWD/../../output/arm-linux --enable-shared --enable-static
测试,编译SDL_mixer自带的测试程序playmus.c 可以从第二个声卡来听到音乐声音
以下是成功运行LINUX脚本:
export PRJ_DIR=/mnt/nfs/obt9808_sw/output/arm-linux
export LD_LIBRARY_PATH=${PRJ_DIR}/lib
export AUDIODEV=plughw:1,0
#export AUDIODEV=default:CARD=U0x4b40x307
./playmus 1.mp3
阅读(6413) | 评论(0) | 转发(3) |