有个需求是实现sample rate的转换,用到了alsa-plugins中的resample
先来说说alsa-utils,alsa-lib,alsa-plugins,libsamplerate的关系
编译
编译alsa-lib-1.1.5
./configure --prefix=/home/lei/alsa/build/
make
make install
经过发现,alsa-lib默认是会编译所有的plugin的,所以不需要再通过--with-pcm-plugins
和--with-plugindir
单独去指定了。当然如果你不需要所有的plugin都编译,可以通过--with-pcm-plugins
指定某个或者某几个plugins,中间通过逗号分隔
可以在alsa-lib中的configure文件中看到目前支持这些plugins
PCM_PLUGIN_LIST="copy linear route mulaw alaw adpcm rate plug multi shm file null empty share meter hooks lfloat ladspa dmix dshare dsnoop asym iec958 softvol extplug ioplug mmap_emul"
编译libsamplerate-0.1.9
因为alsa-plugins中的rate_resample会用到libsamplerate,所以先提前编译好
./configure --prefix=/home/lei/alsa/build/
make
make install
会生成
/home/lei/alsa/build/lib/libsamplerate.so
/home/lei/alsa/build/include/samplerate.h
/home/lei/alsa/build/bin/sndfile-resample
其中sndfile-resample is a sample rate converter using libsndfile for file I/O
编译alsa-plugins-1.1.5
./configure --prefix=/home/lei/alsa/build/
会出现如下错误:
原先是没有找到alsa-lib,解法:export PKG_CONFIG_PATH=/home/lei/alsa/build/lib/pkgconfig
之后又出现了如下错误:
这个问题花了我不少时间,一开始总是以为在libasound中没有找到snd_pcm_ioplug_create
这个symbol,其实并不是,后来在网上查到说可以通过config.log分析具体问题出在哪里,原来是在执行./configure的时候会去check -lasound,发现并没有找到-lasound,原来是这样,于是我在环境变量中设置了下CFLAGS和就好了,但是这里有点奇怪啊,明明上面可以通过PKG_CONFIG_PATH
找到头文件和库文件的位置,非要通过CFLAGS再指定一次。
export CFLAGS="-I/home/lei/alsa/build/include -L/home/lei/alsa/build/lib"
make & make install
最终将samplerate这个plugin编译好了
会生成
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_samplerate_best.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_samplerate_linear.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_samplerate_medium.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_samplerate_order.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_samplerate.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_speexrate_best.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_speexrate_medium.so
/home/lei/alsa/build/lib/alsa-lib/libasound_module_rate_speexrate.so
alsa配置文件
在使用aplay的时候/usr/share/alsa/alsa.conf
会读取~/.asoundrc或者/etc/asound.conf文件,由于这里我们需要使用plugin,有两种方法可以使用
方法一
在~/.asoundrc或者/etc/asound.conf文件加入default.pcm.rate_convert "samplerate"
或者default.pcm.rate_convert "speexrate"
,是两种不同的rate转换的plugin
然后在播放的时候使用命令行aplay -v -D "plug:SLAVE='hw:0,0'" in_my_song_8K16bit2c_mp3.wav
进行播放
方法二
在~/.asoundrc或者/etc/asound.conf文件加入
pcm.my_rate {
type rate
slave {
pcm "hw"
rate 48000
}
converter "samplerate" # or converter "speexrate"
}
然后在播放的时候使用命令行aplay -D my_rate in_my_song_8K16bit2c_mp3.wav
进行播放。
测试
lei@lei:~$ aplay -v -D "plug:SLAVE='hw:0,0'" in_my_song_8K16bit2c_mp3.wav
Playing WAVE 'in_my_song_8K16bit2c_mp3.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
Plug PCM: Rate conversion PCM (48000, sformat=S16_LE)
Converter: libsamplerate
Protocol version: 10002
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 8000
exact rate : 8000 (8000/1)
msbits : 16
buffer_size : 2730
period_size : 682
period_time : 85312
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 682
period_event : 0
start_threshold : 2730
stop_threshold : 2730
silence_threshold: 0
silence_size : 0
boundary : 1536853372840181760
Slave: Hardware PCM card 0 'Intel 82801AA-ICH' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 16
buffer_size : 16380
period_size : 4095
period_time : 85312
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 4095
period_event : 0
start_threshold : 16380
stop_threshold : 16380
silence_threshold: 0
silence_size : 0
boundary : 9221120237041090560
appl_ptr : 0
hw_ptr : 0
播放的sample rate是8000,经过如上的Converter: libsamplerate
转换成48000给最终的硬件播放出去了
如果尝试加上参数--disable-resample
就会发现,不会再走sample rate这个plugin了,实际播放出去的是48000,但是由于音频文件是8000的又没有经过sample rate转换,播放出来的效果是很快的声音,就不是正常的声音了。
lei@lei:~$ aplay -v -D "plug:SLAVE='hw:0,0'" --disable-resample in_my_song_8K16bit2c_mp3.wav
Playing WAVE 'in_my_song_8K16bit2c_mp3.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
Warning: rate is not accurate (requested = 8000Hz, got = 48000Hz)
please, try the plug plugin
Plug PCM: Hardware PCM card 0 'Intel 82801AA-ICH' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 16
buffer_size : 16384
period_size : 4096
period_time : 85333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 4096
period_event : 0
start_threshold : 16384
stop_threshold : 16384
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
appl_ptr : 0
hw_ptr : 0
查看硬件实际播放的sample rate
可以通过cat /proc/asound/card0/pcm0p/sub0/hw_params
查看实际硬件播放时候的sample rate