前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android 音频】“声音”从何而来

【Android 音频】“声音”从何而来

作者头像
腾讯大讲堂
发布2020-08-05 10:40:07
2K0
发布2020-08-05 10:40:07
举报

| 导语 透过本文,全面了解 Android 系统音频录制技能,深入理解王者时刻为什么没有把环境音或者人声录制下来

一、音频量化

音频基础的文章很多,想要了解更多,请自行百度。这里重点关注 PCM 和采样率,因为目前遇到的音频问题都跟这两个有关。 接下来看一张经典的音频采样流程图:

以上就是计算机系统中的音频文件的生成过程:采样、量化、编码。 人耳所能听到的声音,最低的频率是 20Hz ~ 20KHZ,因此音频文件格式的最大带宽是 20KHZ。

根据奈奎斯特的理论,只有采样频率高于声音信号最高频率的两倍时,才能把数字信号表示的声音还原成为原来的声音,所以音频文件的采样率一般在 40~50KHZ,比如最常见的 CD 音质采样率 44.1KHZ。

对声音进行采样、量化过程被称为脉冲编码调制(Pulse Code Modulation),简称PCM。PCM 数据是最原始的音频数据完全无损,所以 PCM 数据虽然音质优秀但体积庞大,为了解决这个问题先后诞生了一系列的音频格式,这些音频格式运用不同的方法对音频数据进行压缩,其中有无损压缩(ALAC、APE、FLAC)和有损压缩(MP3、AAC、OGG、WMA)两种。

二、录音方式

1、系统内录

直接上 Google 官方的文档,大意就通过该接口可以进行实时字幕和游戏内录音。这里不准备深入,因为硬性要求 Android Q 及以上系统版本(文末有 AudioPlaybackCapture 使用实例可以参考):

2、麦克风录制

麦克风录制要特别注意的两个情况:

  • 同时只能有一个实例存在,比如有 GVoice 在录音,那么其他都要歇菜了。官方文档 “共享音频输入” 有详细的说明。
  • 另一种情况就是不可控(可能会录制到 ”黄、爆” 音频)。

2.1、基本概念

Android 系统提供的录制麦克风方式就两种:MediaRecorder 和 AudioRecord:

  • MediaRecorder:简易模式,调用简单,只有开始、结束,录音之后的文件也是指定编码格式,系统播放器可以直接播放。
  • AudioRecord:原始模式,可以暂停、继续,可以实时获取到 PCM 数据然后进行音视频的混合,也是录屏软件经常使用的接口。

2.2、麦克风内录的另类实现

通过上面的 AudioRecord 的代码可以发现,输入源是可以配置的,并且通过接口文档很快就发现 REMOTE_SUBMIX 这个输入源也可以实现内录功能,但是有两个必要条件:

  • 需要系统权限,就是需要在 Android 源码中进行编译的工程才可以获取系统签名权限
  • 会截走扬声器和耳机的声音,也就是说在录音时本地无法播放声音

3、Hook 内录

通过以下 Android 的音频系统架构图可以看出,Android 提供的唯二接口:MediaPlayer 和 AudioTrack,最终都是经过 AudioFlinger 的 AudioStreamOut::write(const void *buffer, size_t numBytes) 把数据传递到硬件层:

通过 inline hook 的形式可以导出音频数据,目前 KM 上已经有同事实践成功,具体可以参考链接: http://km.oa.com/group/22117/articles/show/223181

但是,inline hook 需要操作寄存器并且方案通用性欠佳,所以不建议使用 inline hook。不过,在音频数据流转的过程中截取数据的形式是通用做法,引擎内录就是借鉴的这种做法。在更高的层级进行的获取行为,并且由于层级比较高,所以无法做到一个方案覆盖全的情况。几乎都是跟引擎密切相关,但是也有好的方面,就是稳定性得到了保证并且可以统一多端的获取逻辑。

4、引擎内录

引擎内录可以统一 Android、iOS、PC 多端音频获取逻辑

从上图可以看出,整个获取内音的逻辑很简单,但是,引擎这么多,引擎插件怎么写就成了一个难题

我们先从最简单的 Unity FMOD 开始。

4.1、Unity FMOD 内录

