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

 特异型爷们喵 发布于 2023-02-04 19:20

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

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

提前致谢!

编辑 - 我已经检查了CyanogenMod 10.2源代码树,以及jfltexx驱动程序和内核.以下是kernel/samsung/jf/sound的内容:http://pastebin.com/7vK8THcZ.这记录在哪里?

1 个回答
  • 我曾经在基于高通公司APQ8064平台的手机上实现了你所追求的功能(它似乎与目标设备中的平台几乎相同).下面是我可以从中回忆起的内容摘要,因为我不再能够访问我编写的代码,或者我可以轻松地进行这些修改的环境.因此,如果这个答案看起来像一堆零碎的记忆,那就是因为它正是它的本质.

    此信息也可能适用于其他Qualcomm平台(如MSM8960或MSM8974),但很可能对其他供应商的平台(NVidia Tegra,Samsung Exynos,TI OMAP等)完全无用.

    简要说明:我使用的方法意味着录制应用程序获得的音频将在Android多媒体框架和/或平台的多媒体DSP中经历混音/音量控制.因此,如果您正在播放75%的音量,录制它,然后以75%的音量播放录音,那么听起来可能会非常安静.如果你想获得未处理的PCM数据(在解码之后,但在混音/音量控制之前),你将不得不考虑其他一些方法,例如自定义AudioFlinger,但这不是我试过或可以提供信息的东西.


    一些感兴趣的地方:

    该平台的音频驱动程序.特别是msm-pcm-routing.c文件.

    ALSA UCM(用例管理器)设置文件.这只是一个示例UCM设置文件.根据所使用的确切平台,这些文件有许多变体,因此您的名称可能略有不同(尽管它应该snd_soc_msm_)开头,其内容可能与我链接的内容略有不同.
    Kitkat及更高版本的注意事项: UCM设置文件用于Jellybean(可能还有ICS).我的理解是这些设置已被移动到mixer_paths.xmlKitkat上命名的文件.内容几乎相同,只是格式不同.

    音频HAL代码.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控件.最后,它列出了在此用例中使用的ALSA PCM播放/捕获设备.例如,PlaybackPCM 0表示应该使用回放设备0(ALSA卡隐含为表示内置硬件编解码器的卡,通常是卡0).这些动词由音频HAL根据用例(音乐播放,语音通话,录音......),您附加的配件等选择.


    如果你"AFE_PCM_RX Audio Mixer"在msm_qdsp6_widgets表中查找,msm-pcm-routing.c你会看到它引用了一个名为的混音器控件列表,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 .要了解这些如何相互关联,请参阅这些图表.
    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).还有其他前端讲台,就像MultiMedia3MultiMedia5那些在特殊情况下,如低延时播放和低功耗的音频播放使用.
    当你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_TXAFE_PCM_TX.

    将修改后的UCM设置文件复制回手机(需要root权限),然后重新启动手机.然后开始一些播放(连接有线耳机/耳机,并禁用触摸声音,以便不选择低延迟动词),并从中开始录制AudioSource.MIC.然后,检查录音,看看是否能录制播放音频.如果没有,那么可能选择了低功率音频动词,你必须修改"HiFi Low Power"动词,类似于动词所做的"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_controlsintercon表中msm-pcm-routing.c你会注意到没有SLIM_0_RX条目AFE_PCM_RX Port Mixer,所以你必须自己添加(这只是复制粘贴一些现有的行和更改名称的问题).


    您可能需要进行的其他一些更改:

    在框架/基础和框架/ AV(例如AudioManager,AudioService,AudioSystem)你就必须添加一个新的AudioSource常数,确保它在所有必要的地方得到认可.

    在UCM设置文件中,您必须添加一些新的动词/修饰符,以便在AudioSource使用新的时正确设置ALSA控件.

    在音频HAL中,您必须进行一些更改,以便在使用新音色时选择新的动词/修饰符AudioSource.请注意,有一个AudioPolicyManagerALSA被调用的基类AudioPolicyManagerBase,您也可能需要修改它(它位于源树中的其他位置).

    2023-02-04 19:22 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有