演讲:软件自动口

我在去年的文章“我们吸引声音”的结尾得出了一个公认的结论:“是否有可能在不追踪录音的声谱图的情况下从一张白纸吸引声音?坦白说,我没有成功。”但我最近了解到SAM -在发布1982年通过不问软件,它是第一个商业成功的PC语音合成程序。在2000年代中期德国演示评估师Tobias Korbmacher和Sebastian Macke收集了Commodore 64的组装式SAM清单,并将其转换为不可读但可行的C代码。然后在2014年,英国的Vidar Hokstad尝试将C代码转换为可读的形式-手动为变量赋予有意义的名称并替换goto在循环和分支上;最后,在2017年,另一位德国基督徒Schiffler将代码从C重写为JavaScript。您可以在discordier.imtqy.com/sam上将其作为“黑匣子”进行尝试

在我看来,对于想要了解语音合成总体工作原理的人来说,原始的JavaScript语音合成器是最方便的实验模型。我的SAM分支以及经过大量清理的代码和注释位于github.com/tyomitch/sam上。不幸的是,以前的作者设法使人们对SAM的兴趣消失了,现在他们没有时间分析长期的业余爱好项目的拉动请求。

SAM包含四个功能组件:

  1. 朗诵者将英语文本转换成音素记录:例如,“ LITTLE TOO LOW”(来自SAM附带的演示程序的示例)变成“ AH LIHTUL TUW5 LOW”。
  2. 解析器将语音记录转换为语音记录:从“ AH LIHTUL TUW5 LOW”中得出“ AH, ,L,IH,DX,AX,LX, ,T,*,*,UX,WX, ,L,OW,WX”。对于显示的每个背景解析器还设置持续时间和音调。
  3. 渲染器通过语音记录构建频率,幅度和其他声学特征的数组;
  4. 最后一个匿名组件(函数ProcessFrames)将一系列频率和幅度转换为PCM流以进行音频输出。

在本文中,我将依次分析所有四个组件。

朗诵者


Reciter是作为一个单独的程序附加到SAM的:创建者声称Reciter 469的发音规则正确地记录了大约90%的英语单词。这意味着在将第十个单词的转录提交给以下组件的输入之前,需要进行手动编辑。

SAM使用其自己的转录系统,其中英语音素由集合中的单独字符[A-Z/]或成对的两个这样的字符表示:
音素指定音素指定音素指定音素指定
/ b /B/ p /P/ v /V/ F /F
/天/D/吨/T/ z /Z/秒/S
/dʒ/J/ʃ/CH/ʒ/ZH/ʃ/SH
/ G /G/ k /K/ H //H/ð/DH
/米/M/ n /N/ŋ/NX/θ/TH
/升/L/ r /R/ j /Y/ w /W
/æ/AE/ɛ/EH/ɪ/IH/ 一世 /IY
/ʌ/AH/ɔ/AO/ʊ/UH/ u /UX
/ɒ/OH/ɑ/AA/ə/AX/ɜ/ER
/eɪ/EY/aɪ/AYOY/一ʊ/AW
/oʊ/OW[l̩]UL[m̩]UM[n̩]UN
除音素外,SAM转录中还使用数字1-8 表示压力和语调:1表示“非常情绪化”的压力,4表示正常的压力,6表示中性的音调,8表示“极端的音调下降”。

朗诵者的安排非常简单:列表中的上下文相关规则会交替应用于输入行,例如,规则“ (IR)#=AYR”用/aɪr/替换元音之前的文本⟨ir⟩;规则“ .(S) =Z”用/ z /代替浊音辅音和空格(单词的末尾)之间的⟨s⟩;规则“ (U)^^=AH5”用/ʌ/代替连续两个辅音之前的⟨u⟩,并使音节重读。请务必注意,很多情况下,朗诵者不会强调任何元音,而在某些情况下,它会一次注意到多个元音:例如,“挑衅”一词变成了“PRUW4VOW5KIHNX”,即。/pruvoʊkɪŋ/细心的读者会发现,不必要的压力是不是在这个转录唯一的错误。

