OpenHarmony 源码解析之多媒体子系统(音频框架一)

您所在的位置:网站首页 鸿蒙系统怎么切换播放器 OpenHarmony 源码解析之多媒体子系统(音频框架一)

OpenHarmony 源码解析之多媒体子系统(音频框架一)

2024-07-03 10:38| 来源: 网络整理| 查看: 265

作者:苑春鸽

1 简介

本文档基于 OpenHarmony 3.0-LTS 源码的轻量系统、小型系统编写

因鸿蒙系统目前处在快速发展时期,本文中的一些内容可能会过时,建议在阅读的同时参考最新代码以了解更实时的知识。

音频采集是多媒体系统中最基础最重要的部分之一,OpenHarmony audio_lite 框架有着丰富的音频采集功能,支持麦克风、电话、摄像机等多种音频输入源设备,支持PCM、AAC_LC、AAC_HE_V1等多种编解码格式,支持闹钟、音乐、铃声等多种音频流类型以及满足不同品质的音频数据需求。

1.1 多媒体子系统源码系列

【OpenHarmony 源码解析之多媒体子系统(camera) 】

【OpenHarmony 源码解析之多媒体子系统(音频框架一)】

1.2 OpenHarmony架构图

OpenHarmony 源码解析之多媒体子系统(音频框架一) -鸿蒙开发者社区

1.3 架构图

OpenHarmony 源码解析之多媒体子系统(音频框架一) -鸿蒙开发者社区

1.4 文件目录 ~/foundation/multimedia/audio_lite$ tree ├── frameworks # 框架代码 │   ├── audio_capturer.cpp # 音频采集 │   ├── audio_capturer_impl.cpp │   ├── audio_capturer_impl.h │   ├── audio_encoder # 音频编解码 │   │   ├── audio_encoder.cpp │   │   └── include │   │   └── audio_encoder.h │   └── audio_source # 音频输入源 │      ├── audio_source.cpp │      └── include │      └── audio_source.h └── interfaces # 接口    └── kits # 对外接口    └── audio_capturer.h 2 环境准备 2.1 开发环境、编译环境搭建

参考官方文档,参考链接如下:搭建Ubuntu环境(获取源码及编译,Docker方式)

3 音频采集

OpenHarmony 源码解析之多媒体子系统(音频框架一) -鸿蒙开发者社区

3.1 音频信息采集流程

初始化

通过AudioCapturer调用AudioCapturerImpl中的SetCapturerInfo方法,初始化采集状态,获取适配输入源类型的设备,配置并初始化输入源,编解码等

