NaturalVoiceSAPIAdapter icon indicating copy to clipboard operation
NaturalVoiceSAPIAdapter copied to clipboard

建议开发一个 AI TTS的 SAPI5 适配器

Open qt06 opened this issue 1 year ago • 8 comments

现在已经有不少开源的 AI TTS, 比如 f5-tts/fish-speech/gpt-sovits 等。

这些 TTS 虽然合成速度缓慢,但是作为听书或者文本转音频使用还是不错的。

这些 TTS 一般都提供了通过 http 方式调用的接口,但是没有直接使用 SAPI5 来的方便。

所以我想,您是否有兴趣开发一款 AI TTS 的 SAPI5 适配器呢?

qt06 avatar Nov 20 '24 06:11 qt06

我推测离线微软自然语音实际上也使用了 AI 模型。因为合成语音时有一定的 CPU 占用,并且 SDK 文件里有一个名为 Microsoft.CognitiveServices.Speech.extension.onnxruntime.dll 的文件,也就是说很可能使用了 onnxruntime。不过好在 SDK 本体很小,并且虽然原版不支持旧版 Windows,通过 YY-Thunks 兼容层 + 魔改导入表的方式,也能在 Windows 7 上运行。

虽然目前主要是支持微软系的自然语音(起初也只是因为挖出了密钥想做一个 POC 证明可行性),不过加上其他种类的“自然语音”我觉得也是可以考虑的,毕竟与 SAPI5 框架相关的东西是可以通用的。

不过也有一些问题需要研究探讨一下,因为我目前对 AI 语音的了解并不多。

首先要说一下,SAPI5 语音属于进程内 COM 组件,也就是说,它的 DLL 会被加载进客户端进程,而不是独立出另一个进程用于处理语音数据(至少目前本引擎还是这样实现的)。

那么,

  • 这些 AI 语音是云端服务还是本地运行?
  • 本地运行的话应该如何安装和启动环境?相关的环境和模型文件应该如何获取和发行?
  • 还是说,让用户自行安装 AI 语音,我做一个 HTTP 请求转发器就够了?
  • 目前哪些 AI 语音对中文以及中英文混合的支持较好?

gexgd0419 avatar Nov 20 '24 08:11 gexgd0419

还有一个问题,有些 AI 语音可能不会反馈朗读的每个单词的时间点,也就没法生成 WordBoundary 事件以及 Bookmark 事件,但是一些程序会依赖这一类事件来确定朗读进度。

gexgd0419 avatar Nov 20 '24 14:11 gexgd0419

SAPI5 适配器不需要考虑如何安装那些隐情,因为那些隐情大多数都提供有 http 的api。通过 http 请求发送需要合成的文本,返回音频数据。 我的想法是 SAPI5 适配器提供一个配置程序,用来配置 http 请求所需的参数。

添加一个 http请求就可以作为一个 SAPI5 的声音角色。然后生成一个 son的 配置。

比如下面的例子就是配置了一个叫做 小美的 SAPI5 的角色。

{text} 到时候替换成具体的朗读文本。

{
  "name":"小美",
  "url": "http://127.0.0.1:5000",
  "method": "POST",
  "params": "text={text}&speed=0.5&lang=zh&role=xiaomei",
  "stream": "true"
}

另外,对于朗读时间点的问题,没有的话就忽略。

下面是我找的两个支持 http 的项目,他们的 readme 里的一段:

# get request
curl -G --data-urlencode 'text=This is a test.' -o test.wav 'localhost:5000'
# post request
curl -X POST -H 'Content-Type: text/plain' --data 'This is a test.' -o test.wav 'localhost:5000'

下面是一个 f5-tts-api 的的一个例子:

import requests

res=requests.post('http://127.0.0.1:5010/api',data={
    "ref_text": '古老星系中发现了有机分子,我们离第三类接触还有多远呢',
    "gen_text": '今天是个好日子,外面下了大暴雨,海水也冲上了岸。',
    "model": 'f5-tts'
},files={"audio":open('c:/users/c1/videos/5s.wav','rb')})

if res.status_code!=200:
    print(res.text)
    exit()

with open("ceshi.wav",'wb') as f:
    f.write(res.content)

qt06 avatar Nov 21 '24 01:11 qt06