我决定转录语音合成器中最有趣的部分;而在朗诵者输出给出转录的质量相对较低,我决定有几种免费的Internet服务可用于抄录英文摘录;这些服务不是使用启发式规则,而是使用相当大的词典,以我的经验,最好的转录质量是tophonetics.comphotransedit.com。; 在同一时间,第二个有一些缺点:它使用不太标准的音素符号,音符在单音节词甚至强调,什么是最不方便的-它是写在ASP.NET和要求POST请求正确的价值观__VIEWSTATE__EVENTVALIDATION来自第三方的使用变得复杂网站。因此,在tyomitch.imtqy.com上的SAM设备和操作演示中,我通过https://cors-anywhere.herokuapp.com/https://tophonetics.com/使用音译

解析器


与SAM的创建者所谓的Reciter不同,Parser和Renderer组件是由德国反向工程师命名的,因此这些名称不能完全准确地反映这些组件的用途。

解析器具有三个主要任务:

  1. «» (, ) . ( ) «-» UL, UM, UN, [l̩, m̩, n̩]. , /əl, əm, ən/; Parser , AXL, AXM, AXN .
  2. , .. . «AH LIHTUL TUW LOW» , /t/ [ɾ] (DX) [t] (T,*,*) . ( .) , /l/ [ɫ] (LX) , [l] (L) .
  3. .

SAM支持81种背景,其中61种具有名称,可用于音素记录以“胜过”解析器并立即设置所需的声音。其余20个背景是无名的;其中的18个仅可能是由于Parser的工作而出现的,并且代码46和47的背景无法以任何方式出现,并且可能不受SAM开发人员的监督而无法确定。

代码0-4( .?,-)的背景对应于静默;下表总结了其余的内容:
编码指定声音编码指定声音
5IY[一世]42CH[t]在组成中/tʃ/
6IH[ɪ]43*[ʃ]作为/tʃ/的一部分
7EH[ɛ]44J[d]在组成中/dʒ/
8AE[æ]45*[/] / /dʒ/
9AA[ɑ]48EY〜[ɜ] in /eɪ/
10AH[ʌ]49AY〜[ɑ]在/aɪ/
十一AO[ɔ]五十OY[ɔ] of /ɔɪ/
12UH[ʊ]51AW[ɑ]在/aʊ/
十三AX[ə]52OW[ɔ]作为/oʊ/
14IX较短[ɪ]53UW〜[u]
十五ER[ɜ]54B[b]
十六UX[u]55*
17OH[o]56*
十八RX[ɹ]57D[d]
十九LX[ɫ]58*
二十WX在短命中的短[ʊ]59*
21YX在短片中短[ɪ]60G[G]
22WH更长[w]61*
23R[ɹ̠]62*
24L[l]63GX[G]
25W[w]64*
26Y[j]65岁*
27M[米]66P[p]
28N[n]67*
29日NX[ŋ]68*
三十DX[ɾ]69T[t]
31Q[ʔ]70*
32S[s]71*
33SH[ʃ]72K[kʲ]
34F[F]73*
35TH[θ]74*
36/H[C]75KX[k]
37/X[H]76*
38Z[z]77*
39ZH[ʒ]78UL[l̩]
40V[v]79UM[m̩]
41DH[ð]80UN[n̩]

