在Android中重定向音频/创建备用声音路径

有没有人有经验(使用OpenSL ES,ALSA等)重定向音频或在 Android中创建新的声音路径?最终目标是创建一个虚拟麦克风来取代外部麦克风,在那里可以播放音频文件,就像他们正在说话的麦克风一样.使用AudioSource.MIC访问麦克风的应用程序应使用此备用流.没有必要使用语音电话,我相信实现这种功能更难,因为它都在收音机内完成.

任何关于从哪里开始的想法?我已经对OpenSL和ALSA进行了一些研究,但是看起来我需要打包新的固件(ROM)来定义自定义的音频路径.如果可以避免,我想创建一个应用程序级解决方案.手机是“rooted”(有su二进制文件).目标设备是三星galaxy S4 Google版(GT-i9505G).具体来说,我正在寻找音频驱动程序配置/源代码或i9505G的任何引用.

提前致谢!

编辑 – 我已经检出了CyanogenMod 10.2源代码树,以及jfltexx驱动程序和内核.这是kernel / samsung / jf / sound的内容http://pastebin.com/7vK8THcZ.这是否记录在任何地方?

解决方法

我曾经基于高通的APQ8064平台(这似乎与目标设备中的平台几乎相同的平台)在手机上实现了您的功能.以下是我从此可以回顾的总结,因为我无法访问我写的代码,或者可以轻松进行这些修改的环境.所以如果这个答案看起来像一堆碎片的回忆,那就是因为这是真的.

此信息也可能适用于其他高通平台(如MSM8960或MSM8974),但对于来自其他厂商(NVidia Tegra,Samsung Exynos,TI OMAP等)的平台来说,这些信息很可能是完全无用的.

简要说明:我使用的方法意味着录音应用程序获得的音频将在Android多媒体框架和/或平台的多媒体DSP中进行混合/音量控制.所以,如果你在75%的音量下播放音乐,录制它,然后以75%的音量播放录音,可能听起来很安静.如果要获得未处理的PCM数据(解码之后,但在混合/音量控制之前),您将不得不研究其他方法,例如定制audioflinger,但这不是我尝试过或可以提供信息的东西.

一些兴趣点:

The platform’s audio drivers.特别是msm-pcm-routing.c file.

The ALSA UCM (Use-Case Manager) settings file.这只是一个例子UCM设置文件.这些文件有许多变体,这取决于所使用的确切平台,所以你的名字可能有一个稍微不同的名字(虽然它应该以snd_soc_msm_开头),其内容也可能与我链接内容略有不同.
Kitkat及更高版本的注意事项:UCM设置文件用于Jellybean(也可能是ICS).我的理解是这些设置已被移动到Kitkat上名为mixer_paths.xml文件.内容几乎相同,只是在不同的格式.

The audio HAL code. ALSA UCM存在于libalsa-intf中,AudioHardware / AudioPolicyManager / ALSADevice代码存在于audio-alsa中.请注意,此代码适用于Jellybean,因为这是我熟悉的最新版本. Kitkat上的目录结构(以及可能的一些文件/类)不同.

如果您打开UCM设置文件搜索“HiFiPROXY Rx”,您会发现如下:

SectionVerb
Name "HiFiPROXY Rx"

EnableSequence
    'AFE_PCM_RX Audio mixer MultiMedia1':1:1
EndSequence

disableSequence
    'AFE_PCM_RX Audio mixer MultiMedia1':1:0
EndSequence

# ALSA PCMs
CapturePCM 0
PlaybackPCM 0
EndSection

这定义了一个动词(基本上是音频用例的基础;还有一些修饰符可以应用在诸如同时播放和录音等动作的动词之上),名称为“HiFiPROXY Rx”(高保真音符用于大多数非语音呼叫动词,PROXY是指使用的音频设备,Rx表示输出),并指定在启用/禁用用例时要写入的ALSA控件以及要写入的内容.最后列出在此用例中使用的ALSA PCM播放/捕获设备.例如,PlaybackPCM 0表示应该使用播放设备0(ALSA卡被暗示为代表内置硬件编解码器的ALSA卡,通常是卡0).这些动词由音频HAL根据用例(音乐播放,语音通话,录音,…),您附加的配件等选择.

如果您在msm-pcm-routing.c中查找msm_qdsp6_widgets table中的“AFE_PCM_RX音频混合器”,您将看到它指的是一个list of mixer controls named afe_pcm_rx_mixer_controls,如下所示:

