audio_hw.c核心逻辑及第三方算法集成

天资达人 时政新闻 2026-02-07 4659 0

一、文件核心内容分析

(一)核心配置解析

该文件的配置主要分为PCM参数配置路由配置设备标识配置三类,是音频硬件抽象层(HAL)与底层ALSA驱动交互的基础。

wKgZPGkaixaABjWTAAJWySiB9qc708.png
1. PCM参数配置(音频数据格式定义)

定义了不同场景下的PCM(脉冲编码调制)数据格式,包括声道数、采样率、周期大小等关键参数,决定了音频数据的传输格式。

配置名称

适用场景

核心参数(channels/rate/format

备注

pcm_config

基础音频输出(如媒体播放)

2声道/ 44100Hz / S16_LE16位小端)

通用播放场景默认配置

pcm_config_in

基础音频输入(如录音)

2声道(默认)/ 44100Hz / S16_LE

支持参考声道扩展(PCM_REFERENCE_CHANNELS

pcm_config_in_low_latency

低延迟输入(如语音通话)

2声道/ 48000Hz / S16_LE

降低延迟以保证实时性

pcm_config_sco

蓝牙SCO链路(语音)

1声道/ 8000Hz / S16_LE

蓝牙语音通话专用(窄带音频)

pcm_config_hdmi_multi

HDMI多声道输出

6声道(可动态修改)/默认采样率/ S16_LE

支持多声道环绕声输出

pcm_config_direct

直接输出(如SPDIF

2声道/ 48000Hz / IEC958S24_LE

用于数字音频直通(无解码,直接传输比特流)

2.路由配置(音频路径映射)

通过route_config结构体和路由表route_configs定义输入源与输出设备的对应关系,决定音频数据的物理传输路径(如扬声器、耳机、蓝牙等)。

route_config结构体:包含播放路径(playback_route)、采集路径(capture_route)等,例如:

staticconststructroute_config media_speaker = { "media-speaker", // 播放路径(媒体→扬声器) "media-main-mic", // 采集路径(主麦克风) "playback-off", // 关闭播放时的路径 "capture-off" // 关闭采集时的路径};

路由表route_configs:二维数组,维度为[输入源][输出设备],映射关系如下:

输入源:IN_SOURCE_MIC(麦克风)、IN_SOURCE_CAMCORDER(摄像机)、IN_SOURCE_VOICE_RECOGNITION语音识别)等。

输出设备:OUT_DEVICE_SPEAKER(扬声器)、OUT_DEVICE_HEADSET(耳机)、OUT_DEVICE_BT_SCO(蓝牙SCO)等。

例如:route_configs[IN_SOURCE_MIC][OUT_DEVICE_SPEAKER] = &media_speaker,表示麦克风输入扬声器输出使用media_speaker路由。

3.设备标识配置(硬件匹配列表)

定义了不同类型设备(如扬声器、HDMI、麦克风)的硬件标识列表,用于匹配系统中的实际声卡(通过解析/proc/asound/cards)。

设备列表名称

含义

示例元素(声卡名称)

SPEAKER_OUT_NAME

扬声器输出设备列表

"rockchipcarrk33""realtekrt5616c"codec名称)

HDMI_OUT_NAME

HDMI输出设备列表

"rkhdmidpsound""rockchiphdmi"

SPDIF_OUT_NAME

SPDIF输出设备列表

"ROCKCHIPSPDIF""rockchipspdif"

MIC_IN_NAME

麦克风输入设备列表

"realtekrt5651co""rockchipes8316c"

BT_IN_NAME/BT_OUT_NAME

蓝牙输入/输出设备列表

"rockchipbt"(蓝牙音频设备)

(二)核心函数解析

函数主要围绕设备管理路由控制流操作三大核心功能,实现音频设备的打开、配置、数据传输等流程。

1.设备管理函数

get_output_device_id/get_input_source_id

Android标准音频设备类型(如AUDIO_DEVICE_OUT_SPEAKER)转换为内部ID(如OUT_DEVICE_SPEAKER),用于路由表索引

示例:AUDIO_DEVICE_OUT_SPEAKEROUT_DEVICE_SPEAKER

name_match/is_specified_out_sound_card

设备匹配函数,通过比较声卡名称(从/proc/asound/cards读取)与SPEAKER_OUT_NAME等列表中的标识,确定当前可用硬件设备。

device_lock/device_unlock

线程安全函数,通过互斥锁保护音频设备操作(如流的创建/销毁),避免并发冲突。

2.路由控制函数

getOutputRouteFromDevice/getInputRouteFromDevice

根据输出/输入设备类型获取对应的路由ID(如SPEAKER_NORMAL_ROUTEMAIN_MIC_CAPTURE_ROUTE),用于底层ALSA路由切换。

force_non_hdmi_out_standby

设备冲突处理函数,当HDMI激活时,强制其他输出设备(如扬声器)进入待机状态,避免音频同时从多个设备输出。

3.流操作函数

adev_get_stream_out_by_io_handle_l/adev_get_stream_in_by_io_handle_l

根据IO句柄查找对应的输出/输入流(stream_out/stream_in),用于流的状态管理(如启动、停止)。

adev_add_stream_to_list

将创建的流添加到设备的流列表中,维护流的生命周期(从创建到销毁)。

二、第三方算法集成方案

第三方算法(如降噪、音效增强、回声消除等)需嵌入音频数据流转链路中,核心是在输入数据读取后输出数据写入前插入处理逻辑。

(一)集成位置

1.输入链路(录音)

在麦克风采集的PCM数据被上层应用读取前处理(如降噪)。

对应代码位置:输入流的read回调函数(如stream_in.read),数据从pcm_read获取后,调用算法处理再返回给上层。

2.输出链路(播放)

在上层应用发送的PCM数据写入硬件前处理(如音效增强)。

对应代码位置:输出流的write回调函数(如stream_out.write),数据传入后先调用算法处理,再通过pcm_write写入硬件。

(二)集成步骤

1.算法初始化(设备打开时)

在音频设备打开(如open_output_streamopen_input_stream)时,根据当前PCM配置(pcm_config的采样率、声道数等)初始化算法(如分配缓冲区、设置参数)。

示例:在stream_out创建时,调用algorithm_init(&out->alg, out->pcm_config)

1.数据处理(读写时)

输入链路:在stream_in.read中,pcm_read获取原始数据后,调用algorithm_process_in(alg, pcm_data, processed_data),再返回处理后的数据。

输出链路:在stream_out.write中,接收上层数据后,调用algorithm_process_out(alg, input_data, processed_data),再通过pcm_write输出。

1.资源释放(设备关闭时)

在流停止(stop_output_stream/stop_input_stream)或设备关闭时,调用algorithm_destroy(alg)释放算法占用的内存、线程等资源。

(三)注意事项

数据格式匹配:算法输入输出格式需与PCM配置一致(如采样率、声道数、位深),必要时通过audio_format_convert进行格式转换。

实时性:算法处理耗时需音频帧周期(如period_size/rate,例如44100Hz采样率、256帧周期对应的周期为~5.8ms),避免卡顿。

线程安全:若算法涉及多线程操作,需通过device_lock/device_unlock加锁保护,避免数据竞争。

三、流程图与脑图(文字版)

(一)音频数据流转与算法集成流程图

(二)核心模块与算法集成脑图

wKgZPGkaixaAY45WAAMTsfKQkLQ265.png

通过以上分析,可清晰理解audio_hw.c的核心逻辑及第三方算法的集成方式,实际操作时需根据具体算法接口调整处理逻辑,并严格测试实时性和兼容性。

推荐阅读:

联合育种 中国奶业攻坚“牛芯片”