跳到主要内容

TTS应用说明

修订记录

修订版本修订日期修订说明
0012026-07-10初始版本

概述

本地语音合成(TTS)应用基于 sherpa-onnx 推理框架,在 OpenHarmony 设备上实现完全离线的文字转语音功能。使用 Matcha-TTS 声学模型 + Vocos 声码器,支持中英文混合合成。

平台支持情况

平台 & 系统是否支持
K1 OpenHarmony5.0❌ 不支持
K1 OpenHarmony6.1✅ 支持
K3 OpenHarmony6.1✅ 支持

技术栈

层次技术
开发语言ArkTS(TypeScript 超集,OpenHarmony 专用)
UI 框架ArkUI(声明式 UI)
平台 SDKOpenHarmony SDK v12
构建工具Hvigor + DevEco Studio
推理后端sherpa-onnx(通过 HAR 包提供 riscv64 native 库)
TTS 模型Matcha-TTS(matcha-icefall-zh-en,中英文)
声码器Vocos(16kHz 通用)
文本前端espeak-ng-data + FST 规则(日期/电话/数字)
音频输出AudioRenderer(PCM 流式播放)
多线程Worker(推理在独立线程执行)

核心功能

  • 中英文混合合成:自动识别中英文并分别处理
  • 流式生成:逐句合成,边生成边播放
  • 语速调节:支持 0.5x ~ 2.0x 语速
  • 多说话人:支持 Speaker ID 切换
  • WAV 保存:生成完成后自动保存到应用沙盒,也可手动保存
  • 数字/日期/电话智能朗读:通过 FST 规则将数字转为中文朗读形式

项目结构

sherpaonnxtts_spacemit/
├── AppScope/ # 应用级资源与配置
│ ├── app.json5 # 包名、版本号
│ └── resources/ # 全局资源(图标等)
├── entry/ # 主模块(HAP)
│ ├── sherpa_onnx.har # sherpa-onnx HAR 包(riscv64 native 库)
│ ├── src/main/ets/
│ │ ├── entryability/
│ │ │ └── EntryAbility.ets # 应用入口
│ │ ├── pages/
│ │ │ └── Index.ets # 主界面(TTS 控制 + 音频播放)
│ │ └── workers/
│ │ └── NonStreamingTtsWorker.ets # TTS 推理 Worker
│ ├── src/main/resources/
│ │ └── rawfile/ # 模型文件
│ │ ├── matcha-icefall-zh-en/ # Matcha-TTS 声学模型
│ │ │ ├── model-steps-3.onnx # 模型文件(~75 MB)
│ │ │ ├── tokens.txt # 词表
│ │ │ ├── lexicon.txt # 词典
│ │ │ ├── date-zh.fst # 日期 FST 规则
│ │ │ ├── number-zh.fst # 数字 FST 规则
│ │ │ ├── phone-zh.fst # 电话 FST 规则
│ │ │ └── espeak-ng-data/ # espeak-ng 前端数据(355 文件)
│ │ └── vocos-16khz-univ.onnx # Vocos 声码器(~53 MB)
│ └── build-profile.json5 # 模块构建配置
├── build-profile.json5 # 项目构建配置
├── oh-package.json5 # 依赖声明
└── README.md

架构

┌───────────────────────────────────────────────────────┐
│ OpenHarmony 设备 │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ sherpaonnxtts HAP │ │
│ │ │ │
│ │ ┌────────────┐ ┌─────────────────┐ │ │
│ │ │ Index.ets │ │ AudioRenderer │ │ │
│ │ │ (UI+控制) │ ─────→ │ (PCM 播放) │ │ │
│ │ └─────┬──────┘ └─────────────────┘ │ │
│ │ │ postMessage │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ NonStreamingTtsWorker │ │ │
│ │ │ ┌────────────┐ ┌──────────────────┐ │ │ │
│ │ │ │ Matcha-TTS │→ │ Vocos 声码器 │ │ │ │
│ │ │ │ (声学模型) │ │ (波形生成) │ │ │ │
│ │ │ └────────────┘ └──────────────────┘ │ │ │
│ │ │ ┌────────────────────────────────────┐ │ │ │
│ │ │ │ espeak-ng + FST(文本前端处理) │ │ │ │
│ │ │ └────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ sherpa_onnx.har (riscv64 native libs) │ │
│ │ libc++_shared.so | libonnxruntime.so.1 │ │
│ │ libsherpa-onnx-c-api.so | libsherpa_onnx.so│ │
│ └────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘

数据流

用户输入文本 → 点击"Start"

Index.ets postMessage('tts-generate')

NonStreamingTtsWorker:
文本 → espeak-ng 音素化 → Matcha-TTS 推理 → Vocos 声码器
↓ ↓
tts-generate-partial (Float32Array) tts-generate-done
↓ ↓
Index.ets: CircularBuffer → AudioRenderer 流式播放

savePcmToWav() 自动保存

代码获取

git clone https://gitee.com/spacemit-openharmony/sherpaonnxtts_spacemit.git
cd sherpaonnxtts_spacemit

模型文件获取

Matcha-TTS 声学模型

从 GitHub Releases 下载:

https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
文件名:matcha-icefall-zh-en.tar.bz2

解压后将整个 matcha-icefall-zh-en/ 目录放入 rawfile/