static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
    SOC_SINGLE_EXT("MultiMedia1",MSM_BACKEND_DAI_AFE_PCM_RX,MSM_FRONTEND_DAI_MULTIMEDIA1,1,msm_routing_get_audio_mixer,msm_routing_put_audio_mixer),SOC_SINGLE_EXT("MultiMedia2",... and so on...

这将列出您允许连接到后端DAI(AFE_PCM_RX)的前端DAI.要了解这些关系如何相互关联,请参阅these diagrams.AFE_PCM_RX和AFE_PCM_TX是高通平台上实现一种虚拟/代理设备的一对DAI.您所做的是将音频馈送到AFE_PCM_RX,然后由多媒体DSP(QDSP)处理,然后您可以通过AFE_PCM_TX读取它.这是用于实现USB和WiFi音频路由,以及A2DP IIRC.

返回AFE_PCM_RX音频混音器MultiMedia1行:这表示您将MultiMedia1馈入AFE_PCM_RX音频混音器. MultiMedia1用于正常播放/录制,对应于pcmC0D0(您应该能够使用adb shell cat / proc / asound / devices在手机上列出设备).还有其他前端DAI,如MultiMedia3和MultiMedia5,用于特殊情况下,如低延迟播放和低功耗音频播放.
当您将MultiMedia1馈送到AFE_PCM_RX音频混合器时,您写入0卡上播放设备0的所有内容将被馈送到AFE_PCM_RX后端DAI.要读回来,您可以设置一个类似“MultiMedia1 mixer AFE_PCM_TX”:1:1的UCM动词,然后您将从pcmC0D0c(应该是认的ALSA捕获设备)读取.

一个简单的测试是从您的手机拉取UCM设置文件(应该位于/ system / etc /下的某个地方),并修改“HiFi”动词的EnableSequence,例如:

'AFE_PCM_RX Audio mixer MultiMedia1':1:1
'AFE_PCM_RX Audio mixer MultiMedia3':1:1
'AFE_PCM_RX Audio mixer MultiMedia5':1:1

(和类似地在disableSequence中,但是在每一行末尾有:1:0).

然后转到“Capture Music”修改器(这是正常录制的名称不太好的修饰符),并将SLIM_0_TX更改为AFE_PCM_TX.

修改后的UCM设置文件复制回手机(需要root权限),然后重新启动手机.然后开始一些播放(连接有线耳机/耳机,并禁用触摸声音,以便未选择低延迟动画),并从AudioSource.MIC开始录制.然后,检查录音,看看是否能录制播放音频.如果没有,那么也许选择了低功率的音频动词,你必须像“HiFi”动词一样修改“HiFi Low Power”动词.如果您在音频HAL中启用了所有调试打印功能(即,在所有可以找到它的所有cpp文件中,取消注释#define LOG_NDEBUG 0),以便您可以看到所选的UCM动词/修饰符,这将有助于您.

上面描述的修改变得有点乏味,因为您必须覆盖所有相关动词和修饰符的所有MultiMedia前端DAI.
IIRC,我能够简化为每个动词/修饰符一行:

'AFE_PCM_RX Port mixer SLIM_0_RX':1:1

如果您看“HiFi”,“HiFi Low Power”,“HiFi Lowlatency”动词,您会看到他们都使用了SLIMBUS_0_RX后端DAI,所以我利用这个AFE_PCM_RX端口混音器我建立了从后端DAI到另一个后端DAI的连接.如果您看到msm-pcm-routing.c中的afe_pcm_rx_port_mixer_controls和intercon表,您会注意到AFE_PCM_RX Port mixer没有SLIM_0_RX条目,所以您必须自己添加(这只是一个复制粘贴的问题的现有线条和更改名称).

您可能需要做的其他一些变更:

>在frameworks/baseframeworks/av(例如AudioManager,AudioService,AudioSystem)中,您必须添加一个新的AudioSource常量,并确保它在所有必要的位置被识别.
>在UCM设置文件中,您必须添加一些新的动词/修饰符来在使用新的AudioSource时正确设置ALSA控件.
>在音频HAL中,您必须进行一些更改,以便在使用新的AudioSource时新的动词/修饰符被选中.请注意,有一个基类AudioPolicyManagerALSA称为AudioPolicyManagerBase,您也可能需要修改(它是located elsewhere in the source tree).

相关文章

Android 通过adb shell命令查看内存,CPU,启动时间,电量等...
Monkey Android app稳定性测试工具之Monkey使用教程 by:授客...
Android 常见adb命令 by:授客 QQ:1033553122 1、 查看所有已...
这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...