Open ZhangTianrong opened 11 months ago
个人对这个功能还是比较感兴趣的,但是最近比较忙,新功能需要等到大概12月底才有空写,而且用duration来控制语音合成出来的长度我目前也不知道如何实现,得等之后再去研究了。
如果有人有思路的话也可以提供下,非常感谢~
个人对这个功能还是比较感兴趣的,但是最近比较忙,新功能需要等到大概12月底才有空写,而且用duration来控制语音合成出来的长度我目前也不知道如何实现,得等之后再去研究了。
如果有人有思路的话也可以提供下,非常感谢~
我设想的其实比较简单,只是单纯为了对齐每句话的起始位置,用来给有翻译的音声配一个 shadow 的翻译,免得一个闭目用的东西非得睁着眼睛看字幕(有点像许多播放器的 text to speech 功能,但是语音生硬,音量还不好调整),所以并不考虑改动每句话的语速来完全 match duration (毕竟 SRT 转 SSML 其实 duration 也并不准确,话说完了字幕并不会清空),只是给每个带有 duration attribute 的 voice element 后补一个 time 为 -1 的 break element, 每次遇到这种 break 时通过上一个 voice 的 duration 和 audio 的长度确定当前 break 长度,如果是负的就暂时直接把上一个 audio 尾部多出来的部分删除。不过如果要边生成变 trial and error length 似乎也没有多困难,在 duration 外设置一个 tolerance, 控制最长和最短时长,然后继续通过 -1 break 元素对齐时间(我是有这个需求才开始了解 VITS 的,可能有其他可以调的方式活着需要注意的参数,只是我不知道)。其实我这个需求最好直接生成每个句子的起始锚点,然后新增的 audio 直接插入对应位置就好了,但是考虑到 SSML 好像是一个比较通行的表达方式,而它似乎用的是 duration 所以才打算还是绕一下路来实现,设置左 tolerance 为 0 倍 duration, 右 tolerance 为 1 倍即可。
Edit: 简单在这里尝试修改一下,测试还有点问题,有空我再看看。
Edit:
结果发现好像没什么问题,只是单纯 test_api.py
中的 "蓊蓊" 两个字是 <UNK>
然后无法 handle 了……我以为这个 test 本来肯定是可以过的啊。
Edit:
目前的效果就是每个 <voice>
元素可以有 duration
, duration_min
, duration_max
3 个 attribute:
duration
就是这句话持续的时间,值和 <break>
的 time
格式一致,不论生成的语音长度为多少,最后都会通过停顿补足到 duration
的长度duration_min
(>=0, 默认为 0), duration_max
(<=1, 默认为 1) 是允许生成的音频的最短和最长时间和 duration
的比例,生成时会以 10% 的步长调节原始 length
以保证最终音频不长于 duration_max
× duration
, 也不短于 duration_min
× duration
当 <voice>
元素本身就含有 <break>
时,只能所有部分共用上述 attributes, 如果总长度超过了 duration, 将会直接从末尾截断。如果一定要用这种格式,那只能人为给这句话分配一个较小的 duration_max
, 比如分了 3 段,然后给一个 0.33
之类的 duration_max
.
暂时用上去好像没啥问题,我有空再完善一下,比如重试多少次无法达成要求的持续时间区间就退出啊之类的,然后看看能不能 PR 吧。
运行环境
问题描述
能否支持 SSML 的 duration attribute? 像是字幕之类的文件翻译成 SSML 后会带有 duration, 并只依靠 duration 和 break 来完成时间上的对齐。生成完一句话之后才能测量时长并修改 break 的时间重新对其。
问题复现步骤
N/A