Vocos 声码器

https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
文件名:vocos-16khz-univ.onnx

放入 entry/src/main/resources/rawfile/vocos-16khz-univ.onnx

espeak-ng 数据

espeak-ng-data 目录(约 355 个文件)包含在 matcha 模型包中,解压后自动在 matcha-icefall-zh-en/espeak-ng-data/ 下。


编译构建

环境要求

  • DevEco Studio 5.x(推荐最新版)
  • OpenHarmony SDK v12
  • entry/sherpa_onnx.har 文件存在(约 98 MB,含 riscv64 native 库)
  • 模型文件已放置到 rawfile/ 目录

签名配置

使用 DevEco Studio 自动生成签名:

File → Project Structure → Signing Configs → 勾选 "Automatically generate signature"

构建命令

# 在项目根目录执行
node "<DevEco Studio 安装路径>/tools/hvigor/bin/hvigorw.js" \
--mode module -p module=entry@default -p product=default \
-p buildMode=release assembleHap --no-daemon

构建产物

entry/build/default/outputs/default/entry-default-signed.hap

设备部署

1. 设备连接确认

hdc list targets
# 预期输出设备序列号

2. TCM 设备权限(SpaceMiT 平台必须)

hdc shell "chmod 666 /dev/tcm"

3. 安装 HAP

hdc install entry-default-signed.hap
# 预期:install bundle successfully.

4. 启动应用

hdc shell "aa start -b com.k2fsa.sherpa.onnx.tts -a EntryAbility"

5. 验证初始化

# 等待模型提取和初始化(首次约 30-45 秒,后续约 10 秒)
hdc shell "hilog -x | grep -i 'JSAPP.*init-tts-done'"
# 预期输出:received msg from worker: init-tts-done

功能验证

生成语音

应用初始化完成后:

  1. 在文本框中输入中文或英文(默认已有示例文本)
  2. 点击 Start 按钮开始合成
  3. 合成完成后音频自动保存到应用沙盒
# 使用 uitest 点击 Start 按钮
hdc shell "uitest uiInput click 721 263"

# 等待生成完成
hdc shell "hilog -x | grep -i 'JSAPP.*tts-generate-done'"

# 拉取生成的 WAV 文件
hdc file recv /data/app/el2/100/base/com.k2fsa.sherpa.onnx.tts/haps/entry/files/tts_output.wav tts_output.wav

TTS ↔ ASR 互验

生成的 WAV 文件可直接推送给 ASR 应用进行识别验证:

# 推送给 ASR 应用
hdc file send tts_output.wav /data/app/el2/100/base/com.k2fsa.sherpa.onnx.vad.asr/haps/entry/files/test.wav

# ASR 解码验证
hdc shell "aa start -b com.k2fsa.sherpa.onnx.vad.asr -a EntryAbility"
# 等待 init 后点击 Decode
hdc shell "uitest uiInput click 960 308"
hdc shell "hilog -x | grep -i 'JSAPP.*partial result'"

验证结果(K3-Pico ITX 实测)

项目结果
模型加载Matcha-TTS + Vocos + espeak-ng 初始化成功
中文合成"某某银行的副行长..." 合成清晰自然 ✅
英文合成"Friends fell out often..." 发音准确 ✅
数字朗读"2024年12月31号" → 正确朗读为中文数字 ✅
电话朗读"18920240522" → 逐位朗读 ✅
金额朗读"123456块钱" → "十二万三千四百五十六块钱" ✅
生成性能默认文本(~80字)生成耗时约 10 秒,输出 24 秒音频
音频质量16kHz,ASR 完整准确识别回原文 ✅

修改定制指导

更换 TTS 模型

修改 NonStreamingTtsWorker.ets 中模型路径配置,确保新模型文件放置在 rawfile/ 对应目录下。

调整语速

应用 UI 提供语速输入框(默认 1.0),也可在代码中修改 Index.etsspeechSpeed 默认值。

切换说话人

修改 sid 参数(默认 0)。具体可用的 Speaker ID 范围取决于模型。


已知限制

限制说明解决方案
音频播放延迟K3 设备 AudioRenderer 初始化约 10 秒应用已采用懒加载,推理不受影响
首次启动慢模型文件需从 rawfile 提取到沙盒(~130 MB)后续启动跳过提取

FAQ

Q: 应用启动后显示 "Extracting..." 很长时间?

首次启动需要将 rawfile 中的模型文件(~130 MB)提取到应用沙盒,约需 30-45 秒。后续启动会跳过已提取的文件。

Q: 点击 Start 后没有声音?

K3 设备的 AudioRenderer 初始化较慢,首次播放可能有约 10 秒延迟。TTS 推理本身正常完成,音频文件已自动保存到沙盒,可通过 hdc 拉取验证。

Q: 如何获取生成的音频文件?

hdc file recv /data/app/el2/100/base/com.k2fsa.sherpa.onnx.tts/haps/entry/files/tts_output.wav tts_output.wav

Q: sherpa_onnx.har 从哪里获取?

HAR 包与 ASR 项目共用同一个,含相同的 riscv64 native 库(sherpa-onnx + onnxruntime)。

Q: 支持哪些语言?

Matcha-icefall-zh-en 模型支持中文和英文混合合成。输入文本中的中英文会自动识别和切换。