int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInfo info) { ... // 判断采集状态初始化 if (status_ != INITIALIZED) { MEDIA_ERR_LOG("check state:%u failed", status_); return ERR_ILLEGAL_STATE; } // 获取设备 std::vector devices; int32_t ret = audioSource_->EnumDeviceBySourceType(info.inputSource, devices); ... // 配置输入源参数并初始化 AudioSourceConfig sourceConfig; sourceConfig.deviceId = devices[0].deviceId; ... ret = audioSource_->Initialize(sourceConfig); ... // 配置编解码参数并初始化 AudioEncodeConfig encodeConfig; encodeConfig.audioFormat = info.audioFormat; ... ret = audioEncoder_->Initialize(encodeConfig); ... return SUCCESS; }

开始音频采集

调用AudioCapturerImpl中的Record方法检查采集状态,开始采集音频,绑定音频源到当前设备并开始编解码

bool AudioCapturer::AudioCapturerImpl::Record() { ... // 开始采集音频源 int32_t ret = audioSource_->Start(); ... // 获取当前设备Id ret = audioSource_->GetCurrentDeviceId(deviceId); ... // 绑定音频源到当前设备 ret = audioEncoder_->BindSource(deviceId); ... // 开始编解码 ret = audioEncoder_->Start(); ... return true; }

获取音频数据

在满足采集状态等的条件下,通过传出参数buffer获取音频数据,如果编解码格式为“PCM”或者是缺省值,则直接获取音频数据,否则进行编解码获取音频数据

int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) { ... // 音频帧方式 if (info_.audioFormat == PCM || info_.audioFormat == AUDIO_DEFAULT) { AudioFrame frame; ... readLen = audioSource_->ReadFrame(frame, isBlockingRead); ... } else { //音频流方式 AudioStream stream; ... readLen = audioEncoder_->ReadStream(stream, isBlockingRead); ... } return readLen; } 3.2 音频相关结构体 // audio_capturer.h // 音频采集信息 struct AudioCapturerInfo { AudioSourceType inputSource = AUDIO_MIC; // 音频源类型 AudioCodecFormat audioFormat = AUDIO_DEFAULT; // 编解码格式 int32_t sampleRate = 0; // 采样率 int32_t channelCount = 0; // 通道数 int32_t bitRate = 0; // 码率 AudioStreamType streamType = TYPE_MEDIA; // 音频流类型 AudioBitWidth bitWidth = BIT_WIDTH_16; // 采样位宽 }; // 采集状态 enum State : uint32_t { INITIALIZED, // 初始化 PREPARED, // 准备 RECORDING, // 采集中 STOPPED, // 停止 RELEASED // 销毁 }; // audio_encoder.h // 音频编解码配置 struct AudioEncodeConfig { AudioCodecFormat audioFormat;//音频格式 uint32_t bitRate = 0;//码率 uint32_t sampleRate = 0;//采样率 uint32_t channelCount = 0;//通道数量 AudioBitWidth bitWidth = BIT_WIDTH_16;//采样位宽 }; // audio_source.h struct AudioSourceConfig { uint32_t deviceId;//设备Id AudioCodecFormat audioFormat;//音频格式 int32_t sampleRate = 0;//采样率 int32_t channelCount = 0;//通道数量 bool interleaved; AudioBitWidth bitWidth = BIT_WIDTH_16;//音频位宽 AudioStreamType streamUsage;//音频流类型 }; // ~/foundation/multimedia/utils/lite/interfaces/kits/media_info.h // 音频输入源类型 typedef enum { AUDIO_SOURCE_INVALID = -1, // 无效的音频源 AUDIO_SOURCE_DEFAULT = 0, // 默认的音频源 AUDIO_MIC = 1, // 麦克风 AUDIO_VOICE_UPLINK = 2, // 电话上行 AUDIO_VOICE_DOWNLINK = 3, // 电话下行 AUDIO_VOICE_CALL = 4, // 电话含上下行 AUDIO_CAMCORDER = 5, // 摄像机音频源 AUDIO_VOICE_RECOGNITION = 6, // 语音识别 AUDIO_VOICE_COMMUNICATION = 7, // 电话通信 AUDIO_REMOTE_SUBMIX = 8, // 远程设备输入音频源 AUDIO_UNPROCESSED = 9, // 未被处理的音频源 AUDIO_VOICE_PERFORMANCE = 10, // 声乐 AUDIO_ECHO_REFERENCE = 1997, // 回声 AUDIO_RADIO_TUNER = 1998, // 广播调谐器 AUDIO_HOTWORD = 1999, AUDIO_REMOTE_SUBMIX_EXTEND = 10007, // 扩展的远程设备输入音频源 } AudioSourceType; // 音频设备描述 typedef struct { std::string deviceName; // 设备名称 AudioSourceType inputSourceType; // 音频输入源的类型 uint32_t deviceId; // 31-24位:保留位; bits 23-16:模式ID; 15-8:设备ID; 7-0:通道ID } AudioDeviceDesc; // 音频流类型 typedef enum { TYPE_DEFAULT = -1, // 默认类型 TYPE_MEDIA = 0, // 媒体 TYPE_VOICE_COMMUNICATION = 1, // 语音电话 TYPE_SYSTEM = 2, // 系统声音 TYPE_RING = 3, // 手机铃声 TYPE_MUSIC = 4, // 音乐 TYPE_ALARM = 5, // 闹钟 TYPE_NOTIFICATION = 6, // 通知声音 TYPE_BLUETOOTH_SCO = 7, // 蓝牙同步面向连接 TYPE_ENFORCED_AUDIBLE = 8, // 强制提示音 TYPE_DTMF = 9, // 双音多频 TYPE_TTS = 10, // 文本转语音 TYPE_ACCESSIBILITY = 11, // 辅助提示音 } AudioStreamType; // 音频编解码格式 typedef enum { AUDIO_DEFAULT = 0, PCM = 1, AAC_LC = 2, AAC_HE_V1 = 3, AAC_HE_V2 = 4, AAC_LD = 5, AAC_ELD = 6, G711A = 7, G711U = 8, G726 = 9, FORMAT_BUTT, } AudioCodecFormat; // 采样位宽 typedef enum { BIT_WIDTH_8 = 8, BIT_WIDTH_16 = 16, BIT_WIDTH_24 = 24, BIT_WIDTH_32 = 32, BIT_WIDTH_BUTT, } AudioBitWidth; 3.3 音频相关接口 类名 接口名 描述 AudioCapturer static bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, size_t &frameCount); 获取最小帧数 AudioCapturer uint64_t GetFrameCount() 获取当前条件下所需的帧数 AudioCapturer int32_t SetCapturerInfo(const AudioCapturerInfo info) 设置采集参数 AudioCapturer int32_t GetCapturerInfo(AudioCapturerInfo &info) 获取采样参数 AudioCapturer bool Start() 开始采集 AudioCapturer int32_t Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) 读取音频数据 AudioCapturer State GetStatus() 获取采集状态 AudioCapturer bool GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base) 获取时间戳 AudioCapturer bool Stop() 停止采集 AudioCapturer bool Release() 销毁 AudioEncoder int32_t Initialize(const AudioEncodeConfig &config) 根据给定的配置初始化音频源 AudioEncoder int32_t BindSource(uint32_t deviceId) 绑定音频源到给定的设备 AudioEncoder int32_t GetMute(bool &muted) 获取当前编码器的静音状态 AudioEncoder int32_t SetMute(bool muted) 设置当前编码器的静音状态 AudioEncoder int32_t Start() 开始 AudioEncoder int32_t ReadStream(AudioStream &stream, bool isBlockingRead) 读取音频流 AudioEncoder int32_t Stop() 停止 AudioEncoder int32_t Release() 销毁 AudioSource int32_t EnumDeviceBySourceType(AudioSourceType inputSource, std::vector &devices) 当前音频源类型支持的设备 AudioSource static bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, size_t &frameCount) 获取指定条件下的最小帧数 AudioSource uint64_t GetFrameCount() 获取当前配置条件下的帧数 AudioSource int32_t Initialize(const AudioSourceConfig &config) 根据给定的配置参数初始化 AudioSource int32_t SetInputDevice(uint32_t deviceId) 设置切换设备时输入设备的标识 AudioSource int32_t GetCurrentDeviceId(uint32_t &deviceId) 获取当前设备Id AudioSource int32_t Start() 开始 AudioSource int32_t ReadFrame(AudioFrame &frame, bool isBlockingRead) 读取源数据帧 AudioSource int32_t Stop() 停止 AudioSource int32_t Release() 销毁 4 总结

Audio是多媒体中重要的组成部分,对于系统开发者和应用开发者来说,都很有必要去深入了解。

对于想进一步了解的同学们,敬请期待我们后续将要分享的 《OpenHarmony 源码解析之多媒体子系统(音频框架 L2)》,在这篇我们会进一步的进行分析。

更多原创内容请关注:开鸿 HarmonyOS 学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3