OpenHarmony Audio子系统全栈解码:从HDI驱动到DSP算法的低延迟高保真之路
音频(Audio)组件用于实现音频相关的功能,包括音频播放,录制,音量管理和设备管理.
基本概念:
采样 采样是指将连续时域上的模拟信号按照一定的时间间隔采样,获取到离散时域上离散信号的过程。
采样率 采样率为每秒从连续信号中提取并组成离散信号的采样次数,单位用赫兹(Hz)来表示。通常人耳能听到频率范围大约在20Hz~20kHz之间的声音。常用的音频采样频率有:8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz、96kHz、192kHz等。
声道 声道是指声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号,所以声道数也就是声音录制时的音源数量或回放时相应的扬声器数量。
音频帧 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的。
PCM PCM(Pulse Code Modulation),即脉冲编码调制,是一种将模拟信号数字化的方法,是将时间连续、取值连续的模拟信号转换成时间离散、抽样值离散的数字信号的过程。
目录
- 系统架构概览
- 核心模块详解
- 关键数据结构
- 配置文件详解
- 函数调用流程
- 常见需求定制
- 常见Bug解决方案
- 调试与监控
系统架构概览
OpenHarmony音频框架采用分层架构设计,主要包含以下层次:
┌─────────────────────────────────────────┐
│ 应用层 │
├─────────────────────────────────────────┤
│ 框架接口层 │
├─────────────────────────────────────────┤
│ 服务层 │
│ ┌─────────────────┐ ┌───────────────┐ │
│ │ AudioServer │ │AudioPolicyServer│ │
│ └─────────────────┘ └───────────────┘ │
├─────────────────────────────────────────┤
│ 引擎层 │
│ ┌─────────────┐ ┌───────────────────┐ │
│ │AudioRenderer│ │ AudioCapturer │ │
│ └─────────────┘ └───────────────────┘ │
├─────────────────────────────────────────┤
│ HDI适配层 │
└─────────────────────────────────────────┘
音频服务组件
1. AudioServer (音频服务)
- 源码位置:
services/audio_service/server/src/audio_server.cpp
- 系统ID:
AUDIO_DISTRIBUTED_SERVICE_ID
- 主要功能:
- 音频渲染和捕获的核心服务
- 管理音频流的生命周期
- 处理音频焦点管理
- 音频效果处理
2. AudioPolicyServer (音频策略服务)
- 源码位置:
services/audio_policy/server/src/audio_policy_server.cpp
- 系统ID:
AUDIO_POLICY_SERVICE_ID
- 主要功能:
- 音频路由策略管理
- 音量控制策略
- 设备切换管理
- 音频场景管理
核心模块详解
音频渲染器 (AudioRenderer)
关键类定义
// 源码位置: frameworks/native/audiorenderer/include/audio_renderer.h
class AudioRenderer {
public:static std::unique_ptr<AudioRenderer> Create(const AudioRendererOptions &options);bool Start();bool Pause();bool Stop();bool Flush();bool Release();// 音频数据写入int32_t Write(const uint8_t *buffer, size_t bufferSize, size_t &bytesWritten);// 音量控制int32_t SetVolume(float volume);float GetVolume();// 音频参数设置int32_t SetAudioStreamInfo(const AudioStreamInfo &info);int32_t SetRendererInfo(const AudioRendererInfo &info);
};
渲染流程
音频捕获器 (AudioCapturer)
关键类定义
// 源码位置: frameworks/native/audiocapturer/include/audio_capturer.h
class AudioCapturer {
public:static std::unique_ptr<AudioCapturer> Create(const AudioCapturerOptions &options);bool Start();bool Stop();bool Release();// 读取音频数据int32_t Read(uint8_t *buffer, size_t bufferSize, size_t &bytesRead);// 设置捕获信息int32_t SetCapturerInfo(const AudioCapturerInfo &info);int32_t GetCapturerInfo(AudioCapturerInfo &info);
};
捕获流程
音频策略管理器 (AudioPolicyManager)
关键接口定义
// 源码位置: frameworks/native/audiopolicy/include/audio_policy_manager.h
class AudioPolicyManager {
public:// 音量控制int32_t SetSystemVolumeLevel(AudioVolumeType volumeType, int32_t volumeLevel);int32_t GetSystemVolumeLevel(AudioVolumeType volumeType);// 设备管理std::vector<std::shared_ptr<AudioDeviceDescriptor>> GetDevices(DeviceFlag deviceFlag);int32_t SelectOutputDevice(sptr<AudioRendererFilter> filter, std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices);// 音频场景int32_t SetAudioScene(AudioScene scene);AudioScene GetAudioScene();// 铃声模式int32_t SetRingerMode(AudioRingerMode ringMode);AudioRingerMode GetRingerMode();
};
关键数据结构
音频流类型枚举
// 源码位置: foundation\multimedia\audio_framework/interfaces/inner_api/native/audiocommon/include/audio_info.h
enum AudioStreamType {STREAM_VOICE_CALL = 0, // 语音通话STREAM_SYSTEM = 1, // 系统声音STREAM_RING = 2, // 铃声STREAM_MUSIC = 3, // 音乐STREAM_ALARM = 4, // 闹钟STREAM_NOTIFICATION = 5, // 通知STREAM_BLUETOOTH_SCO = 6, // 蓝牙SCOSTREAM_ENFORCED_AUDIBLE = 7, // 强制可听STREAM_DTMF = 8, // DTMF拨号音STREAM_TTS = 9, // 文本转语音STREAM_ACCESSIBILITY = 10, // 辅助功能STREAM_VOICE_ASSISTANT = 11, // 语音助手STREAM_ULTRASONIC = 12, // 超声波STREAM_VOICE_MESSAGE = 13, // 语音消息STREAM_VOICE_RING = 14, // 语音铃声STREAM_VOICE_MODEM_COMMUNICATION = 15, // 调制解调器通信STREAM_SYSTEM_ENFORCED = 16, // 系统强制STREAM_VOICE_RECOGNITION = 17, // 语音识别STREAM_MAX
};
音频设备类型枚举
foundation\multimedia\audio_framework\interfaces\inner_api\native\audiocommon\include\audio_device_info.h
enum DeviceType {DEVICE_TYPE_NONE = 0, // 无设备DEVICE_TYPE_EARPIECE = 1, // 听筒DEVICE_TYPE_SPEAKER = 2, // 扬声器DEVICE_TYPE_WIRED_HEADSET = 3, // 有线耳机DEVICE_TYPE_WIRED_HEADPHONES = 4, // 有线头戴式耳机DEVICE_TYPE_BLUETOOTH_SCO = 5, // 蓝牙SCODEVICE_TYPE_BLUETOOTH_A2DP = 6, // 蓝牙A2DPDEVICE_TYPE_HDMI = 7, // HDMIDEVICE_TYPE_USB_DEVICE = 8, // USB设备DEVICE_TYPE_USB_HEADSET = 9, // USB耳机DEVICE_TYPE_USB_ACCESSORY = 10, // USB配件DEVICE_TYPE_DOCK = 11, // 底座DEVICE_TYPE_FM = 12, // FMDEVICE_TYPE_BUILTIN_SPEAKER = 13, // 内置扬声器DEVICE_TYPE_HDMI_ARC = 14, // HDMI ARCDEVICE_TYPE_BLUETOOTH_A2DP_HEADPHONES = 15, // 蓝牙A2DP耳机DEVICE_TYPE_BLUETOOTH_A2DP_SPEAKER = 16, // 蓝牙A2DP扬声器DEVICE_TYPE_HEARING_AID = 17, // 助听器DEVICE_TYPE_MAX
};
音频场景枚举
enum AudioScene {AUDIO_SCENE_DEFAULT = 0, // 默认场景AUDIO_SCENE_RINGING, // 响铃场景AUDIO_SCENE_PHONE_CALL, // 通话场景AUDIO_SCENE_VOICE_CHAT, // 语音聊天AUDIO_SCENE_VIDEO_CHAT, // 视频聊天AUDIO_SCENE_MAX
};
配置文件详解
音频策略配置文件
文件路径
- 主配置文件:
/vendor/etc/audio/audio_policy_config.xml
- 芯片产品配置:
/chip_prod/etc/audio/audio_policy_config.xml
配置结构
<audio_policy_configuration><modules><module name="primary" halVersion="3.0"><attachedDevices><item>Speaker</item><item>WiredHeadset</item><item>BluetoothA2dp</item></attachedDevices><defaultOutputDevice>Speaker</defaultOutputDevice><mixPorts><mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/></mixPort></mixPorts><devicePorts><devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/></devicePort></devicePorts></module></modules>
</audio_policy_configuration>
音频参数配置文件
文件路径
- 主配置文件:
/vendor/etc/audio/audio_param_config.xml
配置结构
<audioParameters><mainKeys><mainKey name="volume"><subKeys><subKey name="music"><usecases><usecase name="speaker"><parameter name="volume" value="0.5"/></usecase></usecases></subKey></subKeys></mainKey></mainKeys>
</audioParameters>
函数调用流程
音频播放完整流程
音频设备切换流程
常见需求定制
1. 添加新的音频流类型
修改位置
interfaces/inner_api/native/audiocommon/include/audio_info.h
services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp
实现步骤
- 在
audio_info.h
中添加新的流类型枚举值 - 在配置文件中添加对应的音量曲线配置
- 更新策略配置文件中的流映射关系
// 示例:添加STREAM_CUSTOM类型
enum AudioStreamType {// ... 现有类型STREAM_CUSTOM = 18, // 自定义类型STREAM_MAX
};
2. 自定义音量曲线
修改位置
services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp
- 配置文件:
/vendor/etc/audio/audio_policy_config.xml
实现步骤
- 在配置文件中添加音量曲线定义
- 更新对应的流类型映射
<volumeCurves><volumeCurve stream="STREAM_CUSTOM"><point>0,0</point><point>1,33</point><point>2,66</point><point>3,100</point></volumeCurve>
</volumeCurves>
3. 添加新的音频设备
修改位置
interfaces/inner_api/native/audiocommon/include/audio_info.h
services/audio_policy/server/src/device/audio_device_manager.cpp
- HDI适配层代码
实现步骤
- 定义新的设备类型枚举
- 实现设备检测逻辑
- 更新设备能力配置
- 添加路由策略
4. 自定义音频效果
修改位置
frameworks/native/audioeffect/include/audio_effect.h
services/audio_service/server/src/effect/audio_effect_server.cpp
实现步骤
- 定义新的效果类型
- 实现效果处理算法
- 注册到效果框架
- 配置效果参数
常见Bug解决方案
1. 音频播放无声问题
排查步骤
-
检查音频焦点
// 源码位置: services/audio_policy/server/src/service/audio_policy_service.cpp bool AudioPolicyService::IsStreamActive(AudioStreamType streamType)
-
验证音量设置
// 源码位置: services/audio_policy/server/src/service/audio_policy_service.cpp int32_t AudioPolicyService::GetSystemVolumeLevel(AudioVolumeType volumeType)
-
检查设备状态
// 源码位置: services/audio_policy/server/src/device/audio_device_manager.cpp bool AudioDeviceManager::IsDeviceActive(DeviceType deviceType)
常见原因
- 音频焦点被其他应用占用
- 音量被设置为0或静音
- 输出设备选择错误
- 音频路由配置错误
2. 音频录制失败问题
排查步骤
-
检查权限
- 确认应用具有
ohos.permission.MICROPHONE
权限 - 检查隐私设置中的麦克风权限
- 确认应用具有
-
验证设备状态
// 源码位置: services/audio_policy/server/src/device/audio_device_manager.cpp std::vector<std::shared_ptr<AudioDeviceDescriptor>> AudioDeviceManager::GetDevices(DeviceFlag deviceFlag)
-
检查音频策略
// 源码位置: services/audio_policy/server/src/service/audio_policy_service.cpp bool AudioPolicyService::IsMicrophoneMute()
常见原因
- 权限被拒绝
- 麦克风被其他应用占用
- 麦克风被系统静音
- 录制参数设置错误
3. 音频设备切换异常
排查步骤
-
检查设备监听
// 源码位置: services/audio_policy/server/src/device/audio_device_manager.cpp void AudioDeviceManager::RegisterDeviceStatusListener()
-
验证路由策略
// 源码位置: services/audio_policy/server/src/router/audio_router_center.cpp int32_t AudioRouterCenter::RouteDeviceChange(DeviceType deviceType, bool isConnected)
-
检查焦点处理
// 源码位置: services/audio_policy/server/src/interrupt/audio_interrupt_service.cpp int32_t AudioInterruptService::HandleDeviceChange(DeviceType deviceType)
4. 音频延迟过高
优化方案
-
使用低延迟模式
// 源码位置: frameworks/native/audiorenderer/src/audio_renderer_impl.cpp bool AudioRendererImpl::IsFastPlaybackSupported(AudioStreamInfo &streamInfo, StreamUsage usage)
-
优化缓冲区大小
// 源码位置: services/audio_service/server/src/audio_stream.cpp int32_t AudioStream::GetFrameCount() const
-
调整线程优先级
// 源码位置: services/audio_service/server/src/audio_schedule.cpp void ScheduleThreadInServer(pid_t pid, pid_t tid)
调试与监控
1. 音频调试开关
开启PCM数据dump
# 设置环境变量
export PCM_DUMP=1
export PCM_DUMP_PATH=/data/local/tmp/audio_dump
开启详细日志
# 设置系统参数
hilog -T audio_server -L DEBUG
hilog -T audio_policy -L DEBUG
2. 性能监控
监控音频延迟
// 源码位置: frameworks/native/audiorenderer/include/audio_timestamp.h
struct Timestamp {int64_t tvSec; // 秒int64_t tvNSec; // 纳秒Timebase base; // 时间基
};
监控CPU使用率
# 使用top命令监控top -p $(pidof audio_server)
top -p $(pidof audio_policy)
3. 调试工具
音频策略调试
# 查看音频策略状态
hidumper -s audio_policy_server -a -p
音频服务调试
# 查看音频服务状态
hidumper -s audio_server -a -p
4. 常见问题诊断命令
检查音频服务状态
# 检查服务是否运行
aa dump -a audio_server
aa dump -a audio_policy
查看音频设备
# 查看当前音频设备
hidumper -s audio_policy_server -a -d
检查音频路由
# 查看当前音频路由
hidumper -s audio_policy_server -a -r
附录
A. 相关源码路径
模块 | 路径 | 说明 |
---|---|---|
AudioServer | services/audio_service/ | 音频服务主目录 |
AudioPolicy | services/audio_policy/ | 音频策略服务 |
AudioRenderer | frameworks/native/audiorenderer/ | 音频渲染器 |
AudioCapturer | frameworks/native/audiocapturer/ | 音频捕获器 |
AudioPolicyManager | frameworks/native/audiopolicy/ | 音频策略管理器 |
AudioCommon | interfaces/inner_api/native/audiocommon/ | 公共接口定义 |
B. 配置文件路径
配置文件 | 路径 | 说明 |
---|---|---|
audio_policy_config.xml | /vendor/etc/audio/ | 音频策略配置 |
audio_param_config.xml | /vendor/etc/audio/ | 音频参数配置 |
audio_policy_config.xml | /chip_prod/etc/audio/ | 芯片产品配置 |
C. 调试日志标签
组件 | 日志标签 | 说明 |
---|---|---|
AudioServer | AudioServer | 音频服务日志 |
AudioPolicyServer | AudioPolicyServer | 音频策略日志 |
AudioRenderer | AudioRendererImpl | 音频渲染器日志 |
AudioCapturer | AudioCapturerImpl | 音频捕获器日志 |
D. 系统权限
权限 | 说明 |
---|---|
ohos.permission.MICROPHONE | 麦克风访问权限 |
ohos.permission.CAPTURE_AUDIO_OUTPUT | 音频输出捕获权限 |
ohos.permission.MODIFY_AUDIO_SETTINGS | 修改音频设置权限 |
ohos.permission.MANAGE_AUDIO_CONFIG | 管理音频配置权限 |