Unity 內置的 Audio 內部使用的是 FMOD,但是没有导出接口,所以无法使用 FMOD 插件的方式。

通过查找 ,Unity 给出类似的接口,简单实现如下,具体的请查看附件 ExportAudioRes.cs 和 FmodSupport.cs

集成的话,只需要把 ExportAudioRes.cs 挂载到 AudioListener 所在的主 Camera 就可以(保存成 PCM 文件是常用的调试技巧):

代码语言:javascript
复制
public class ExportAudioRes : MonoBehaviour
{
    ...
    void OnAudioFilterRead(float[] data, int channels)
    {
        FmodSupport.FmodWritePCM(data, data.Length, (uint)channels);
        
        if (DebugInGame)
        {
            // 把音频数据直接保存成 PCM 文件,这样就可以定位是否是音频本身的问题
            this.Write(data);
        }
    }
}

4.2、 FMOD Studio 内录

感觉这是废话:安装 FMOD Studio ,打开工程导入 FMOD for Unity

如果只是测试,可以直接使用 FMOD Studio 自带的样例的 bank 文件,FMOD 在 Unity 里面的配置也比较简单,如下动图所示,设置 bank 路径然后添加事件响应就可以:

接下来是 FMOD 插件实现的关键代码:

4.3、 Wwise 内录

安装 wwise Launcher 之后可以在本地路径下找到 AkDelay 的源码,通过改造源码添加转发器就可以实现自定义插件:

代码语言:javascript
复制
D:\Program Files (x86)\Audiokinetic\Wwise 2017.1.9.6501\SDK\samples\Plugins\AkDelay
//通过修改上面的工程名,就可以得到一个自定义插件,有需要可以找我要工程源码

这里的关键就变成,如何在自定义插件里面把 “音频转发器” 这个库给拉起来? 为了减少工程之间的依赖,Unity 里面可以通过 PInvoke 的形式动态拉起,但是在 wwise 插件里面就需要另辟蹊径,但是肯定还是想使用动态打开库的形式。直接上代码,大体如下:

另外需要注意的就是 wwise 插件需要挂载到 Master Audio Bus 上,并且不能同时挂载多个,否则录制出来的声音会叠加在一起:

前面只是抛砖引玉。 想要实现一个插件远比上面说的复杂。因为没有考虑版本兼容问题、插件的编译环境、动态获取库代码健壮性、不同平台差异兼容、插件集成等等问题。

5、思考扩展

既然引擎层面都有插件特效,那么 Android 原生应该也有对应的功能才对?是否可以利用呢?

代码语言:javascript
复制
//https://developer.android.com/reference/android/media/audiofx/Visualizer
//下面是摘抄于 Google 的文档,Google 早就料到会有人像我这样思考, 还特别提醒:这不是音频录制接口,别瞎用

三、联调案例

两个音频相关的实例:CFM 上出现的音频加速问题和 AOV 上出现的音频叠加问题

如果出现类似的情况,你会如何思考定位问题呢?答案就在上面的内容里,如果有好的思路请留言回复

无处不在的辛普森悖论

走近鹅厂专家 | Ta们靠什么成为专家?

如何通过画像洞察用户价值点

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯大讲堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、音频量化
  • 二、录音方式
    • 1、系统内录
      • 2、麦克风录制
        • 2.1、基本概念
        • 2.2、麦克风内录的另类实现
        • 通过上面的 AudioRecord 的代码可以发现,输入源是可以配置的,并且通过接口文档很快就发现 REMOTE_SUBMIX 这个输入源也可以实现内录功能,但是有两个必要条件:
      • 3、Hook 内录
        • 4、引擎内录
          • 4.1、Unity FMOD 内录
          • 4.2、 FMOD Studio 内录
        • 5、思考扩展
        相关产品与服务
        汽车精准获客服务
        腾讯云汽车精准获客服务(Automotive Precise Customer Acquisition Service,APCAS)为车企提供潜客洞察能力, 实现已有线索特征洞察与意向预判。支持人群管理,为企业提供已有线索人群特征洞察服务与可视化展示,以及潜客购车意向预判服务,搭建高效简单的精准营销获客服务。支持多种结算和部署方式,灵活满足业务需求。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档