一些不错的开源 tts,除了 piper 之外,其他的几的的中文都还不错。

qt06 avatar Nov 21 '24 01:11 qt06

这些语音对 SSML 和事件的支持如何?它们是如何反馈语音朗读进度的?还是说,它们只能合成语音,不能反馈进度?

我希望支持尽可能多的 SAPI5 特性。微软的那几个语音对此的支持还是不错的。Edge 语音不支持书签事件,但是至少还能通过每个单词的时间点来模拟。当然不是所有 SAPI5 特性都是必须的,但总有一些程序会依赖其中几个特性。

如果实在没有进度反馈的办法,可能只能把文本拆分成句子,之后逐个句子合成,这样至少还有以句子为单位的进度表示。不过这样也要考虑各种语言的文本应该如何切分句子。

gexgd0419 avatar Nov 21 '24 01:11 gexgd0419

这些都是不支持xml标记的。他们现在提供的 API 都非常的简陋,基本上就只能返回音频数据了。

qt06 avatar Nov 21 '24 01:11 qt06

看了一下 calibre(一款内置了 piper 语音的电子书管理器) 的实现,它是在启动了 piper 进程后,用 ICU 库把文本拆分成句子,之后逐句合成,以得到以句子为单位的朗读进度的。此外应该是为了保证一定的合成效果,它也会把太短的句子合并,把太长的句子进一步在单词分界处拆分。

至于音量、语速和语调调节,看起来也需要自己想办法实现了。

gexgd0419 avatar Nov 21 '24 03:11 gexgd0419

我觉得要支持现有的这些开源的 AI TTS 的话,单词边界这些视健就只能舍弃了。 语速、音量、音高这些可能也的自己实现。 工作量不小的。

qt06 avatar Nov 21 '24 06:11 qt06

AI TTS的SAPI5 适配器开发得怎么样了,是暂时还未实现吗

rinjing avatar Jul 27 '25 19:07 rinjing

这些语音对 SSML 和事件的支持如何?它们是如何反馈语音朗读进度的?还是说,它们只能合成语音,不能反馈进度?

我希望支持尽可能多的 SAPI5 特性。微软的那几个语音对此的支持还是不错的。Edge 语音不支持书签事件,但是至少还能通过每个单词的时间点来模拟。当然不是所有 SAPI5 特性都是必须的,但总有一些程序会依赖其中几个特性。

如果实在没有进度反馈的办法,可能只能把文本拆分成句子,之后逐个句子合成,这样至少还有以句子为单位的进度表示。不过这样也要考虑各种语言的文本应该如何切分句子。

以gptsovits为例,这个AI可通过更改参考音频来实现情感标记的功能,而且现在gpt sovits有个推理特化的GUI,或许可以基于这个进行进一步开发:https://github.com/AI-Hobbyist/GPT-SoVITS-Inference

rinjing avatar Jul 27 '25 19:07 rinjing

想问问js能直接调用SAPI5吗

Achuan-2 avatar Aug 05 '25 04:08 Achuan-2

想问问js能直接调用SAPI5吗

如果你指的是网页开发,那么能否使用 SAPI5 语音取决于浏览器。

SpeechSynthesis 是用于语音合成的通用接口,在不同的平台、不同的浏览器中,可能使用不同的语音服务。Windows 上,Firefox 浏览器会使用 SAPI5 语音,而 Chrome 和 Chromium 只能使用 OneCore 语音。(虽然本质上还是用 SAPI5 语音框架调用的 OneCore,但是只有不支持 OneCore 语音的系统上,Chrome 才会回退到使用 SAPI5 语音,否则 SAPI5 语音是不会出现在语音选项中的)

所以如果使用的是谷歌系浏览器,或是基于 Chromium 的框架(如 Electron),默认只能使用 OneCore 语音。

如果不介意使用 hack 的话,通过一些注册表 hack,倒是可以让 Chromium 能够使用 SAPI5 语音,参考 #5。

gexgd0419 avatar Aug 05 '25 06:08 gexgd0419

@gexgd0419 谢谢成了

给思源笔记(基于electron开发)的插件加了本地朗读功能

Image

Achuan-2 avatar Aug 05 '25 09:08 Achuan-2