将sherpa-onnx嵌入unity中进行语音识别(ASR)
起因因为有语音识别需求且需要低延迟在查找了很多ASR项目后偶然间发现sherpa-onnx比较契合我的需求因为可以本地部署还免费查找了不少资料后发现很少有sherpa-onnxunity的资料因此尝试自己研究下。sherpa-onnx项目基础介绍sherpa-onnx 是一个开源项目旨在提供离线的语音识别、文本转语音、说话人识别和语音活动检测VAD功能。该项目支持很多语言其中包括C#在原项目文件中有C#示例因此可以移植到unity中本文参考了sherpa-onnx的TTS实现和原项目C#示例代码。首先该项目进行语音识别需要语音识别大模型我这边以sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20模型作为测试要下载该模型请自行去该项目的官方网址去下载。​然后需要导入相关dll库和lib库我在原项目文件中找了很久都没找到最后在他的示例项目中找到。现在万事俱备接下来可以开始了。首先在官方的C#示例代码中有流式和非流式的示例代码此处先以流式作为例子至于非流式道理差不多。直接上代码using SherpaOnnx; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading; using UnityEngine; public class MyAsr_Test : MonoBehaviour { private static int minFreq, maxFreq;//最小和最大频率 WaitForSeconds seconds new WaitForSeconds(0.2f); /// summary /// 上一次采样位置 /// /summary int lastSampling; float[] f new float[16000]; AudioClip microphoneClip; bool recoeding true; bool Init() { if (Microphone.devices.Length 0) { Debug.Log($设备名称为{Microphone.devices[0]}); Microphone.GetDeviceCaps(null, out minFreq, out maxFreq); if (minFreq 0 maxFreq 0) { maxFreq 44100; } return true; } return false; } /// summary /// 设置录音状态 /// /summary void SetRecoeding(bool recoeding) { this.recoeding recoeding; if (recoeding) lastSampling 0; } private IEnumerator Start() { Init(); yield return seconds; var model_dir Path.Combine(Application.streamingAssetsPath, SoundToTextModel); var modelDir Path.Combine(model_dir, sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20); OnlineRecognizerConfig config new(); config.FeatConfig.SampleRate 16000; config.FeatConfig.FeatureDim 80; config.ModelConfig.Transducer.Encoder Path.Combine(modelDir, encoder-epoch-99-avg-1.onnx); config.ModelConfig.Transducer.Decoder Path.Combine(modelDir, decoder-epoch-99-avg-1.onnx); config.ModelConfig.Transducer.Joiner Path.Combine(modelDir, joiner-epoch-99-avg-1.onnx); config.ModelConfig.Paraformer.Encoder ; config.ModelConfig.Paraformer.Decoder ; config.ModelConfig.Tokens Path.Combine(modelDir, tokens.txt); config.ModelConfig.Provider cpu; config.ModelConfig.NumThreads 1; config.ModelConfig.Debug 0; config.DecodingMethod greedy_search; config.MaxActivePaths 4; config.EnableEndpoint 1; config.Rule1MinTrailingSilence 2.4f; config.Rule2MinTrailingSilence 0.8f; config.Rule3MinUtteranceLength 20; #region 添加识别标点符号的模型 OfflinePunctuationConfig opc new OfflinePunctuationConfig(); OfflinePunctuationModelConfig opmc new OfflinePunctuationModelConfig(); string model_path Path.Combine(model_dir, sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12, model.onnx); if (!File.Exists(model_path)) { yield break; } opmc.CtTransformer model_path; opmc.NumThreads 2; opmc.Provider cpu; opmc.Debug 1; opc.Model opmc; var offlinePunctuation new OfflinePunctuation(opc); #endregion OnlineRecognizer recognizer new(config); OnlineStream s recognizer.CreateStream(); string lastText string.Empty; int segmentIndex 0; // 等待应用获取麦克风权限 yield return Application.RequestUserAuthorization(UserAuthorization.Microphone); // 如果未获取到麦克风权限 if (!Application.HasUserAuthorization(UserAuthorization.Microphone)) yield break; do { microphoneClip Microphone.Start(null, true, 1, 16000); yield return null; } while (!Microphone.IsRecording(null)); Application.quitting () Microphone.End(null); Debug.Log(开始录音); while (true) { yield return seconds; int currentPos Microphone.GetPosition(null); bool isSucceed microphoneClip.GetData(f, 0); if (!recoeding) continue; if (isSucceed) { if (lastSampling ! currentPos) { int count 0; float[] p default; if (currentPos lastSampling) { count currentPos - lastSampling; p new float[count]; Array.Copy(f, lastSampling, p, 0, count); } else { count 16000 - lastSampling; p new float[count currentPos]; Array.Copy(f, lastSampling, p, 0, count); Array.Copy(f, 0, p, count, currentPos); count currentPos; } lastSampling currentPos; s.AcceptWaveform(16000, p); } } while (recognizer.IsReady(s)) { recognizer.Decode(s); } var text recognizer.GetResult(s).Text; bool isEndpoint recognizer.IsEndpoint(s); if (!string.IsNullOrWhiteSpace(text) lastText ! text) { lastText text; Debug.Log($\r{segmentIndex}: {lastText}); } if (isEndpoint) { if (!string.IsNullOrWhiteSpace(text)) { segmentIndex; lastText offlinePunctuation.AddPunct(text); Debug.Log($\r{segmentIndex}: {lastText}); } recognizer.Reset(s); } } } }上述是一个测试脚本引入了sherpa-onnx自动添加标点的模型该模型同样去官网自行下载因为仅使用sherpa-onnx的asr语音识别模型那么它识别的结果不会自动添加标点符号如果不需要自动添加标点可以将自动添加标点的部分代码删掉。将该脚本随便挂在一个物体上就可以测试了个人觉得还行这里以音乐来测试。

