常见的USB摄像头会自带MIC
使用tinypcminfo -D [card编号] 查看usb声卡支持的格式,通道等;pcm_in就是录音的,pcm_out是放音的。如下可知,该usb声卡支持的是1通道,因此使用tinycap录音时记得把声道设置正确。此外,例如你使用rk809进行放音,但由于rk809支持的是2通道的,所以放音会失败。
usb摄像头自带MIC不能走tinyalsa_hal,其走的是usbaudio_hal,这样才能自动识别支持的格式。hardware\libhardware\modules\usbaudio\audio_hal.c中可以打印出这些函数的返回值,tinypcminfo -D [USB声卡] 看下和usb声卡参数是否正确,这些函数都是根据usb声卡信息去自动匹配的。
调试时会遇到使用tinycap可以正常的录取到声音,但用系统自带的录音机无法录音,会报如下错误: 这是参数不匹配导致的,可如下修改
proxy_open() pcm_is_ready() failed: cannot set hw params: Invalid argument
usb mic的优先级是高于板载麦的,例如rk3568平台,未插入usb摄像头时,使用rk809,插入带mic的usb摄像头时,就会使用usb声卡录音。那如何修改,在插入usb摄像头时,还是使用rk809进行录音呢?如下patch,当接入usb带麦克风的设备时,使用板载麦克风。
android只能录默认优先级高的设备,而优先级的修改参考下面的补丁:也是在Engine.c文件中
在apk里面调用相关的接口去选择录音设备,也就是实现切换录音设备的功能
//获取当前录音设备
private AudioDeviceInfo mSelectDevice;
AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
//设置录音设备
public native void setAudioSource(@Source int audioSource) throws IllegalStateException;
加入使用mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);这个接口去获取录音设备,获取到个数是3,通过cat /proc/asound/cards查到的只有一个,这个会是什么原因造成的? 其原因是音频来源除了物理声卡,还可以源自其他地方,比如投屏,网络,或者一些模拟设备等。这个又不是一一对应的关系。
usb声卡,使用tinycap录音正常,但本地录音会存在杂音;看logcat存在如下警告,内存溢出了,可能是buffer太小的原因,导致溢出,存在杂音
04-14 17:06:29.539 425 2860 W AudioFlinger: RecordThread: buffer overflow
\system\media\alsa_utils\alsa_device_proxy.c如下修改,使用默认的SIZE;在alsa_utils/alsa_device_profile.c中定义了#define DEFAULT_PERIOD_SIZE 1024
上面是针对usb声卡,还有板载mic,修改 hardware\rockchip\audio\tinyalsa_hal\audio_hw.h里面period_size
所以usb声卡的相关调试文件主要有以下几个,可以去熟悉下
system/media/alsa_utils/alsa_device_proxy.c
system/media/alsa_utils/alsa_device_profile.c
hardware\libhardware\modules\usbaudio\audio_hal.c
frameworks\av\services\audiopolicy\enginedefault\src\Engine.cpp