任何关于从哪里开始的想法?我已经对OpenSL和ALSA进行了一些研究,但是看起来我需要打包新的固件(ROM)来定义自定义的音频路径.如果可以避免,我想创建一个应用程序级解决方案.手机是“rooted”(有su二进制文件).目标设备是三星Galaxy S4 Google版(GT-i9505G).具体来说,我正在寻找音频驱动程序配置/源代码或i9505G的任何引用.
提前致谢!
编辑 – 我已经检出了CyanogenMod 10.2源代码树,以及jfltexx驱动程序和内核.这是kernel / samsung / jf / sound的内容:http://pastebin.com/7vK8THcZ.这是否记录在任何地方?
解决方法
此信息也可能适用于其他高通平台(如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/base和frameworks/av(例如AudioManager,AudioService,AudioSystem)中,您必须添加一个新的AudioSource常量,并确保它在所有必要的位置被识别.
>在UCM设置文件中,您必须添加一些新的动词/修饰符来在使用新的AudioSource时正确设置ALSA控件.
>在音频HAL中,您必须进行一些更改,以便在使用新的AudioSource时新的动词/修饰符被选中.请注意,有一个基类AudioPolicyManagerALSA称为AudioPolicyManagerBase,您也可能需要修改(它是located elsewhere in the source tree).