相关新闻

解决99%问题!enen开源项目排坑指南

解决99%问题!enen开源项目排坑指南

解决99%问题!enen开源项目排坑指南 你还在为enen项目运行报错抓狂?Cookie过期、依赖冲突、推送失败?本文汇总开发者最常遇到的20问题,提供复制即用的解决方案,让你从配置到部署全程顺畅! 读完你将获得&…

2026/10/10 1:24:38 阅读更多 →
STM32L432KC与PCA9422 PMIC组合的低功耗电源管理实战解析

STM32L432KC与PCA9422 PMIC组合的低功耗电源管理实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:24:38 阅读更多 →
8086机器码解码实战:从字节流反推汇编指令

8086机器码解码实战:从字节流反推汇编指令

简介:这份笔记面向编写8086汇编器、需要理解机器指令编码细节的开发者,系统整理了8086机器语言解码的核心知识。内容涵盖指令格式、寄存器编号、寻址模式、操作码、立即数以及字节/字/双字等基本概念,并重点剖析固定编码指令与双操作数指令的…

2026/10/11 4:21:06 阅读更多 →

最新新闻

Jenkins最新版本2.585修改插件源的方法

Jenkins最新版本2.585修改插件源的方法

前言: Jenkins安装完成后需要下载多个插件,而国外插件源升级站点下载非常慢经常会出现超时的错误影响效率。所以最好的方法是当jenkins安装完成后修改插件源升级站点的地址。关于Jenkins2.585版本的安装方法参见、、。 一、修改更新站点地址 1、在Jenk…

2026/10/11 9:34:43 阅读更多 →
Realtek高清晰音频管理器不见了怎么办 教你快速找回

Realtek高清晰音频管理器不见了怎么办 教你快速找回

电脑控制面板中找不到Realtek高清晰音频管理器,通常与声卡驱动未正确安装、驱动版本不匹配、管理器未安装或Windows音频设置有关。这种情况不一定代表声卡损坏,也不需要立即重装系统。可以先检查声卡设备和驱动状态,再根据实际情况重新安装驱…

2026/10/11 9:34:43 阅读更多 →
REA模型:资源-事件-代理语义建模原理与应用

REA模型:资源-事件-代理语义建模原理与应用

我无法基于当前输入内容生成符合要求的博文。原因如下:输入中仅提供了项目标题"rea",未提供任何有效上下文;“相关热搜词”与“最新网络热词”字段为空,无实际关键词支撑;基于标题及热词网络搜索的内容部分为…

2026/10/11 9:34:43 阅读更多 →
Spring Boot企业智能生产管理系统毕设全攻略:从架构设计到答辩

Spring Boot企业智能生产管理系统毕设全攻略:从架构设计到答辩

我接触过不少做毕设的学生,十个里面有八个卡在“题目太大、代码抄来但说不清、答辩被问住”。今天借着“基于Spring Boot的企业智能生产管理信息系统”这个电子企业方向的选题,我把整个项目的设计思路、表结构、核心代码、实操步骤和答辩避坑点都拆开讲一…

2026/10/11 9:34:43 阅读更多 →
多模态大模型落地指南:从架构选型到数据训练与部署

多模态大模型落地指南:从架构选型到数据训练与部署

简介:《多模态基础大模型技术白皮书》是一份面向人工智能学习者、大模型研究人员及AI应用开发者的技术参考,系统讲解多模态基础大模型如何整合文本、图像、语音等数据,通过自动学习构建正交化模型,支持细粒度查询与复杂数据关系建…

2026/10/11 9:34:43 阅读更多 →
江苏轨道交通专用原子灰源头厂家合作实力参考:原子灰快干不踩坑选择指南

江苏轨道交通专用原子灰源头厂家合作实力参考:原子灰快干不踩坑选择指南

江苏地区不少轨道交通装备制造企业在挑选原子灰时,最关心的无非两件事:能不能快速干透、会不会返工踩坑。无锡市涂料有限公司作为深耕工业找平腻子三十余年的源头厂家,其锡德原子灰系列,尤其是MT-005轨道交通专用水性原子灰&#…

2026/10/11 9:33:43 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →