我曾经在一款基于高通 APQ8064 平台的手机上实现了您想要的功能(该平台似乎与您的目标设备中的平台几乎相同)。以下是我从中回忆起的内容的摘要,因为我不再能够访问我编写的代码,也无法再访问可以轻松进行此类修改的环境。因此,如果这个答案读起来像是一堆零碎的记忆,那是因为事实就是如此。
此信息也可能或多或少适用于其他 Qualcomm 平台(例如 MSM8960 或 MSM8974),但对于其他供应商(NVidia Tegra、Samsung Exynos、TI OMAP 等)的平台很可能完全无用。
简单说明:我使用的方法意味着录音应用程序获取的音频将在 Android 多媒体框架和/或平台的多媒体 DSP 中经过混音/音量控制。因此,如果您以 75% 的音量播放某些内容,录制它,然后以 75% 的音量播放录音,最终听起来可能会非常安静。如果你想获得未处理的 PCM 数据(解码后,但在混合/音量控制之前),你将不得不寻找其他方法,例如定制AudioFlinger
,但这不是我尝试过或可以提供的信息。
几个感兴趣的地点:
该平台的音频驱动程序 https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/sound/soc/msm?h=kk_3.5_rb1.16。特别是msm-pcm-routing.c 文件 https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/sound/soc/msm/msm-pcm-routing.c?h=kk_3.5_rb1.16.
ALSA UCM(用例管理器)设置文件 https://android.googlesource.com/device/lge/mako/+/jb-mr1-dev/snd_soc_msm_2x_Fusion3。这只是 UCM 设置文件的示例。这些文件有许多变体,具体取决于所使用的具体平台,因此您的文件的名称可能略有不同(尽管它should从...开始snd_soc_msm_
),其内容可能也与我链接的内容略有不同。
Kitkat 及更高版本的注意事项:UCM 设置文件用于 Jellybean(也可能是 ICS)。我的理解是这些设置已移至名为的文件中mixer_paths.xml https://android.googlesource.com/device/lge/mako/+/master/mixer_paths.xml关于奇巧。内容几乎相同,只是格式不同。
音频HAL代码 https://www.codeaurora.org/cgit/quic/la/platform/hardware/qcom/audio/tree/?h=jb_3.2_rb5.43。 ALSA UCM 存在于libalsa-intf
,以及AudioHardware
/ AudioPolicyManager
/ ALSADevice
代码存在于audio-alsa
。请注意,此代码适用于 Jelly Bean,因为这是我熟悉的最新版本。 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
这定义了一个verb(本质上是音频用例的基础;还有修饰语可以应用于动词之上,例如同时播放和录音),名称为"HiFiPROXY Rx"
(the HiFi
绰号用于大多数非语音呼叫动词,PROXY
指所使用的音频设备,并且Rx
表示输出)并指定在应启用/禁用用例时要写入哪些 ALSA 控件以及写入内容。最后,它列出了在此用例中使用的 ALSA PCM 播放/捕获设备。例如,PlaybackPCM 0
表示应使用播放设备 0(ALSA 卡隐含为代表内置硬件编解码器的卡,通常为卡 0)。这些动词由音频 HAL 根据用例(音乐播放、语音通话、录音……)、您连接的附件等进行选择。
如果你抬头看"AFE_PCM_RX Audio Mixer"
in the msm_qdsp6_widgets 表 https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/sound/soc/msm/msm-pcm-routing.c?h=kk_3.5_rb1.16#n2719 in msm-pcm-routing.c
你会看到它指的是名为的混音器控件列表afe_pcm_rx_mixer_controls https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/sound/soc/msm/msm-pcm-routing.c?h=kk_3.5_rb1.16#n1691看起来像这样:
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 的前端 DAI(AFE_PCM_RX
)。要了解它们之间的关系,请参阅这些图 https://www.kernel.org/doc/Documentation/sound/alsa/soc/DPCM.txt.
AFE_PCM_RX
and 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
and MultiMedia5
用于低延迟播放和低功耗音频播放等特殊情况。
当你喂食时MultiMedia1
to the 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"
verb's 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
to AFE_PCM_TX
.
将修改后的 UCM 设置文件复制回手机(需要 root 权限),然后重新启动手机。然后开始一些播放(连接有线耳机/耳机,并禁用触摸声音,以便不会选择低延迟动词),并从AudioSource.MIC
。然后,检查录音并查看是否能够录制播放音频。如果没有,那么可能选择了低功率音频动词,您必须修改"HiFi Low Power"
动词类似于你对 the 所做的"HiFi"
动词。如果您在音频 HAL 中启用了所有调试打印(即取消注释#define LOG_NDEBUG 0
在所有可以找到它的 cpp 文件中),这样您就可以看到选择了哪些 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
and intercon
表在msm-pcm-routing.c
你会注意到没有SLIM_0_RX
条目为AFE_PCM_RX Port Mixer
,因此您必须自己添加这些内容(只需复制粘贴一些现有行并更改名称即可)。
您可能需要进行的其他一些更改:
In 框架/基础 https://www.codeaurora.org/cgit/quic/la/platform/frameworks/base/tree/?h=aosp-new/master and 框架/AV https://www.codeaurora.org/cgit/quic/la/platform/frameworks/av/tree/?h=aosp-new/master (e.g. AudioManager
, AudioService
, AudioSystem
)你必须添加一个新的AudioSource
恒定并确保它在所有必要的地方得到认可。
在 UCM 设置文件中,您必须添加一些新的动词/修饰符,以便在您的新版本时正确设置 ALSA 控件。AudioSource
用来。
在音频 HAL 中,您必须进行一些更改,以便在您的新动词/修饰语时选择您的新动词/修饰语。AudioSource
用来。请注意,有一个基类AudioPolicyManagerALSA
called AudioPolicyManagerBase
您可能还需要修改它(它是位于源代码树的其他位置 https://www.codeaurora.org/cgit/quic/la/platform/hardware/libhardware_legacy/tree/audio?h=kk_2.7_rb1.21).