当前位置: 首页 > news >正文

OpenHarmony海思WS63星闪平台:Opus 音频编解码库介绍与海思 WS63 平台移植

文章目录

    • 前言
    • 1. Opus 是什么?
      • 1.1 定位与标准
      • 1.2 主要能力(摘自公开说明与 `opus/include/opus.h` 文档)
      • 1.3 库对外 API 轮廓
      • 1.4 与本仓库 `opus/` 目录的关系
    • 2. 本工程中的 Opus 与音频业务
      • 2.1 目录结构(与移植相关部分)
      • 2.2 应用侧示例:CI1302 Opus 解码
    • 3. WS63 平台特点与移植目标
    • 4. 编译与集成方式
      • 4.1 方式 A:海思 SDK / `build_component`(推荐,与本仓库 CMakeLists 一致)
      • 4.2 方式 B:独立 CMake 子工程 / 交叉编译
      • 4.3 方式 C:GN(`BUILD.gn`)静态库
    • 5. 头文件与链接检查清单
    • 6. 内存与实时性建议
    • 7. 功能验证建议
    • 8. 常见问题
    • 9. 参考链接
    • 总结

前言

Opus是互联网语音与音频场景中最常用的开放编解码器之一,适合 VoIP、对讲、语音播报、流媒体等。海思 WS63一类 IoT SoC 常跑LiteOS / OpenHarmony 衍生内核,RAM 与 CPU 有限,需要在「功能完整」与「体积/内存」之间做裁剪。本仓库已在项目根目录提供opus/源码树,且其中的opus/CMakeLists.txt已按海思 SDK 组件(build_component风格编写,便于与 WS63 工程链对接。

本文说明 Opus是什么、能做什么,并结合本仓库布局给出在WS63 工程编译集成、链接与使用的实操要点(含与本项目ci1302Opus 解码示例的衔接)。


1. Opus 是什么?

Opus 是一款完全开放、免版税且功能强大的音频编解码器。它在互联网上的交互式语音和音乐传输方面无可匹敌,同时也适用于存储和流媒体应用。它由互联网工程任务组 (IETF) 制定为RFC 6716标准 ,该标准融合了 Skype 的 SILK 编解码器和 Xiph.Org 的 CELT 编解码器的技术。

1.1 定位与标准

  • IETF RFC 6716定义了 Opus 比特流格式与解码过程。
  • 实现融合了Skype SILK(语音)与Xiph CELT(通用音频)两条技术路线,由IETF Codec 工作组标准化。
  • github地址:https://github.com/xiph/opus
  • 官方资料与下载:https://opus-codec.org/

1.2 主要能力(摘自公开说明与opus/include/opus.h文档)

维度典型范围
采样率8 kHz~48 kHz
帧长2.5 ms~60 ms(多种离散长度)
声道单声道、立体声,以及多流 API 下的多声道场景
码率约 6 kb/s~510 kb/s(与模式/帧长有关)
特性语音与音乐、CBR/VBR、丢包隐藏(PLC)等

1.3 库对外 API 轮廓

嵌入式最常用的是解码(播放 TTS、网络语音)或编码(上行录音):

  • 解码opus_decoder_create/opus_decoder_initopus_decodeopus_decoder_destroy(或仅init配合静态缓冲,见下文)。
  • 编码opus_encoder_createopus_encodeopus_encoder_destroy
  • 头文件入口:opus.h(内部包含opus_types.hopus_defines.h)。

比特流若走RTP,需遵守RFC 7587;若存文件,通常用Ogg 封装(RFC 7845),需额外opusfile/libogg等,与本仓库「裸 Opus 帧」解码场景不同。

1.4 与本仓库opus/目录的关系

  • 根目录opus/Xiph 官方 Opus 参考实现的完整源码树(含celt/silk/dnn/等)。
  • 上游版本号由opus/cmake/OpusPackageVersion.cmake等解析;本仓库opus/CMakeLists.txt在无法读取版本时回退为 1.5.2,与常见 HiSilicon 集成版本一致。
  • 与上游唯一显著差异:根目录opus/CMakeLists.txt不是通用add_library(opus …),而是为海思build_component()准备的组件描述(源列表来自*_sources.mk,生成config.h)。在非海思构建系统中需自行等价实现(见第 4 节)。

2. 本工程中的 Opus 与音频业务

2.1 目录结构(与移植相关部分)

opus/ ├── CMakeLists.txt # 海思 LiteOS 组件式构建(本仓库已提供) ├── cmake/ │ ├── config.h.cmake.in # 生成 config.h 的模板 │ └── … ├── include/ # 对外头文件:opus.h 等 ├── celt/、silk/、src/ # 编解码核心实现 ├── *_sources.mk # 参与编译的源文件列表(由 CMakeLists 读取) └── …

2.2 应用侧示例:CI1302 Opus 解码

src/audio/ci1302/中,当宏CI1302_TTS_DECODE_OPUS_TO_PCM打开时,会编译ci1302_opus_decode.c,通过opus.h调用解码接口,将 Opus 帧解为 PCM。该实现刻意使用opus_decoder_get_size+opus_decoder_init+ 静态缓冲,避免在堆很小的 LiteOS上频繁opus_decoder_create导致OPUS_ALLOC_FAIL

未链接真实 libopus 时,可用ci1302_opus_decoder_weak_stub.c提供弱符号占位,便于分阶段联调。

结论:WS63 上「移植 Opus」在工程层面的落点是:opus/编成静态库并链到最终镜像,保证#include "opus.h"与链接符号解析成功。


3. WS63 平台特点与移植目标

  • WS63为海思面向连接类 IoT 的芯片平台,软件栈常见LiteOS-M + CMSIS-RTOS2 + 厂商驱动,构建可能是GN(OpenHarmony 系)CMake +build_component
  • 无 MMU 或资源紧张时,建议:
    • 使用与本仓库opus/CMakeLists.txt一致的OPUS_DISABLE_INTRINSICS等选项,避免依赖难以在 MCU 上统一验证的 SIMD/内联汇编路径;
    • 解码器状态尽量静态分配或可控堆,避免与 WiFi 等任务抢堆导致LOS_TaskCreate失败(与ci1302_opus_decode.c注释一致)。

4. 编译与集成方式

CMakeLists文件:

#===============================================================================# @brief cmake file — Opus 静态库(LiteOS / HiSilicon SDK build_component 集成)# @details 风格对齐 open_source/lvgl/CMakeLists.txt;源文件列表与上游 silk/celt/opus 的 .mk 保持一致。# 与 ESP-IDF 工程(如 xiaozhi-esp32/main/CMakeLists.txt 中 esp_audio_codec 链 libopus)# 为两套集成方式,本文件仅用于 sdkv106 中 LiteOS 组件构建。# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.#===============================================================================set(COMPONENT_NAME"opus")set(CMAKE_OPUS_SOURCE_DIR${CMAKE_CURRENT_SOURCE_DIR})list(APPEND CMAKE_MODULE_PATH"${CMAKE_OPUS_SOURCE_DIR}/cmake")include(OpusFunctions)include(OpusPackageVersion)get_package_version(PACKAGE_VERSION PROJECT_VERSION)if(NOT PACKAGE_VERSION OR PACKAGE_VERSION STREQUAL"0")set(PACKAGE_VERSION"1.5.2")endif()configure_file(${CMAKE_OPUS_SOURCE_DIR}/cmake/config.h.cmake.in${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY)get_opus_sources(SILK_SOURCES${CMAKE_OPUS_SOURCE_DIR}/silk_sources.mk silk_sources_rel)get_opus_sources(SILK_SOURCES_FLOAT${CMAKE_OPUS_SOURCE_DIR}/silk_sources.mk silk_sources_float_rel)get_opus_sources(CELT_SOURCES${CMAKE_OPUS_SOURCE_DIR}/celt_sources.mk celt_sources_rel)get_opus_sources(OPUS_SOURCES${CMAKE_OPUS_SOURCE_DIR}/opus_sources.mk opus_sources_rel)get_opus_sources(OPUS_SOURCES_FLOAT${CMAKE_OPUS_SOURCE_DIR}/opus_sources.mk opus_sources_float_rel)set(SOURCES"")foreach(src${silk_sources_rel}${silk_sources_float_rel}${celt_sources_rel}${opus_sources_rel}${opus_sources_float_rel})list(APPEND SOURCES"${CMAKE_OPUS_SOURCE_DIR}/${src}")endforeach()set(PUBLIC_HEADER${CMAKE_OPUS_SOURCE_DIR}/include)set(PRIVATE_HEADER${CMAKE_OPUS_SOURCE_DIR}${CMAKE_OPUS_SOURCE_DIR}/celt${CMAKE_OPUS_SOURCE_DIR}/silk${CMAKE_OPUS_SOURCE_DIR}/silk/float${CMAKE_CURRENT_BINARY_DIR})set(COMPONENT_PUBLIC_CCFLAGS)set(COMPONENT_CCFLAGS -Wno-jump-misses-init -Wno-error=unused-parameter -Wno-error=sign-compare)# 与上游 CMake 默认接近:C99 变长数组、关闭 SIMD/内联汇编路径(适合 Cortex-M 等无 x86/NEON 运行时检测环境)# HAVE_LRINT / HAVE_LRINTF:避免 celt/float_cast.h 走 #else 里的 #warning(与 cmake/OpusConfig.cmake 中 check_symbol_exists 一致)set(PRIVATE_DEFINES HAVE_CONFIG_H OPUS_BUILD VAR_ARRAYS OPUS_DISABLE_INTRINSICS DISABLE_DEBUG_FLOAT ENABLE_HARDENING HAVE_LRINT HAVE_LRINTF)set(WHOLE_LINKtrue)set(MAIN_COMPONENTfalse)set(LIB_OUT_PATH${BIN_DIR}/${CHIP}/libs/${TARGET_COMMAND})build_component()

4.1 方式 A:海思 SDK /build_component(推荐,与本仓库 CMakeLists 一致)

若父工程已支持海思build_component()(与open_source中 LVGL、opus 等组件相同模式):

  1. opus/置于 SDK 约定的open_source/opus或工程内等价路径。
  2. 确保opus/CMakeLists.txt被组件扫描到,configure_file能在CMAKE_CURRENT_BINARY_DIR生成config.h
  3. PRIVATE_DEFINES(本仓库已设)通常包括:
    • HAVE_CONFIG_HOPUS_BUILD
    • VAR_ARRAYS(C99 变长数组,需工具链支持)
    • OPUS_DISABLE_INTRINSICS
    • DISABLE_DEBUG_FLOATENABLE_HARDENING
    • HAVE_LRINTHAVE_LRINTF(与float_cast.h行为一致,避免多余 warning)
  4. PUBLIC_HEADER指向opus/include,业务模块include 目录增加该路径(或拷贝生成的config.h可见路径)。
  5. 最终静态库WHOLE_LINK等由build_component()处理,应用链接时-lopus或等价组件依赖即可。

4.2 方式 B:独立 CMake 子工程 / 交叉编译

若需在 PC 上先验证 ARM 静态库:

cdopusmkdirbuild&&cdbuild cmake..-DCMAKE_TOOLCHAIN_FILE=/path/to/arm-none-eabi.cmake\-DCMAKE_BUILD_TYPE=Release\-DBUILD_SHARED_LIBS=OFF\-DOPUS_BUILD_PROGRAMS=OFF\-DOPUS_BUILD_TESTING=OFF cmake--build.

说明:上游官方opus/CMakeLists.txt(若与本文档「海思定制版」不同)选项名可能为OPUS_FIXED_POINTOPUS_FLOAT_APPROX等,需以当前树内CMakeLists.txtcmake/OpusConfig.cmake为准。本仓库根目录opus/CMakeLists.txt不采用通用add_library,直接cmake ..可能需改用官方 release 包自行写add_library包装*_sources.mk

4.3 方式 C:GN(BUILD.gn)静态库

当前xiaohongBUILD.gn若尚未列出opus源文件,可新增static_library("opus")

  • sources:需与silk_sources.mkcelt_sources.mkopus_sources.mk及 float 列表一致,或写脚本从.mk生成 GN 列表(维护成本较高)。
  • defines:与opus/CMakeLists.txtPRIVATE_DEFINES对齐,并保证config.h在 include 路径中(可预生成后include_dirs += ["//path/to/opus/build_gen"])。
  • include_dirsopusopus/celtopus/silkopus/silk/float、生成config.h的目录

5. 头文件与链接检查清单

步骤说明
头文件添加opus/include;若编译报config.hmissing,检查是否执行了configure_file或手动放置生成结果。
符号确认最终 elf/map 中含opus_decodeopus_decoder_init等,而非仅弱符号桩。
重复定义同时链SDK 自带 opus与本仓库opus会冲突,应二选一
浮点WS63 工具链若使用硬浮点 ABI,需全工程一致;Opus 本树含float 路径源(见*_float_rel),与DISABLE_DEBUG_FLOAT等宏共同决定行为。

6. 内存与实时性建议

  • 解码器状态opus_decoder_get_size(channels)给出单实例所需字节数;单声道常见约十几 KB 量级(随版本与宏略变),ci1302_opus_decode.c使用20 KiB 静态区opus_decoder_init,避免堆碎片。
  • opus_decode内部有一定栈深度,解码任务栈不宜过小(建议≥ 2~4 KB起步,以实测为准)。
  • CPU:48 kHz、20 ms 帧在无 NEON 的 Cortex-M上仍可能占用可观 MIPS,需在目标板上profiling
  • DNN / LPCNet:新版 Opus 含深度学习扩展(如 DRED),嵌入式若不需要,应通过源列表 / CMake 选项关闭相关编译单元以减体积(具体以当前opus_sources.mk与构建脚本为准)。

7. 功能验证建议

  1. 单元级:在板端调用opus_decoder_initopus_decode,输入已知 Opus 测试帧(可由 PCopus_demo生成),检查返回值是否为样本数、PCM 是否合理
  2. 业务级:打开CI1302_TTS_DECODE_OPUS_TO_PCM,走CI1302 TTS 管线,听音并观察CPU 占用与欠载
  3. 异常:若返回OPUS_ALLOC_FAIL (-7),优先检查堆与静态缓冲策略,与ci1302_opus_decode.c设计对齐。

8. 常见问题

现象可能原因处理方向
找不到config.h未运行configure_file或未加入 include 路径opus/CMakeLists.txt生成并包含CMAKE_CURRENT_BINARY_DIR
链接 undefined reference未链 opus 静态库或源列表不全检查WHOLE_LINK、GNdeps
弱符号桩一直打印未链真实 libopus移除桩或调整链接顺序,确保强符号覆盖
解码杂音/失败采样率/声道与流不一致opus_decoder_initFs、channels与编码端一致
RAM 暴涨多路create或堆分配过多单实例 +opus_decoder_ctl限制+ 静态缓冲

9. 参考链接

  • Opus 官网:https://opus-codec.org/
  • RFC 6716:https://www.rfc-editor.org/rfc/rfc6716
  • RTP 封装 RFC 7587:https://www.rfc-editor.org/rfc/rfc7587
  • Ogg Opus RFC 7845:https://www.rfc-editor.org/rfc/rfc7845
  • 上游仓库(GitLab):https://gitlab.xiph.org/xiph/opus
  • 本仓库opus/cmake/README.md:通用 CMake 构建说明(与海思组件 CMake 并存时以根目录opus/CMakeLists.txt为准)

总结

Opus是 RFC 标准化的低延迟音频编解码库,适合 WS63 上的语音对讲、播报与网络音频。本仓库opus/已含完整源码面向海思 LiteOSbuild_componentCMakeLists.txt,移植核心是:生成config.h、编译全量mk所列源文件、导出include、与业务(如ci1302_opus_decode.c)正确链接。在RAM 紧张场景下,优先采用opus_decoder_init+ 静态工作区,并控制仅链接一份 Opus、避免与 SDK 重复集成。按第 7 节在板端做解码与听音验证后,再投入量产参数(帧长、码率、任务优先级)。

http://www.cnnetsun.cn/news/1501763.html

相关文章:

  • OpenClaw安全指南:百川2-13B-4bits模型权限管控与操作审计
  • 从零到一!LangChain入门+企业RAG实战,手把手教你搭企业知识库
  • 内容访问优化工具:突破信息壁垒的开源解决方案
  • w3x2lni:魔兽地图格式转换工具深度解析与技术实现
  • AI Agent技能大揭秘!让产品经理升档,大厂Offer手到擒来!
  • 智能体开发:基于《新概念英语》第一册课头的短视频自动生成系统
  • Orleans分布式追踪终极指南:Jaeger与Zipkin深度对比分析
  • 博士延毕,导师连坐,这项新规一出,网友直呼早该这样了,治标又治本 !
  • FLUX.1-dev-fp8-dit文生图+SDXL_Prompt风格效果展示:低光照/夜景/霓虹灯风格生成
  • Windows控制器模拟技术详解:ViGEmBus驱动全方位应用指南
  • 具身智能中的传感器技术6——感知技术概述0
  • MinerU开源大模型落地实践:财务报表自动解析与关键数据抽取
  • 多分类问题避坑指南:为什么我的OVR模型准确率比OVO低?
  • RMBG-1.4动态演示:AI净界处理长发人物的流畅抠图过程
  • MathType公式对齐终极指南:从菜单操作到快捷键全解析(含实战演示)
  • Debian离线更新终极方案:apt-offline零网络环境部署指南
  • 动手学习深度学习学习笔记(一)
  • 深入理解 Django REST Framework 的 Serializer(上)
  • 【AI总结】【技术总结】深入剖析编程语言的分类:运行时语言 vs 编译型语言
  • 拒绝Token无效消耗 蚂蚁数科推出百灵企业版金融大模型
  • OpenClaw 勾搭 Qwen 官方 OAuth 全攻略:从新手村到实战大牛
  • 如何用智能工具重塑英雄联盟体验:League-Toolkit全场景应用指南
  • 贝叶斯岭回归实战:用Python搞定金融数据预测(附完整代码)
  • AI大模型评测避坑指南:读懂这5大维度4类方法,告别跑分陷阱,精准选型落地
  • 告别单调!用这招让你的VSCode Markdown标题五彩斑斓(2023最新配置)
  • 快速原型:用快马AI一键生成Win11右键菜单恢复工具脚本
  • iOS-通用链接link的作用
  • 实时屏幕翻译:打破语言壁垒的跨场景解决方案
  • Vue.Draggable:告别拖拽焦虑,三分钟解锁丝滑交互体验
  • 永磁同步电机双矢量模型预测电流MPCC控制仿真:传统与现代控制策略的对比分析