-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
能否提高离线讲述人自然语音的响应速度 #1
Comments
我用程序测试了一下,几种不同情况下,从按下键盘按键到读屏软件输出音频的延迟。 其中,NVDA 版本为 2024.1,系统为 Win 11 23H2,所有语音都调整到了最大速度。 测试方法是输入A到Z的字母,然后取每次延迟的平均值。 延迟的计算方法是,使用程序监测键盘和回录系统声音,记录键盘按下的时间点、音频数据变为非零的时间点(即输出音频延迟)、音频数据大于0.0001的时间点(即音频可听见延迟)。
看来这个引擎的确是延迟最大的。 我又测试了直接作为 SAPI 客户端调用 Speak 函数的延迟。
其中,从客户端调用请求 SAPI 合成语音,到引擎接收到来自客户端程序的请求,SAPI 5 系统自己就带来了四十多毫秒的延迟。对这一部分的延迟,我可能是没什么办法的。 而如果去除这四十多毫秒的延迟,延迟的水平就和讲述人内置的自然语音功能差不多了。同时从数据也可以看出,SAPI 版的 Huihui 语音也比 OneCore 版的 Huihui 多出五十毫秒左右的延迟。 (提示:Huihui Desktop 是 SAPI 语音,不带 Desktop 的 Huihui 是 OneCore 语音) |
OneCore 的延迟还是可以的。 |
首先要注意一点,即使是离线语音,自然语音也比普通语音的延迟更高。因为自然语音看起来是使用了 AI 模型运算的,使用了 onnxruntime 组件,也会有一定的 CPU 占用。可以把“讲述人 Xiaoxiao (内置功能)”的延迟作为基准,如果讲述人内置的自然语音功能的延迟可以接受的话,或许还有优化空间。 OneCore 接口的问题在于,微软并没有提供“如何编写第三方 OneCore 语音”的文档,反而在 OneCore 语音的 SpeechSynthesizer 文档里指出 OneCore 语音必须有微软的签名。
单看这一点的话,支持 OneCore 似乎是没戏了,因为微软不可能放行一个“破解”了自然语音的项目。 但是我发现,至少在桌面版的 Windows 上, OneCore 语音架构是和 SAPI5 的架构非常相似的。 SAPI5 语音注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices 并且里面的结构也是相似的。 你甚至可以把 OneCore 的注册表复制到 SAPI5 的注册表里面,让只支持 SAPI5 语音的程序能使用 OneCore 语音。(只是一部分,某些 OneCore 语音这样用会不正常,例如 Kangkang 会“变性”成女声)但是反过来操作,把 SAPI5 的注册表复制到 OneCore 的注册表里面,却是行不通的。除了 Chromium 系软件可以识别外,大多数 UWP 应用都是没法使用注册表里的 SAPI5 语音的。 研究了一下发现,OneCore 语音有一套“注册表隔离”系统,也就是每个应用有属于自己的 Speech_OneCore 注册表(大概是为了做 UWP 的应用隔离,毕竟 OneCore 语音一开始就是给移动应用和 UWP 用的)。因此,把语音注册表数据放在 又研究了一阵发现,这些应用自己的 Speech_OneCore 注册表的初始数据来源,是存放在 除此之外,还需要在 经过一番折腾(包括为文件配置合适的权限让 UWP 也能访问等),我居然真的能够让该引擎的语音在只支持 OneCore 语音的 UWP 阅读器中加载了!看来微软的“必须要求微软签名”的说法,貌似也不是那么准确。 所以,就算是微软没有提供官方文档,也是有可能对接 OneCore 接口的。 只不过会有一些问题。
|
感谢如此细致的研究,还提供了宝贵的研究成果。 是的,即使是离线语音依然有瓶颈。但如果本项目能提高到讲述人的延迟水平也是非常值得欣喜的,视障朋友对 TTS 的延迟太敏感了。
没错,让我想到了一个项目,或许你也会感兴趣:https://github.com/Mahmood-Taghavi/SAPI_Unifier
我确实记得用以上工具注册后‘康康’会出问题,但当时整理了一个注册表,导入就正常了,然而导致问题的原因/具体细节完全不记得。相关注册表如下:
|
如果想要减小读屏延迟,最好的方法可能是使用直接与读屏软件对接的插件。NVDA 实际上已经有了微软离线自然语音的插件,名叫 NeuralVoices,而且里面自带所有离线语音包。目前还没测试过它的延迟水平如何。 在 #18 里也有人建议我出一个 NVDA 插件,因为 NVDA 不支持 SAPI5 语音的自动语言切换,并且这个 NeuralVoices 也不支持自动语言切换。我暂时没有出 NVDA 插件的计划,不过给 NVDA 提了 PR 修了 SAPI5 的语言切换问题。SAPI5 更主要的是通用性,不只限于读屏软件,任何需要 TTS 的程序都可以使用。 这个项目本身只是一个将 SAPI5 对接到 Azure Speech SDK 的适配器。使用离线语音的关键,在于得到的密钥。Azure Speech SDK 支持多种平台(安卓/Linux/macOS/Windows)和编程语言(C#/C++/Java),因此,只要有了语音模型文件和密钥,就可以按照官方文档的示例,在各种场景使用离线语音了。注意 Azure Speech SDK 要使用 1.38.0 或之前的版本,因为从 1.40 版本开始,密钥验证方法改变了。
看起来原理也是把注册表复制到 SAPI5 的注册表位置。这是不是意味着,这几个看起来不同的语音系统,底层实际上是相同的?(Azure Speech SDK 除外,否则就不需要单独的程序适配了) 我去看了一下 SAPI5 和 OneCore 的 Voices 注册表,发现系统自带语音,无论是 SAPI5 还是 OneCore,CLSID 都是相同的 我把这个 SAPI5 语音引擎程序稍加修改就能“适配”OneCore,或许也是这个原因。可惜的是这个没法用在 NVDA 上,因为 NVDA 对于 OneCore 语音的检查很严格,如果语音注册表不存在,或者不包含 另外,貌似 OneCore 语音用到了一些未公开的 COM 接口。尽管这个 SAPI5 引擎已经尽可能地把所有的 SAPI5 指令转换成了对应的 SSML(以发送到 Speech SDK),但依然有一些 SSML 特性因为无法翻译成 SAPI5 指令而丢失,例如 |
开发者您好,我使用的是nvda屏幕阅读器。在使用自然语音朗读时,有点儿不太跟手,也就是说当我按下按键到它发出声音有短暂的延迟,这个延迟在打字之类的场景的时候,影响最大。不知道能否进行优化,再次提升一些响应速度。
The text was updated successfully, but these errors were encountered: