有没有人有在 Android 中重定向音频或创建新声音路径的经验(使用 OpenSL ES、ALSA 等)?最终目标是创建一个虚拟麦克风来取代外部麦克风,在那里人们可以播放音频文件,就像他们对着麦克风说话一样。使用 AudioSource.MIC
访问麦克风的应用程序应该使用这个备用流。它没有必要与语音通话一起工作,我相信实现这种功能更难,因为这一切都是在 radio 中完成的。
关于从哪里开始的任何想法?我已经对 OpenSL 和 ALSA 进行了一些研究,但看起来我需要打包新固件 (ROM) 才能定义自定义音频路径。如果可以避免,我想创建一个应用程序级解决方案。电话是“ Root ”的(有 su 二进制文件)。此操作的目标设备是三星 Galaxy S4 Google 版 (GT-i9505G)。具体来说,我正在寻找 i9505G 的音频驱动程序配置/源代码或任何引用资料。
提前致谢!
编辑 - 我已经检查了 CyanogenMod 10.2 源代码树,以及 jfltexx 驱动程序和内核。以下是kernel/samsung/jf/sound的内容:http://pastebin.com/7vK8THcZ .这在任何地方都有记录吗?
最佳答案
我曾经在基于 Qualcomm 的 APQ8064 平台(这似乎与目标设备中的平台几乎相同的平台)的手机上实现了您所追求的功能。以下是我从中可以记忆起的内容的摘要,因为我无法再访问我编写的代码,也无法访问可以轻松进行此类修改的环境。所以如果这个答案读起来像是一堆零碎的内存,那是因为它就是这样。
此信息也可能或多或少适用于其他高通平台(如 MSM8960 或 MSM8974),但很可能对其他供应商的平台(NVidia Tegra、三星 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)。我的理解是这些设置已移至名为 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"
的动词(基本上是音频用例的基础;还有一些修饰符可以应用于动词之上,用于同步播放和录音等内容)。 (HiFi
绰号用于大多数非语音调用动词,PROXY
指使用的音频设备,Rx
表示输出)并指定要写入的 ALSA 控件以及要写入的内容对他们来说,何时应该启用/禁用用例。最后,它列出了在此用例中使用的 ALSA PCM 播放/捕获设备。例如,PlaybackPCM 0
意味着应该使用播放设备 0(ALSA 卡被暗示为代表内置硬件编解码器的卡,通常是卡 0)。这些动词由音频 HAL 根据用例(音乐播放、语音通话、录音等)、您附加的附件等选择。如果您查找
"AFE_PCM_RX Audio Mixer"
在 msm_qdsp6_widgets table在 msm-pcm-routing.c
你会看到它指的是 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, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
... and so on...
这列出了允许您连接到后端 DAI (
AFE_PCM_RX
) 的前端 DAI。要了解这些之间的关系,请参阅 these diagrams . AFE_PCM_RX
和 AFE_PCM_TX
是 Qualcomm 某些平台上的一对 DAI,它们实现了一种虚拟/代理设备。您所做的是将音频输入 AFE_PCM_RX
然后由多媒体DSP(QDSP)处理,然后您可以通过AFE_PCM_TX
读取它.这用于实现 USB 和 WiFi 音频路由,以及 A2DP IIRC。返回
AFE_PCM_RX Audio Mixer MultiMedia1
行:这表示您正在喂食 MultiMedia1
进AFE_PCM_RX Audio Mixer
. MultiMedia1
用于正常播放/录音,对应pcmC0D0
(您应该能够使用 adb shell cat /proc/asound/devices
列出手机上的设备)。还有其他前端 DAI,例如 MultiMedia3
和 MultiMedia5
用于低延迟播放和低功耗音频播放等特殊情况。当您喂食时
MultiMedia1
到 AFE_PCM_RX Audio Mixer
您写入卡 0 上的播放设备 0 的所有内容都将被送入 AFE_PCM_RX
后端 DAI。要回读它,您可以设置一个 UCM 动词,它执行类似 'MultiMedia1 Mixer AFE_PCM_TX':1:1
的操作。 ,然后你会读到 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 Low Power"
动词与您对 "HiFi"
所做的类似动词。如果您在音频 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 Port Mixer
来利用它这让我可以建立从后端 DAI 到另一个后端 DAI 的连接。如果你看 afe_pcm_rx_port_mixer_controls
和 intercon
msm-pcm-routing.c
中的表格你会注意到没有 SLIM_0_RX
AFE_PCM_RX Port Mixer
的条目,所以你必须自己添加这些(这只是复制粘贴一些现有行并更改名称的问题)。您可能需要进行的其他一些更改:
AudioManager
、 AudioService
、 AudioSystem
)你必须添加一个新的 AudioSource
不变,并确保它在所有必要的地方得到认可。 AudioSource
时正确设置 ALSA 控件。用来。 AudioSource
时选择您的新动词/修饰语。用来。请注意,有一个基类 AudioPolicyManagerALSA
叫 AudioPolicyManagerBase
您可能还需要修改(它是 located elsewhere in the source tree )。 关于android - 在 Android 中重定向音频/创建备用声音路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21024851/