解析器执行的操作包括七个步骤:

  1. 自身解析:在输入行上形成背景代码列表和由输入行中的数字给出的并行音调列表。
  2. 将一组两个打法规则应用于背景列表:例如,替换项/ t / + / r /→[tʃ] + [ɹ̠]和/ k / + /非前元音/→[k] + [元音]。(前元音前面的/ k /保持不变,并且与背景[kʲ]相匹配。)
  3. CopyStress:为重音元音设置的音调扩展到它们前面的辅音。
  4. SetPhonemeLength:持续时间被替换为每个背景(在条件“帧”中)。使用了两个背景经度表-一个用于重读音节,一个用于不重读音节。
  5. AdjustLengths:应用一组七个规则来调整背景持续时间。例如,将浊音辅音之前的元音加长一倍半,并将连续的爆炸辅音减半。
  6. ProlongPlosiveStopConsonants:在元音前面有爆炸性辅音,平滑辅音和副音被分为三重背景。这三个中的第一个背景对应于较低的声音强度,第二个对应于全强度,第三个对应于静音。
  7. InsertBreath:该短语被“静音”背景( .?,-划分“呼气”最长可达232帧(约2½秒)。在用于逆向PC的SAM实现中,这样的分区对于节省内存是必需的。在JavaScript版本中没有任何意义,而在我的fork中则将其删除。

解析器输出三个并行列表:背景代码,其音调和持续时间。

渲染器


此组件负责从单词的狭义上合成语音。在输入端,它接收具有指定音调和持续时间的背景列表,以及影响合成语音的参数。在输出处,它产生八个并行列表:共振峰 F 1 -F 3的频率,它们的强度(振幅),主频率F 0(声音)和值sampledConsonant,这将在下面更详细地描述。

参考SAM指令,提供了以下语音参数值示例:
投票速度沥青
小精灵7264110160
小机器人9260190190
闷家伙8272110105
小老太太8232145145
外星人10064150200
SAM7264128128
达莱克120100100200
值得注意的是,速度参数未在Renderer中使用,而是在音频生成阶段使用:一帧声音的持续时间取决于此参数。除速度参数外,帧持续时间还取决于声音的类型,如下所述。

共振峰语音合成基于以下事实:每个背景与前几个共振峰的频率和振幅相关。对于元音的合成,使用两个共振峰就足够了-例如,从曼尼托巴大学网站获取的典型的英语元音共振峰频率图:


要合成辅音,需要附加的共振峰。而且,正如我在去年的文章中提到的那样,嘈杂的辅音的特征是在很宽的频带内出现“爆发”:



这些“爆发”是无法通过纯共振峰合成获得的,因此SAM从样本表中复制了嘈杂的辅音。上面提到的值sampledConsonant选择表中与特定嘈杂辅音对应的部分。

Renderer执行的操作包括五个步骤:

  1. SetMouthThroat:对于元音和Sonor背景(代码5–29和48–53),频率F 1和F 2的列表值分别乘以参数Mouth和Throat。
  2. CreateFrames: . , (1–8) Pitch (1 → −32, 6 → 0, 8 → +12). , ( 30 ) , .
  3. CreateTransitions: F0–F3 F1–F3 . , , .
  4. F0 F1, «pitch contour», .
  5. , () , PCM.


从物理角度来看,语音是声带产生的声门脉冲序列(请参见图)。声带沿口和鼻(语音路径通过出口,而类似谐振器的那些则放大了喉声中的某些谐波。喉波的频率-这是声音F 0的主要频率。通常,它的值在100到400 Hz之间:男性较低,女性较高,甚至儿童较高。 共振峰合成中使用的语音模型是将多个带通滤波器应用于喉部波,每个带通滤波器可区分一个共振峰。分配频带的宽度取决于共振峰的频率,并且根据实验数据,它高达200 Hz: 在我的tyomitch.imtqy.com上的 SAM演示中







使用此方法:在参数Bandwidth = 3的默认值下,每个共振峰将谐波F 0引入到最终共振峰频率的5.9%范围内的音频信号中。这大致对应于上图:频率为3 KHz的共振峰分配了177 Hz的带宽。在经典的SAM实现中,更创新地解决了所需谐波次数的产生:对于每个共振峰,都会产生一个波,但该波的相位会以频率F 0归零。在我的演示中,您可以通过取消选中“音高”参数来切换到一种模式,该模式为每个共振峰合成一个波(但不将相位调零)。经典SAM中

的功能ProcessFrames与所有其他背景分开处理聋哑人和浊音辅音:

  • . , Speed. ([s]) 105 , ([p] [t]) — 10.4 .
  • Speed16250PCM-, : () F1 F2, ( ) F3. , Speed=72 10.6 .
  • , , 34Speed16250PCM-, . , Speed . , Pitch=64, 1.6 , .. 9.5 .

对于嘈杂的辅音,使用了五个样本表:一个用于肺泡([t,s,z]),一个用于室内肺泡([ʃ,ʒ]),一个用于阴唇和牙齿([p,f,v,θ,ð ]),以及一个[ç]和[h]。与同一张表格相关的样本仅在持续时间和强度上有所不同。

在我的演示中,为简单起见,所有帧都会产生相等持续时间的声音,并且该持续时间仅取决于速度参数:在其默认值下,一帧对应于10.4毫秒的声音。如实验所示,此“平均”对应于经典SAM,尽管就其而言,合成短语中的各个声音可以“向前”或“向后”以ms为单位“移动”。

最后,我将演示经典SAM音频生成器和我的音频生成器在打开和关闭音调合成的情况下创建的三个欢迎短语的频谱图:



如您所见,关闭音调合成可以在音质和频谱图中共振峰的可见性之间达成折衷。

All Articles