Linux ALSA - 支持软件回采参考信号
前期说明
-
什么是 “回采”?
回采是我司部门自定义的一个词, 说白了, 就是把 Codec(声卡) 输出(playback) 的音频信号重新集回 Soc 的动作. 目的是获取参考信号.
-
回采哪两种类型?
-
软件回采
-
通过代码实现, 首先 malloc 从内存中申请一块 buffer. 用于缓存播放音频, 在需要的时候将该buffer数据按照需要的格式传递给消费者的方式. 称为软件回采
硬件回采
-
通过 Codec 自身的录音通道(MIC_IN / LINE_IN / HP_IN), 将 Codec 输出(HP_OUT / LINE_OUT) 到 SPK(功放) 的音频(模拟信号) 重新采集到 Codec 的动作, 称为硬件回采
适用场景
-
为什么要回采
在这个 AI 漫天飞的世纪, 语音交互已经有很多的产品落地了. 比如智能音箱, 语音遥控, 手机语音助手, 均已接入语音服务商的SDK. 一般来说这个功能产品都是基于 NP(降噪), AEC(回声消除) 等技术实现, 回采功能就是 AEC 技术的基石.
-
应用场景
智能音箱(单MIC, 双MIC, 阵列MIC)
下面适用两张原理图来说明为什么需要软件回采
左边: RK3126C 内置声卡, 仅一路MIC_IN, 如果需要 AEC 功能, 在不增加硬件成本的前提下, 只能采用软件回采获取 playback 数据
右边: RK3128 内置声卡, 有 MIC_IN(MICL, R) 和 LINE_IN(AIL, R), 可惜内部 L/R 通路同时只允许一路输入, 可以采用硬件回采, 但仅仅只能获取一路 playback(L或者R)数据.
接下来我介绍的就是软件回采如何是实现. 需要修改的是 ALSA 的原生框架. 不了解的可以先自学一下.
实现原理
- 基于 Android6.0, AudioRecord录音流程图
源码路径:
/framework/base/media/java/android/media/AudioRecord.java
/framework/base/core/jni/android_media_AudioRecord.cpp
/framework/av/media/libmedia/AudioRecord.cpp
/framework/av/services/audioflinger/Threads.cpp
/hardware/rockchip/audio/tinyalsa_hal/audio_hw.c
/kernel/sound/core/pcm_native.c
/kernel/sound/core/pcm_lib.c
- 基本原理概述
在系统播放音频(playback)的时候, malloc playback_buffer(需要做成环形缓冲区), 将输出数据填入 buffer 备用, 当系统录音(capture)时, 将 playback_buffer 数据覆盖或者拼接到 capture_buffer 里面去.
Linux3.10 修改方法
linux_soft_callback_playback_record_patch.zip 一共为 kernel Alsa 三个部分(付费).
linux_include.patch
linux_core_pcm.patch
linux_soc_dmaengine.patch
[补充]: 有问题可以邮件沟通 iFinelio Tower <308662170@qq.com>