forked from cnlinxi/book-text-to-speech
-
Notifications
You must be signed in to change notification settings - Fork 3
/
text_to_speech.tex
2676 lines (1930 loc) · 188 KB
/
text_to_speech.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[cn,10pt,math=newtx,citestyle=gb7714-2015,bibstyle=gb7714-2015]{elegantbook}
\title{Text-to-Speech}
\subtitle{语音合成:从入门到放弃}
\author{冬色}
\institute{https://github.com/cnlinxi}
\date{March 20, 2022}
\version{1.0}
\bioinfo{开源协议}{Apache License 2.0}
\extrainfo{一花独放不是春,百花齐放春满园。—— 《古今贤文》}
\setcounter{tocdepth}{3}
\cover{cover.jpeg}
% 本文档命令
\usepackage{array}
\newcommand{\ccr}[1]{\makecell{{\color{#1}\rule{1cm}{1cm}}}}
\definecolor{customcolor}{RGB}{32,178,170}
\colorlet{coverlinecolor}{customcolor}
\begin{document}
\maketitle
\frontmatter
\chapter*{前言}
\markboth{Introduction}{前言}
语音合成(Speech Synthesis)是一种将文本转换为语音的技术,大多数情况下与Text-to-Speech (TTS)同义,是人工智能的子领域之一。本文档简要介绍当前语音合成技术的发展。
想写这个总结已经很久了,上海疫情导致各个区几乎停摆,不间断的核酸检测,小区也封闭很久了,现在算是一个好时机,就赶快整理出来吧。大多数内容来自平日的博客和毕业论文,所以还不算特别辛苦。
最近自愿半自愿地迷恋上烹饪,比较自豪,零基础至少学会了20+道菜,炒炸爆煎焖炖煮,几乎顿顿不重样,自我感觉良好。
最近刷了《雍正王朝》,感慨颇多,是一部好剧。
感谢我的夫人,由于上海严重的疫情,她居家办公,但一直在家划水,不然我应该能够多写一点,所以我希望知道友商领导的联系方式,我要举报她/doge。
精力有限,不免错漏,可以通过GitHub发起issue,或者我的邮箱:cncmn/at/hotmail.com联系我。
\vskip 0.5cm
\LaTeX{}模板来自\href{https://github.com/ElegantLaTeX/ElegantBook}{ElegantBook},感谢开源社区的贡献。
\vskip 1.5cm
\begin{flushright}
冬色\\
2022年春分于上海
\end{flushright}
\tableofcontents
\mainmatter
\chapter{语音合成概述}
\section{背景和概述}
语音合成(Speech Synthesis),大部分情况下与文语转换(Text-to-Speech,TTS)同义,是一种将文本转换为语音的技术,是人工智能的子领域之一,赋予机器像人一样自如说话能力的技术,是人机语音交互中重要的一环。语音合成的研究历史可追溯至18至19世纪,从早期的基于规则的机械式、电子式语音合成器,到基于波形拼接、统计参数的语音合成。近年来,基于深度学习(Deep Learning)和神经网络(Neural Network)的建模方法在机器学习领域各个任务上都取得了快速的发展,语音合成技术也在此基础上得到了显著的提升。随着信息技术及人工智能技术的发展,各种应用场景对语音合成的效果有了越来越高的要求。
\subsection{背景介绍}
语音是最方便最自然的人机交互方式之一,随着近年来智能手机等智能终端的迅速发展,人机语音交互收到了越来越多的关注。人机语音交互是基于语音识别、自然语言理解及语音合成的人机语音对话技术,作为人机交互的核心技术之一,语音合成就是赋予计算机及各种终端设备像人一样自如说话的能力。语音合成是一门交叉学科,它涉及到语言学、语音学、自然语言处理、信号处理、统计学习、模式识别等众多学科的理论与技术。
随着信息技术和人工智能技术的发展,以及对语音信号和统计建模技术本身不断的深入理解,语音合成系统的效果逐渐提高,被广泛应用于各个场景,包括语音对话系统;智能语音助手,如 Siri,讯飞语点;电话信息查询系统;车载导航,有声电子书等辅助应用;语言学习;机场,车站等实时信息广播系统;视力或语音障碍者的信息获取与交流等。同时,不同应用场景对于合成语音的各项指标,包括自然度、可懂度、音质、情感风格、控制力也都提出了更高的要求。
\subsection{语音合成概述}
语音信号的产生分为两个阶段,信息编码和生理控制。首先在大脑中出现某种想要表达的想法,然后由大脑将其编码为具体的语言文字序列,及语音中可能存在的强调、重读等韵律信息。经过语言的组织,大脑通过控制发音器官肌肉的运动,产生出相应的语音信号。其中第一阶段主要涉及人脑语言处理方面,第二阶段涉及语音信号产生的生理机制。
从滤波的角度,人体涉及发音的器官可以分为两部分:激励系统和声道系统,如图\ref{fig:human_speech_arch}所示。激励系统中,储存于肺部的空气源,经过胸腔的压缩排出,经过气管进入声带,根据发音单元决定是否产生振动,形成准周期的脉冲空气激励流或噪声空气激励流。这些空气流作为激励,进入声道系统,被频率整形,形成不同的声音。声道系统包括咽喉、口腔(舌、唇、颌和口)组成,可能还包括鼻道。不同周期的脉冲空气流或者噪声空气流,以及不同声道器官的位置决定了产生的声音。因此,语音合成中通常将语音的建模分解为激励建模和声道建模。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.4\textwidth]{human_speech_arch.png}
\caption{人类发声机理 \label{fig:human_speech_arch}}
\end{figure}
\subsection{语音合成的历史}
语音合成系统分为两部分,分别称为文本前端和后端,如下图所示。
\begin{figure}[htbp]
\centering
\includegraphics[scale=0.7]{text_to_speech_arch.png}
\caption{语音合成系统框图 \label{fig:text_to_speech_arch}}
\end{figure}
文本前端主要负责在语言层、语法层、语义层对输入文本进行文本分析;后端主要是从信号处理、模式识别、机器学习等角度,在语音层面上进行韵律特征建模,声学特征建模,然后进行声学预测或者在音库中进行单元挑选,最终经过合成器或者波形拼接等方法合成语音。
\begin{figure}[htbp]
\centering
\includegraphics[scale=0.7]{text_to_speech_history.png}
\caption{语音合成发展历史 \label{fig:text_to_speech_history}}
\end{figure}
根据语音合成研究的历史,如图\ref{fig:text_to_speech_history}所示,语音合成研究方法可以分为:机械式语音合成器、电子式语音合成器、共振峰参数合成器、基于波形拼接的语音合成、统计参数语音合成、以及神经网络语音合成。
语音合成的早期工作主要是通过源-滤波器模型对语音产生的过程进行模拟。最开始的机械式语音合成器,使用风箱模拟人的肺部运动,产生激励空气流,采用振动弹簧片和皮革模拟声道系统,通过手动协调各部分运动,能够合成出五个长元音。机械式的语音合成器难以实用,随着时代的发展,贝尔实验室提出了电子式的语音合成器。不再模拟具体的生理器官,电子式语音合成器通过脉冲发射器和噪声发射器来分别产生模拟浊音和清音的激励系统,通过操作人员手动控制多个带通滤波器来模拟声道系统,最后通过放大器输出语音信号。由于电子式语音合成器使用有限个带通滤波器模拟声道系统,对自然语音的频谱特征的刻画精度有限。为了更好地刻画声道系统,共振峰参数合成器被提出。共振峰参数合成器将声道系统看成一个谐振腔,利用共振峰频率和宽度等声道的谐振特性,构建声道滤波器,以更好地刻画语音的声道特性。然而由于共振峰参数合成器结构复杂,需要大量人工分析调整参数,难以实用。
早期的语音合成方法由于模型简单,系统复杂等原因,难以在实际场景应用。随着计算机技术的发展,基于波形拼接的语音合成被提出。基于波形拼接的语音合成的基本原理是首先构建一个音库,在合成阶段,通过对合成文本的分析,按照一定的准则,从音库中挑选出与待合成语音相似的声学单元,对这些声学单元进行少量调整,拼接得到合成的语音。早期的波形拼接系统受限于音库大小、挑选算法、拼接调整的限制,合成语音质量较低。1990年,基于同步叠加的时域波形修改算法被提出,解决了声学单元拼接处的局部不连续问题。更进一步,基于大语料库的波形拼接语音合成方法被提出,采用更精细的挑选策略,将语音音库极大地拓展,大幅提升了合成语音的自然度。由于直接使用发音人的原始语音,基于波形拼接的语音合成方法合成语音的音质接近自然语音,被广泛应用。但其缺点也较为明显,包括音库制作时间长、需要保存整个音库、拓展性差、合成语音自然度受音库和挑选算法影响,鲁棒性不高等。
随着统计建模理论的完善,以及对语音信号理解的深入,基于统计参数的语音合成方法被提出。其基本原理是使用统计模型,对语音的参数化表征进行建模。在合成阶段,给定待合成文本,使用统计模型预测出对应的声学参数,经过声码器合成语音波形。统计参数语音合成方法是目前的主流语音合成方法之一。统计参数音合成方法的优点很多,包括只需要较少的人工干预,能够快速地自动构建系统,同时具有较强的灵活性,能够适应不同发音人,不同发音风格,多语种的语音合成,具有较强的鲁棒性等。由于语音参数化表示以及统计建模的平均效应,统计参数语音合成方法生成的语音自然度相比自然语音通常会有一定的差距。基于隐马尔科夫的统计参数语音合成方法是发展最为完善的一种。基于HMM的统计参数语音合成系统能够同时对语音的基频、频谱和时长进行建模,生成出连续流畅且可懂度高的语音,被广泛应用,但其合成音质较差。
\subsection{当代语音合成框架}
和统计参数语音合成系统类似,深度学习语音合成系统也可大致分为两个部分:文本前端和声学后端。文本前端的主要作用是文本预处理,如:为文本添加韵律信息,并将文本词面转化为语言学特征序列(Linguistic Feature Sequence);声学后端又可以分为声学特征生成网络和声码器,其中声学特征生成网络根据文本前端输出的信息产生声学特征,如:将语言学特征序列映射到梅尔频谱或线性谱;声码器利用频谱等声学特征,生成语音样本点并重建时域波形,如:将梅尔频谱恢复为对应的语音。近年来,也出现了完全端到端的语音合成系统,将声学特征生成网络和声码器和合并起来,声学后端成为一个整体,直接将语言学特征序列,甚至文本词面端到端转换为语音波形。
\begin{enumerate}
\item 文本前端
文本前端的作用是从文本中提取发音和语言学信息,其任务至少包括以下四点。
\begin{enumerate}
\item 文本正则化
在语音合成中,用于合成的文本存在特殊符号、阿拉伯数字等,需要把符号转换为文本。如“1.5元”需要转换成“一点五元”,方便后续的语言学分析。
\item 韵律预测
该模块的主要作用是添加句子中韵律停顿或起伏。如“在抗击新型冠状病毒的战役中,党和人民群众经受了一次次的考验”,如果停顿信息不准确就会出现:“在/抗击/新型冠状病毒/的/战役中,党/和/人民群众/经受了/一次/次/的/考验”。“一次次”的地方存在一个错误停顿,这将会导致合成语音不自然,如果严重些甚至会影响语义信息的传达。
\item 字形转音素
将文字转化为发音信息。比如“中国”是汉字表示,需要先将其转化为拼音“zhong1 guo2”,以帮助后续的声学模型更加准确地获知每个汉字的发音情况。
\item 多音字和变调
许多语言中都有多音字的现象,比如“模型”和“模样”,这里“模”字的发音就存在差异。另外,汉字中又存在变调现象,如“一个”和“看一看”中的“一”发音音调不同。所以在输入一个句子的时候,文本前端就需要准确判断出文字中的特殊发音情况,否则可能会导致后续的声学模型合成错误的声学特征,进而生成不正确的语音。
\end{enumerate}
\item 声学特征生成网络
声学特征生成网络根据文本前端的发音信息,产生声学特征,如梅尔频谱或线性谱。近年来,基于深度学习的生成网络甚至可以去除文本前端,直接由英文等文本生成对应的频谱。但是一般来说,因为中文字形和读音关联寥寥,因此中文语音合成系统大多无法抛弃文本前端,换言之,直接将中文文本输入到声学特征生成网络中是不可行的。基于深度学习的声学特征生成网络发展迅速,比较有代表性的模型有Tacotron系列,FastSpeech系列等。近年来,也涌现出类似于VITS的语音合成模型,将声学特征生成网络和声码器融合在一起,直接将文本映射为语音波形。
\item 声码器
通过声学特征产生语音波形的系统被称作声码器,声码器是决定语音质量的一个重要因素。一般而言,声码器可以分为以下4类:纯信号处理,如Griffin-Lim、STRAIGHT和WORLD;自回归深度网络模型,如WaveNet和WaveRNN;非自回归模型,如Parallel WaveNet、ClariNet和WaveGlow;基于生成对抗网络(Generative Adversarial Network,GAN)的模型,如MelGAN、Parallel WaveGAN和HiFiGAN。
\end{enumerate}
\section{Awesome List}
\begin{enumerate}
\item https://github.com/faroit/awesome-python-scientific-audio
\item https://github.com/wenet-e2e/speech-synthesis-paper
\item https://github.com/ddlBoJack/Speech-Resources
\item https://github.com/sindresorhus/awesome
\end{enumerate}
\section{参考书籍}
\begin{enumerate}
\item \href{https://nndl.github.io/}{神经网络与深度学习}
\item Tan X, Qin T, Soong F, et al. A survey on neural speech synthesis[J]. arXiv preprint arXiv:2106.15561, 2021.
\item Sisman B, Yamagishi J, King S, et al. An Overview of Voice Conversion and Its Challenges: From Statistical Modeling to Deep Learning[J]. IEEE/ACM Transactions on Audio, Speech, and Language Processing, 2020, 29: 132-157.
\end{enumerate}
\section{语音相关的会议、期刊、比赛和公司}
\subsection{会议}
\begin{enumerate}
\item INTERSPEECH(Conference of the International Speech Communication Association)
\item ICASSP(IEEE International Conference on Acoustics, Speech and Signal Processing)
\item ASRU(IEEE Automatic Speech Recognition and Understanding Workshop)
\item ISCSLP(International Symposium on Chinese Spoken Language Processing)
\item ACL(Association of Computational Linguistics)
\end{enumerate}
\subsection{期刊}
\begin{enumerate}
\item Computer Speech and Language
\end{enumerate}
\subsection{最新论文}
\begin{enumerate}
\item \href{http://yqli.tech/page/tts_paper.html}{低调奋进TTS最新论文集}
\item https://arxiv.org/list/eess.AS/recent
\item https://arxiv.org/list/cs.SD/recent
\item https://arxiv.org/list/cs.CL/recent
\item https://arxiv.org/list/cs.MM/recent
\end{enumerate}
\subsection{比赛}
\begin{enumerate}
\item \href{http://www.festvox.org/blizzard/}{Blizzard Challenge}
\item \href{https://www.zerospeech.com/}{Zero Resource Speech Challenge}
\item \href{http://challenge.ai.iqiyi.com/detail?raceId=5fb2688224954e0b48431fe0}{ICASSP2021 M2VoC}
\item \href{http://www.vc-challenge.org/}{Voice Conversion Challenge}
\item CHiME: Computational Hearing in Multisource Environment
\item NIST
\end{enumerate}
\subsection{公司}
\begin{enumerate}
\item \href{https://azure.microsoft.com/en-us/services/cognitive-services/text-to-speech/#features}{微软}
\item \href{https://cloud.google.com/text-to-speech/docs/voices?hl=zh-cn}{谷歌云}
\item \href{https://www.aicloud.com/dev/ability/index.html?key=tts#ability-experience}{捷通华声}
\item \href{https://www.nuance.com/omni-channel-customer-engagement/voice-and-ivr/text-to-speech.html#!}{Nuance}
\item \href{https://aws.amazon.com/cn/polly/}{Amazon polly}
\item \href{https://fanyi.baidu.com/}{百度(翻译)}
\item \href{https://ai.sogou.com/product/audio_composition/}{搜狗开发平台}
\item \href{https://fanyi.sogou.com/}{搜狗(翻译)}
\item \href{https://ai.youdao.com/product-tts.s}{有道开放平台}
\item \href{http://fanyi.youdao.com}{有道(翻译)}
\item \href{https://cn.bing.com/translator}{微软(翻译)}
\item \href{https://translate.google.cn/}{Google翻译}
\end{enumerate}
\subsection{微信公众号}
\begin{enumerate}
\item 阿里语音AI
\item CCF语音对话与听觉专委会
\item CSMT
\item 声学挖掘机
\item 谈谈语音技术
\item THUsatlab
\item WeNet步行街
\item 音频语音与语言处理研究组
\item 雨石记
\item 语音算法组
\item 语音杂谈
\item 语音之家
\item 智能语音新青年
\end{enumerate}
\section{开源资料}
\subsection{中文数据集}
\begin{enumerate}
\item \href{https://www.data-baker.com/open_source.html}{标贝中文标准女声音库}: 中文单说话人语音合成数据集,质量高。
\item \href{https://www.openslr.org/18/}{THCHS-30}: 中文多说话人数据集,原为语音识别练手级别的数据集,也可用于多说话人中文语音合成。
\item \href{https://www.openslr.org/38/}{Free ST Chinese Mandarin Corpus}: 855个说话人,每个说话人120句话,有对应人工核对的文本,共102600句话。
\item \href{https://github.com/KuangDD/zhvoice}{zhvoice}: zhvoice语料由8个开源数据集,经过降噪和去除静音处理而成,说话人约3200个,音频约900小时,文本约113万条,共有约1300万字。
\item \href{https://arxiv.org/abs/2010.09275}{滴滴800+小时DiDiSpeech语音数据集}: DiDi开源数据集,800小时,48kHz,6000说话人,存在对应文本,背景噪音干净,适用于音色转换、多说话人语音合成和语音识别,参见:https://zhuanlan.zhihu.com/p/268425880。
\item \href{https://github.com/khiajohnson/SpiCE-Corpus}{SpiCE-Corpus}: SpiCE是粤语和英语会话双语语料库。
\item \href{http://www.paper.edu.cn/scholar/showpdf/MUT2IN4INTD0Exwh}{HKUST}: 10小时,单说话人,采样率8kHz。
\item \href{https://www.aishelltech.com/kysjcp}{AISHELL-1}: 170小时,400个说话人,采样率16kHz。
\item \href{http://www.aishelltech.com/aishell_2}{AISHELL-2}: 1000小时,1991个说话人,采样率44.1kHz。希尔贝壳开源了不少中文语音数据集,AISHELL-2是最近开源的一个1000小时的语音数据库,禁止商用。官网上还有其它领域,比如用于语音识别的4个开源数据集。
\item \href{https://www.aishelltech.com/aishell_3}{AISHELL-3}: 85小时,218个说话人,采样率44.1kHz。
\end{enumerate}
\subsection{英文数据集}
\begin{enumerate}
\item \href{https://keithito.com/LJ-Speech-Dataset/}{LJSpeech}: 英文单说话人语音合成数据集,质量较高,25小时,采样率22.05kHz。
\item \href{https://datashare.is.ed.ac.uk/handle/10283/2651}{VCTK}: 英文多说话人语音数据集,44小时,109个说话人,每人400句话,采样率48kHz,位深16bits。
\item \href{https://catalog.ldc.upenn.edu/LDC93S1}{TIMIT}: 630个说话人,8个美式英语口音,每人10句话,采样率16kHz,位深16bits。\href{http://academictorrents.com/details/34e2b78745138186976cbc27939b1b34d18bd5b3}{这里是具体下载地址},下载方法:首先下载种子,然后执行:
\begin{lstlisting}
ctorrent *.torrent
\end{lstlisting}
\item \href{http://festvox.org/cmu_arctic/packed/}{CMU ARCTIC}: 7小时,7个说话人,采样率16kHz。语音质量较高,可以用于英文多说话人的训练。
\item \href{https://www.cstr.ed.ac.uk/projects/blizzard/2011/lessac_blizzard2011/}{Blizzard-2011}: 16.6小时,单说话人,采样率16kHz。可以从\href{https://www.cstr.ed.ac.uk/projects/blizzard/}{The Blizzard Challenge}查找该比赛的相关数据,从\href{https://www.synsig.org/index.php}{SynSIG}查找该比赛的相关信息。
\item \href{https://www.cstr.ed.ac.uk/projects/blizzard/2013/lessac_blizzard2013/}{Blizzard-2013}: 319小时,单说话人,采样率44.1kHz。
\item \href{https://www.openslr.org/12}{LibriSpeech}: 982小时,2484个说话人,采样率16kHz。\href{https://www.openslr.org/resources.php}{OpenSLR}搜集了语音合成和识别常用的语料。
\item \href{https://www.openslr.org/60}{LibriTTS}: 586小时,2456个说话人,采样率24kHz。
\item \href{https://datashare.ed.ac.uk/handle/10283/3061}{VCC 2018}: 1小时,12个说话人,采样率22.05kHz。类似的,可以从\href{https://datashare.ed.ac.uk/handle/10283/2211}{The Voice Conversion Challenge 2016}获取2016年的VC数据。
\item \href{http://www.openslr.org/109/}{HiFi-TTS}: 300小时,11个说话人,采样率44.1kHz。
\item \href{https://www.openslr.org/7/}{TED-LIUM}: 118小时,666个说话人。
\item \href{https://catalog.ldc.upenn.edu/LDC97S42}{CALLHOME}: 60小时,120个说话人,采样率8kHz。
\item \href{https://github.com/roholazandie/ryan-tts}{RyanSpeech}: 10小时,单说话人,采样率44.1kHz。交互式语音合成语料。
\end{enumerate}
\subsection{情感数据集}
\begin{enumerate}
\item \href{https://github.com/HLTSingapore/Emotional-Speech-Data}{ESD}: 用于语音合成和语音转换的情感数据集。
\item \href{https://github.com/Emotional-Text-to-Speech/dl-for-emo-tts}{情感数据和实验总结}: 实际是情感语音合成的实验总结,包含了一些情感数据集的总结。
\end{enumerate}
\subsection{其它数据集}
\begin{enumerate}
\item \href{https://wenet.org.cn/opencpop}{Opencpop}: 高质量歌唱合成数据集。
\item \href{https://ai.100tal.com/dataset}{好未来开源数据集}: 目前主要开源了3个大的语音数据集,分别是语音识别数据集,语音情感数据集和中英文混合语音数据集,都是多说话人教师授课音频。
\item \href{https://sites.google.com/site/shinnosuketakamichi/publication/jsut}{JSUT}: 日语,10小时,单说话人,采样率48kHz。
\item \href{https://github.com/IS2AI/Kazakh_TTS}{KazakhTTS}: 哈萨克语,93小时,2个说话人,采样率44.1/48kHz。
\item \href{https://ruslan-corpus.github.io/}{Ruslan}: 俄语,31小时,单说话人,采样率44.1kHz。
\item \href{https://github.com/iisys-hof/HUI-Audio-Corpus-German}{HUI-Audio-Corpus}: 德语,326小时,122个说话人,采样率44.1kHz。
\item \href{https://github.com/imdatsolak/m-ailabs-dataset}{M-AILABS}: 多语种,1000小时,采样率16kHz。
\item \href{https://data.statmt.org/pmindia/}{India Corpus}: 多语种,39小时,253个说话人,采样率48kHz。
\item \href{http://www.openslr.org/94/}{MLS}: 多语种,5.1万小时,6千个说话人,采样率16kHz。
\item \href{https://commonvoice.mozilla.org/zh-CN/datasets}{CommonVoice}: 多语种,2500小时,5万个说话人,采样率48kHz。
\item \href{https://github.com/Kyubyong/css10}{CSS10}: 十个语种的单说话人语音数据的集合,140小时,采样率22.05kHz。
\item \href{https://www.openslr.org/resources.php}{OpenSLR}: OpenSLR是一个专门托管语音和语言资源的网站,例如语音识别训练语料库和与语音识别相关的软件。迄今为止,已经有100+语音相关的语料。
\item \href{https://datashare.ed.ac.uk/}{DataShare}: 爱丁堡大学维护的数据集汇总,包含了语音、图像等多个领域的数据集和软件,语音数据集中包括了语音合成、增强、说话人识别、语音转换等方面的内容。
\item \href{https://msropendata.com/datasets?term=speech}{Speech in Microsoft Research Open Data}: 微软开源数据搜索引擎中关于语音的相关数据集。
\item \href{https://github.com/jim-schwoebel/voice_datasets}{voice datasets}: Github上较为全面的开源语音和音乐数据集列表,包括语音合成、语音识别、情感语音数据集、语音分离、歌唱等语料,找不到语料可以到这里看看。
\item \href{https://github.com/JRMeyer/open-speech-corpora}{Open Speech Corpora}: 开放式语音数据库列表,特点是包含多个语种的语料。
\item \href{https://www.emime.org/participate.html}{EMIME}: 包含一些TTS和ASR模型,以及一个中文/英语,法语/英语,德语/英语双语数据集。
\item \href{https://github.com/celebrity-audio-collection/videoprocess}{Celebrity Audio Extraction}: 中国名人数据集,包含中国名人语音和图像数据。
\end{enumerate}
\subsection{开源工具}
\begin{enumerate}
\item \href{https://github.com/waywardgeek/sonic}{sonic}: 语音升降速工具。
\item \href{https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/releases/download/v1.0.1/montreal-forced-aligner_linux.tar.gz}{MFA}: 从语音识别工具Kaldi中提取出来的音素-音频对齐工具,可以利用MFA获取每一个音素的时长,供预标注或时长模型使用。
\item \href{https://github.com/jaekookang/p2fa_py3}{宾西法尼亚大学强制对齐标注软件(P2FA)}:\href{https://blog.csdn.net/jojozhangju/article/details/51951622}{这里}有相关的介绍,对于噪音数据鲁棒性差。
\item \href{https://github.com/bootphon/ABXpy}{ABXpy}: 语音等测评ABX测试网页。
\item \href{https://github.com/bigpon/SpeechSubjectiveTest}{SpeechSubjectiveTest}: 主观测评工具,包括用于语音合成和转换的MOS、PK(倾向性测听)、说话人相似度测试和ABX测试。
\item \href{https://github.com/matpool/matools}{Matools}: 机器学习环境配置工具库
\item \href{https://github.com/Alinshans/MyTinySTL}{MyTinySTL}: 基于C++11的迷你STL。
\item \href{https://github.com/applenob/Cpp_Primer_Practice}{CppPrimerPractice}: 《C++ Primer 中文版(第 5 版)》学习仓库。
\item \href{https://github.com/521xueweihan/git-tips}{git-tips}: Git的奇技淫巧。
\end{enumerate}
\subsection{开源项目}
\begin{enumerate}
\item \href{https://github.com/coqui-ai/TTS}{coqui-ai TTS}: 采用最新研究成果构建的语音合成后端工具集。
\item \href{https://github.com/espnet/espnet}{ESPNet}: 语音合成和识别工具集,主要集成声学模型、声码器等后端模型。
\item \href{https://github.com/pytorch/fairseq}{fairseq}: 序列到序列建模工具,包含语音识别、合成、机器翻译等模型。
\item \href{https://github.com/espeak-ng/espeak-ng}{eSpeak NG Text-to-Speech}: 共振峰生成的语音合成模型,集成超过100个语种和口音的语音合成系统,特别地,可借鉴该项目中的多语种文本前端。
\item \href{https://github.com/dmort27/epitran}{Epitran}: 将文本转换为IPA的工具,支持众多语种。
\item \href{https://github.com/Rayhane-mamah/Tacotron-2}{Tacotron-2}: Tensorflow版本的Tacotron-2.
\item \href{https://github.com/as-ideas/TransformerTTS}{Transformer TTS}: TensorFlow 2实现的FastSpeech系列语音合成。
\item \href{https://github.com/syoyo/tacotron-tts-cpp}{Text-to-speech in (partially) C++ using Tacotron model + Tensorflow}: 采用TensorFlow C++ API运行Tacotron模型。
\item \href{https://github.com/microsoft/muzic}{muzic}: 微软AI音乐的开源项目,包括乐曲理解、音乐生成等多种工作。
\item \href{https://github.com/CSTR-Edinburgh/merlin}{merlin}: CSTR开发的统计参数语音合成工具包,需要与文本前端(比如Festival)和声码器(比如STRAIGHT或WORLD)搭配使用。
\end{enumerate}
\section{语音合成评价指标}
对合成语音的质量评价,主要可以分为主观和客观评价。主观评价是通过人类对语音进行打分,比如平均意见得分(Mean Opinion Score,MOS)、众包平均意见得分(CrowdMOS,CMOS)和ABX测试。客观评价是通过计算机自动给出语音音质的评估,在语音合成领域研究的比较少,论文中常常通过展示频谱细节,计算梅尔倒谱失真(Mel Cepstral Distortion,MCD)等方法作为客观评价。客观评价还可以分为有参考和无参考质量评估,这两者的主要判别依据在于该方法是否需要标准信号。有参考评估方法除了待评测信号,还需要一个音质优异的,可以认为没有损伤的参考信号。常见的有参考质量评估主要有ITU-T P.861 (MNB)、ITU-T P.862 (PESQ)、ITU-T P.863 (POLQA)、STOI和BSSEval。无参考评估方法则不需要参考信号,直接根据待评估信号,给出质量评分,无参考评估方法还可以分为基于信号、基于参数以及基于深度学习的质量评估方法。常见的基于信号的无参考质量评估包括ITU-T P.563和ANIQUE+,基于参数的方法有ITU-T G.107(E-Model)。近年来,深度学习也逐步应用到无参考质量评估中,如:AutoMOS、QualityNet、NISQA和MOSNet。
主观评价中的MOS评测是一种较为宽泛的说法,由于给出评测分数的主体是人类,因此可以灵活测试语音的不同方面。比如在语音合成领域,主要有自然度MOS(MOS of Naturalness)和相似度MOS(MOS of Similarity)。但是人类给出的评分结果受到的干扰因素较多,谷歌对合成语音的主观评估方法进行了比较,在评估较长语音中的单个句子时,音频样本的呈现形式会显著影响参与人员给出的结果。比如仅提供单个句子而不提供上下文,与相同句子给出语境相比,被测人员给出的评分差异显著。国际电信联盟(International Telecommunication Union,ITU)将MOS评测规范化为ITU-T P.800,其中绝对等级评分(Absolute Category Rating,ACR)应用最为广泛,ACR的详细评估标准如下表所示。
\begin{table}[htbp]
\centering
\caption{主观意见得分的评估标准}
\begin{tabular}{llll}
\toprule
音频级别 & 平均意见得分 & 评价标准 \\
\midrule
优 & 5.0 & 很好,听得清楚;延迟小,交流流畅 \\
良 & 4.0 & 稍差,听得清楚;延迟小,交流欠流畅,有点杂音 \\
中 & 3.0 & 还可以,听不太清;有一定延迟,可以交流 \\
差 & 2.0 & 勉强,听不太清;延迟较大,交流需要重复多遍 \\
劣 & 1.0 & 极差,听不懂;延迟大,交流不通畅 \\
\bottomrule
\end{tabular}
\end{table}
在使用ACR方法对语音质量进行评价时,参与评测的人员(简称被试)对语音整体质量进行打分,分值范围为1~5分,分数越大表示语音质量越好。MOS大于4时,可以认为该音质受到大部分被试的认可,音质较好;若MOS低于3,则该语音有比较大的缺陷,大部分被试并不满意该音质。
\section{平均意见得分的测评要求与方法}
语音合成的最终目标是,合成语音应尽可能接近真实发音,以至于人类无法区分合成和真实语音。因此让人类对合成语音进行评价打分是最为直观的评价方法,评分经处理之后即可获得平均意见得分。平均意见得分是语音合成系统最重要的性能指标之一,能够直接反映合成语音的自然度、清晰度以及可懂度。
\subsection{实验要求}
获取多样化且数量足够大的音频样本,以确保结果在统计上的显著,测评在具有特定声学特性的设备上进行,控制每个被试遵循同样的评估标准,并且确保每个被试的实验环境保持一致。
\subsection{实验方法}
为了达到实验要求,可以通过两种方法获得足够精确的测评结果。第一种是实验室方式,该方式让被试在实验室环境中进行测评,在试听过程中环境噪音必须低于35dB,测试语音数量至少保持30个以上,且覆盖该语种所有音素和音素组合,参与评测的被试应尽可能熟练掌握待测合成语音的语种,最好以合成语音的语种为母语。该方法的优点是测试要素容易控制,能够稳定保证实验环境达到测评要求;缺点则主要是需要被试在固定场所完成试听,人力成本高。第二种是众包,也就是将任务发布到网络上,让具有条件的被试在任何地方进行测评。该方法主要优点是易于获得较为有效的评估结果;而缺点则体现在无法确保试听条件。
\subsection{实验步骤}
\begin{enumerate}
\item 收集合成语音和录制的真实语音;
\item 确保文本和语音一一对应,去除发音明显错误的音频样本;
\item 生成问卷,将合成语音和真实语音交叉打乱,确保打乱的顺序没有规律,合成语音和真实语音不可让被试提前探知到;
\item 开始任务前,被试试听示例语音,并告知其对应的大致得分;
\item 被试开始对给定音频打分,前三条语音可以作为被试进入平稳打分状态的铺垫,不计入最终结果;
\item 回收问卷,舍弃有明显偏差的评价数据,统计最终得分。
\end{enumerate}
\subsection{实验设计}
\begin{enumerate}
\item 准备测试语音数据。(1)从各领域和语音合成系统实际应用场景中,摘选常规文本作为测试语料,选取的语句一般尽可能排除生僻字;(2)用于测试的句子一般是未出现在训练集中的;(3) 被试必须使用耳机试听语音,以便于判断更为细微的差别;(4)为了避免被试的疲惫,待测评系统和语料数量不可太多,需要控制测评时间;(5)一个句子需要由多个被试打分。
\item 设置实验参数。在准备测试语音时,需要提前设置好训练语料、待测系统、参与测试的句子数量、每个句子被试听的次数等。以中文语音合成系统的语音评估为例,测评设置如下表所示。
\begin{table}[htbp]
\centering
\caption{语音测评设置}
\begin{tabular}{llll}
\toprule
训练集 & 待测系统 & 句子数量 & 每个句子被测次数 \\
\midrule
内部数据集 & 真实语音 & 40 & 12 \\
内部数据集 & Tacotron-2 & 40 & 12 \\
内部数据集 & FastSpeech-2 & 40 & 12 \\
\bottomrule
\end{tabular}
\end{table}
\item 准备HTML文档等展示材料,向被试介绍该测试。该HTML文档至少包括:(1)测试注意事项,如被试应该使用何种设备,在何种环境下试听,试听时应该排除的干扰因素等;(2)测试任务,向被试介绍本次试听的测试目标,应关注的侧重点,如:可懂度、相似度、清晰度等方面;(3)参考音频,可以放置一些示例音频,如MOS=5的优质语音,MOS=1的低劣音频,以便被试更好地对音频打分;(4) 测试音频,根据不同任务,放置合理的测试音频,真实和合成音频应提前打乱,并且不可告知被试打乱的顺序。
\end{enumerate}
\subsection{实验数据处理}
\begin{enumerate}
\item 数据筛选。由于被试有可能没有受到监督,因此需要对收集到的评分进行事后检查,如删除使用扬声器试听的评分。另外,为了控制个体因素对整体结果的影响,减少偏离整体数据的异常值,需要计算每个人的评分与总体得分序列的相关性,相关性的度量使用相关系数来实现,如果相关系数r大于0.25,则保留;否则拒绝该被试的所有评分。相关系数r的计算方法如下:
\begin{equation}
r=\frac{\mathop{cov}(\mu_{1n},...,\mu_{Mn};\mu_1,...,\mu_M)}{\sqrt{\mathop{var}(\mu_{1n},...,\mu_{Mn})}\cdot \sqrt{\mathop{var}(\mu_1,...,\mu_M)}}
\end{equation}
\end{enumerate}
其中, $M$ 为句子数量,$N$为被试数量, $\mu_{mn}$ 为被试 $n$ 对句子 $m$ 给出的评分,$1\leq m\leq M$ ,$1\leq n\leq N$, $\mu_m=1/N\sum_{n=1}^N\mu_{mn}$ 为句子 $m$ 的总体平均分, $\mathop{cov}$ 为协方差, $\mathop{var}$ 为方差。
\chapter{语音信号基础}
\section{参考资料}
\begin{enumerate}
\item \href{http://dsp.whu.edu.cn/syszy/szxin_hao_chu.htm}{武汉大学-数字信号处理}
\item \href{http://speech.ee.ntu.edu.tw/SS2020Spring/}{台湾大学李琳山-数位语音处理}
\item \href{http://labrosa.ee.columbia.edu/~dpwe/pubs/Ellis10-introspeech.pdf}{An Introduction to Signal Processing for Speech}
\item \href{https://www.inf.ed.ac.uk/teaching/courses/asr/2020-21/asr02-signal.pdf}{爱丁堡大学课件}
\end{enumerate}
\section{语音基本概念}
声波通过空气传播,被麦克风接收,通过 \lstinline{采样}、 \lstinline{量化}、 \lstinline{编码}转换为离散的数字信号,即波形文件。音量、音高和音色是声音的基本属性。
\subsection{能量}
音频的能量通常指的是时域上每帧的能量,幅度的平方。在简单的语音活动检测(Voice Activity Detection,VAD)中,直接利用能量特征:能量大的音频片段是语音,能量小的音频片段是非语音(包括噪音、静音段等)。这种VAD的局限性比较大,正确率也不高,对噪音非常敏感。
\subsection{短时能量}
短时能量体现的是信号在不同时刻的强弱程度。设第n帧语音信号的短时能量用 $E_n$ 表示,则其计算公式为:
\begin{equation}
E_n=\sum_{m=0}^{M-1}x_n^2(m)
\end{equation}
上式中, $M$ 为帧长, $x_n(m)$ 为该帧中的样本点。
\subsection{声强和声强级}
单位时间内通过垂直于声波传播方向的单位面积的平均声能,称作声强,声强用I表示,单位为“瓦/平米”。实验研究表明,人对声音的强弱感觉并不是与声强成正比,而是与其对数成正比,所以一般声强用声强级来表示:
\begin{equation}
L=10{\rm log}(\frac{I}{I'})
\end{equation}
其中,I为声强,$I'=10e^{-12}w/m^2$ 称为基本声强,声强级的常用单位是分贝(dB)。
\subsection{响度}
响度是一种主观心理量,是人类主观感觉到的声音强弱程度,又称音量。\lstinline{响度与声强和频率有关}。一般来说,声音频率一定时,声强越强,响度也越大。相同的声强,频率不同时,响度也可能不同。响度若用对数值表示,即为响度级,响度级的单位定义为方,符号为phon。根据国际协议规定,0dB声强级的1000Hz纯音的响度级定义为0 phon,n dB声强级的1000Hz纯音的响度级就是n phon。其它频率的声强级与响度级的对应关系要从如图\ref{fig:loudness_curve}等响度曲线查出。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{loudness_curve.png}
\caption{等响曲线 \label{fig:loudness_curve}}
\end{figure}
\subsection{过零率}
过零率体现的是信号过零点的次数,体现的是频率特性。
\begin{equation}
Z_n=\sum_{n=0}^{N-1}\sum_{m=0}^{M-1}|{\rm sgn}(x_n(m))-{\rm sgn}(x_n(m-1))|
\end{equation}
其中,$N$ 表示帧数, $M$ 表示每一帧中的样本点个数, ${\rm sgn}$ 为符号函数,即
\begin{equation}
{\rm sgn}=\left\{\begin{matrix}
& 1,x \geq 0 \\
& -1,x<0
\end{matrix}\right.
\end{equation}
\subsection{共振峰}
声门处的准周期激励进入声道时会引起共振特性,产生一组共振频率,这一组共振频率称为共振峰频率或简称共振峰。共振峰包含在语音的频谱包络中,频谱包络的局部极大值就是共振峰。频率最低的共振峰称为第一共振峰,记作$f_1$,频率更高的共振峰称为第二共振峰$f_2$、第三共振峰$f_3$……以此类推。实践中一个元音用三个共振峰表示,复杂的辅音或鼻音,要用五个共振峰。参见:\href{https://www.zhihu.com/question/27126800/answer/35376174}{不同元音辅音在声音频谱的表现是什么样子?},\href{https://www.zhihu.com/question/24190826/answer/280149476}{什么是共振峰?}
\subsection{基频和基音周期}
基音周期反映了声门相邻两次开闭之间的时间间隔,基频(fundamental frequency,f0/F0)则是基音周期的倒数,对应着声带振动的频率,代表声音的音高,声带振动越快,基频越高。它是语音激励源的一个重要特征,比如可以通过基频区分性别。一般来说,成年男性基频在100$\sim$250Hz左右,成年女性基频在150$\sim$350Hz左右,女声的音高一般比男声稍高。
如图\ref{fig:frequency_f0}所示,蓝色箭头指向的明亮横线对应频率就是基频,决定音高;而绿框中的明亮横线统称为谐波。谐波是基频对应的整数次频率成分,由声带发声带动空气共振形成的,对应着声音三要素的音色。谐波的位置,相邻的距离共同形成了音色特征。谐波之间距离近听起来则偏厚粗,之间距离远听起来偏清澈。在男声变女声的时候,除了基频的移动,还需要调整谐波间的包络,距离等,否则将会丢失音色信息。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{frequency_f0.png}
\caption{基频和谐波} \label{fig:frequency_f0}
\end{figure}
人类可感知声音的频率大致在20-20000Hz之间,人类对于基频的感知遵循对数律,也就是说,人们会感觉100Hz到200Hz的差距,与200Hz到400Hz的差距相同。因此,音高常常用基频的对数来表示。在音乐上,把相差一倍的两个基频的差距称为一个八度(octave);把一个八度12等分,每一份称为一个半音(semitone);把一个半音再100等分,每一份称为一个音分(cent)。
基频是语音的重要特征,在包括语音合成的语音处理中有着广泛的应用,比如语音转换(Voice Conversion,VC)和语音合成中基频是一个强特征。基频的提取可以分为时域法和频域法。时域法以波形为输入,基本原理是寻找波形的最小正周期;频域法则会先对信号进行傅里叶变换,得到频谱,频谱在基频的整倍数处有尖峰,频域法的基本原理就是求出这些尖峰频率的最大公约数。但是考虑到基频并非每一帧都有,因此在提取基频前后,都需要判断有无基频,称之为清浊音判断(Unvoiced/Voiced Decision,U/V Decision)。语音的基频往往随着时间变化,在提取基频之前往往要进行分帧,逐帧提取的基频常常含有错误,其中常见的错误就是倍频错误和半频错误,也就是提取出来的基频是真实基频的两倍或者一半,因此基频提取后要进行平滑操作。常见的基频提取算法有基于信号处理时域法的YIN\footnote{A. de Cheveigné and H. Kawahara, "YIN, a fundamental frequency estimator for speech and music", Journal of the Acoustical Society of America, 2002.},基于信号处理频域法的SWIPE\footnote{A. Camacho and J. G. Harris, "A sawtooth waveform inspired pitch estimator for speech and music", Journal of the Acoustical Society of America, 2008.},基于机器学习时域法的CREPE\footnote{J. W. Kim, et al., "CREPE: A convolutional representation for pitch estimation", ICASSP, 2018.}和基于机器学习频域法的SPICE\footnote{B. Gfeller, et al., "SPICE: Self-supervised pitch estimation", IEEE Transactions on Audio, Speech and Language Processing, 2020.}。常用的基频提取工具有\href{https://github.com/JeremyCCHsu/Python-Wrapper-for-World-Vocoder}{pyWORLD},\href{https://github.com/YannickJadoul/Parselmouth}{Parselmouth},\href{https://github.com/marl/crepe}{CREPE},\href{https://github.com/patriceguyot/Yin}{YIN}等。参见\href{https://zhuanlan.zhihu.com/p/269107205}{基频提取算法综述}。
\subsection{音高}
音高(pitch)是由声音的基频决定的,音高和基频常常混用。可以这样认为,音高(pitch)是稀疏离散化的基频(F0)。由规律振动产生的声音一般都会有基频,比如语音中的元音和浊辅音;也有些声音没有基频,比如人类通过口腔挤压气流的清辅音。在汉语中,元音有a/e/i/o/u,浊辅音有y/w/v,其余音素比如b/p/q/x等均为清辅音,在发音时,可以通过触摸喉咙感受和判断发音所属音素的种类。
\subsection{MFCC和语谱图}
对语音进行分析和处理时,部分信息在时域上难以分析,因此往往会提取频谱特征。在语音合成中,通常将频谱作为中间声学特征:首先将文本转换为频谱,再将频谱转换为波形;在语音识别中,则将频谱或者MFCC作为中间声学特征。语音通过预加重、分帧、加窗、傅里叶变换之后,取功率谱的幅度平方,进行梅尔滤波取对数之后,就得到了梅尔频谱(或称FilterBank/FBank),如果再进行离散余弦变换,就能够获得MFCC,下一章将进行详述。语音通常是一个短时平稳信号,在进行傅里叶变换之前,一般要进行分帧,取音频的一个小片段进行短时傅里叶变换(STFT)。STFT的结果是一个复数,包括幅度和相位信息,将该复数中的频率作为横轴,幅度作为纵轴,如图\ref{fig:frequency_spectrum}所示,就组成了频谱图,将频谱图中的尖峰点连接起来,就形成了频谱包络。注意到,频谱图反映一个语音帧的频域情况,没有时间信息。因此,将每个帧对应的频谱图连接起来,以时间作为横轴,频率作为纵轴,颜色深浅表示幅度,如图\ref{fig:frequency_time_fig}下面红图所示,就组成了语谱图。语谱图实际上是一个三维图,横轴时间,纵轴频率,颜色深浅表示幅度大小,一般来说,颜色越深,表示幅度值越大。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{frequency_spectrum.jpeg}
\caption{频谱图 \label{fig:frequency_spectrum}}
\end{figure}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{frequency_time_fig.png}
\caption{波形和对应的语谱图 \label{fig:frequency_time_fig}}
\end{figure}
\section{语言学}
语言学研究人类的语言,计算语言学则是一门跨学科的研究领域,试图找出自然语言的规律,建立运算模型,语音合成其实就是计算语言学的子领域之一。在语音合成中,一般需要将文本转换为对应的音素,然后再将音素输入到后端模型中,因此需要为每个语种甚至方言构建恰当合理的音素体系。相关概念如下。
\begin{enumerate}
\item 音素(phoneme):也称音位,是能够区别意义的最小语音单位,同一音素由不同人/环境阅读,可以形成不同的发音。
\item 字素(grapheme):音素对应的文本。具体的区别参见:\href{https://www.youtube.com/watch?v=25r1fyoorko}{Phonemes, Graphemes, and Morphemes!}
\item 发音(phone): 某个音素的具体发音。实际上,phoneme和phone都是指的是音素,音素可具化为实际的音,该过程称为音素的语音体现。一个音素可能包含着几个不同音值的音,因而可以体现为一个音、两个音或更多的同位音。但是在一些论述中,phoneme偏向于表示发音的符号,phone更偏向于符号对应的实际发音,因此phoneme可对应无数个phone。
\item 音节(syllable):音节由音素组成。在汉语中,除儿化音外,一个汉字就是一个音节。如wo3(我)是一个音节,zhong1(中)也是一个音节。
\end{enumerate}
\subsection{国际音标简介}
国际音标(International Phonetic Alphabet,IPA)是一种通用的注音系统,一套注音体系可以标注多种语言。对于汉语来说,使用国际音标和使用拼音标注发音效果是相同的;但是如果希望实现多语言的注音,就必须采用统一的注音,IPA就是这样一种比较好的发音标注形式。
因为人类语音差异很大,有限的拉丁字母远不够用,于是就需要改变字形和借用其它语言的字母来补充。也就是说,IPA以拉丁字母(罗马字母)的小写印刷体为主,如:a、b、c、d、f、g、h、i、j、k、p等。在不够用时,使用以下几种方法来补充,包括:
\begin{enumerate}
\item 使用拉丁字母大写印刷体或书写体(草体);
\item 颠倒或者改变拉丁字母的字形,如:倒置e,卷尾c,右弯尾d,长右腿n等;
\item 借用其它语言字母;
\item 新制字母;
\item 在字母上加符号。
\end{enumerate}
\subsection{IPA的字母和发音}
读音上,为照顾习惯,大多数符号仍读拉丁语或其它语言的原音。IPA追求一个字符表示一个发音,不会出现在一些语言中,如英语用“th”、“sh”表示一个发音的情况。IPA字母的发音,有些和原始的希腊字母发音相同,但有些又和英语等语言发音相同,其大致的规则包括:
\begin{enumerate}
\item 元音字母:如[a]、[o]、[i]等发音和意大利语、西班牙语无较大差别;
\item 辅音字母:如[m]、[n]、[z]、[p]、[b]的发音则接近于英语;
\item 其他字母:如[y]和德语或芬兰语中的y类似,而[j]与英语的y发音接近。
\end{enumerate}
IPA的字母构成会随着规范的修改而变动,2018年发布的标准中,IPA的字母有107个,包括了59个肺部气流辅音,10个非肺部气流辅音,28个元音和10个其他字母,如下表\ref{fig:ipa_consant}-\ref{fig:other_alphabet}所示:
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{ipa_consant.png}
\caption{肺部气流辅音(59个) \label{fig:ipa_consant}}
\end{figure}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{ipa_consant_not.png}
\caption{非肺部气流辅音(10个) \label{fig:ipa_consant_not}}
\end{figure}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{vowel.png}
\caption{(元音) \label{fig:vowel}}
\end{figure}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{other_alphabet.png}
\caption{(其它字母) \label{fig:other_alphabet}}
\end{figure}
在国际音标表中,同一列、或同一行的音标,在发音方法上有相同之处,因此也就具有相似的性质,这为语音的研究提供了较大的便利。“国际音标表”是语音学的基础,就如同“元素周期表”是化学的基础。一些开源工具,比如\href{https://github.com/espeak-ng/espeak-ng}{eSpeak NG Text-to-Speech}、\href{https://github.com/dmort27/epitran}{Epitran}实现了各语种的字素转国际音标。但是,这些国际音标开源工具并没有提供对方言的支持,比如上海话、闽南语的字素转音素;国际音标本身识记较为复杂,学习成本比较高,并且为了照顾世界所有语种,音素的划分上较为精细,因此国际音标是语音合成中音素体系的重要参考方案,但非最佳方案。
\subsection{音系学}
对于语音合成来说,需要了解语言学的分支之一:音系学,以便更好地制定适用于一个语种语音合成系统的音素体系。这里需要探讨三个问题:音位数量,这里的音位和音素概念区别不大,音素不针对一个语种,是一个最小的语音单位,音位是针对一个特定语言的,具有区别意义的最小语音单位,参见\href{https://www.zhihu.com/question/27250496}{音素和音位的区别与联系是什么?};语音配列,也就是语音符号的组合规律,哪些音段的组合是不被允许的,音段出现的位置有哪些限制;音系交替,音与音同时出现时,彼此受影响会导致哪些形式的变化,这涉及到音系过程。音系过程可以理解为一个音段受所处语音环境或语法环境的影响而产生变化的过程,音系过程的种类有很多,比如同化和异化两种过程。
音位数量的确定牵扯到对比分布和互补分布两个概念。如果A和B处于对比分布时,那么甲和乙处于同样的语言环境中时,就会引起意义的不同。比如英语中的[p]和[b]就处于对比分布,当它们处于相同的语言环境中时,比如pin[\underline{p}in]和bin[\underline{b}in],但是两个单词的意义完全不同,因此[p]和[b]就分属两个不同的音位。而假如A和B处于互补分布时,那么甲和乙不可能出现在同样的语音环境中,例如英语中的[p]处于重读音节首时pig[\underline{p}ig],往往表现为送气的[$p^h$],而在[s]后面时spit[s\underline{p}it],往往表现为不送气的[p],送气的[$p^h$]和不送气的[p]不会出现在同一语音环境中,可以说,它们是同一个音位在不同语音环境中的音位变体。因此,\lstinline{音位处于对比分布,而音位变体处于互补分布}。确立音位的做法便是寻找最小对比对,也就是说寻找音位时要满足:1. 在相同的语音环境;2. 单词的意思不同。最直接的做法就是找两个意义不同的的单词,并且只有在一个位置上有不同的音段,在其它位置上的音段都相同,这一对单词就是最小对比对。比如ban[\underline{b}an]和man[\underline{m}an]这对最小对比对中,除了[b]和[m]之外,其它音段都相同,正因为[b]和[m],这两个单词的意义也不同。 因此归纳音位的原则有:对立互补原则和语音相似原则。
语音配列是一个语种中,对于一个单词、语素或音节中可能出现的元音和辅音序列制约条件的集合。比如英语单词“wtist”是不可能存在的,因为[w]是滑音(glide),而[t]则是塞擦音(plosive),在英语中如果滑音和塞擦音同时出现在词首,则塞擦音一定在滑音的前面,比如twin,因此“wtist”一定是非法英语单词。
同化是指一个音段变得和另一个音段相似的音系学过程,根据同化的方向,这一过程又可以分为顺同化和逆同化。顺同化又称遗留同化,是指后面的音段被前面的音段同化了,比如英语中的复数和动词的过去式。英语单词“cup”词缀辅音和前面词干尾的辅音在清浊上是一致的,音系学上认为复数形式本来的形式是[z],是一个浊音,但当词干尾的辅音是清音比如[t]、[k]、[p],这个浊辅音就会被前面的清音同化为清辅音[s],因此“cup”的复数形式“cups”读音就是[kaps]而不是[kapz]。顺同化是从左到右的同化,逆同化就是从右到左的同化。逆同化又称为先行同化,是前面的音段被后面音段同化的过程。比如汉语普通话中,当两个第三声的字放在一起,第一个就会变成第二声,如永(yong3)、远(yuan3),组成单词“永远”时,读音为“yong2 yuan3”。
对于目前类似于Tacotron这样的端到端声学模型来说,给定的音素体系一般\lstinline{只需确定音位,对于各种协同发音导致的音位变体,则可以不加区分。}例如对于法语这样存在同一个音素在不同单词中发音不同的语种,文本前端的音素体系可以只关注音位,音位变体由后端模型自行学习。为了模型增强可控性,也可以尝试结合词面信息,根据上下文给出音位不同的符号表示。比如s[s]这个字母,在不同语境中可能存在不同的音位变体,后面结合字母a是一个音位变体,因此将此时字母s的音位变体标记为[sa];后面结合字母b可能又是一个音位变体,这时则将该s的音位变体标记为[sb]。
\subsection{参考资料}
\begin{enumerate}
\item \href{https://space.bilibili.com/363660379}{十分语言学(视频扫盲课程)}
\item \href{http://media.openonline.com.cn/media_file/rm/huashi0703/yuyanxgl/mulu.htm}{语言学概论}
\item \href{https://zhuanlan.zhihu.com/p/470501423}{《语音模式》笔记(上):肺部气流辅音}
\item \href{https://zhuanlan.zhihu.com/p/471036291}{《语音模式》笔记(下):非肺部辅音、元音、一些杂谈}
\item \href{https://www.zhihu.com/column/yulinhanshe}{语林寒舍-Huisje in het Taalbos}
\end{enumerate}
\section{音频格式}
\begin{enumerate}
\item *.wav: 波形无损压缩格式,是语音合成中音频语料的常用格式,主要的三个参数:采样率,量化位数和通道数。一般来说,合成语音的采样率采用16kHz、22050Hz、24kHz,对于歌唱合成等高质量合成场景采样率可达到48kHz;量化位数采用16bit;通道数采用1.
\item *.flac: Free Lossless Audio Codec,无损音频压缩编码。
\item *.mp3: Moving Picture Experts Group Audio Player III,有损压缩。
\item *.wma: Window Media Audio,有损压缩。
\item *.avi: Audio Video Interleaved,avi文件将音频和视频包含在一个文件容器中,允许音视频同步播放。
\end{enumerate}
\section{数字信号处理}
\subsection{模数转换}
模拟信号到数字信号的转换(Analog to Digital Converter,ADC)称为模数转换。
奈奎斯特采样定理:要从抽样信号中无失真地恢复原信号,抽样频率应大于2倍信号最高频率。抽样频率小于2倍频谱最高频率时,信号的频谱有混叠。抽样频率大于2倍频谱最高频率时,信号的频谱无混叠。如果对语音模拟信号进行采样率为16000Hz的采样,得到的离散信号中包含的最大频率为8000Hz。
\subsection{频谱泄露}
音频处理中,经常需要利用傅里叶变换将时域信号转换到频域,而一次快速傅里叶变换(FFT)只能处理有限长的时域信号,但语音信号通常是长的,所以需要将原始语音截断成一帧一帧长度的数据块。这个过程叫\lstinline{信号截断},也叫\lstinline{分帧}。分完帧后再对每帧做FFT,得到对应的频域信号。FFT是离散傅里叶变换(DFT)的快速计算方式,而做DFT有一个先验条件:分帧得到的数据块必须是整数周期的信号,也即是每次截断得到的信号要求是周期主值序列。
但做分帧时,很难满足\lstinline{周期截断},因此就会导致\lstinline{频谱泄露}。要解决非周期截断导致的频谱泄露是比较困难的,可以通过\lstinline{加窗}尽可能减少频谱泄露带来的影响。窗类型可以分为汉宁窗、汉明窗、平顶窗等。虽然加窗能够减少频谱泄露,但加窗衰减了每帧信号的能量,特别是边界处的能量,这时加一个合成窗,且overlap-add,便可以补回能量。参见:\href{https://zhuanlan.zhihu.com/p/339692933}{频谱泄露和加窗}。
\subsection{频率分辨率}
频率分辨率是指将两个相邻谱峰分开的能力,在实际应用中是指分辨两个不同频率信号的最小间隔。
\section{其它概念}
\begin{enumerate}
\item 波形(waveform): 声音是由声源振动产生的波。
\item 信道: 通信的通道Channel,是信号传输的媒介。
\item 声道: 声音在录制和播放时,在不同空间位置采集或回放相互独立的音频信号,因此声道数也就是声音录制时的音源数量或回放时相应的扬声器数量。
\item 采样率:单位时间内从连续信号中提取并组成离散信号的采样个数,音频常用单位kHz。
\item 采样位数/采样深度:数字信号的二进制位数,与每次采样的可能值个数有关,音频常用单位bit。常见的音频格式: \lstinline{16kHz,16bit}中16kHz指的是采样率,16bit表示采样位深。
\item 信噪比(SNR):和声压级类似,单位仍采用分贝,数值越高,表示声音越干净,噪音比例越小。
\item LPC。线性预测系数。LPC的基本思想是,当前时刻的信号可以用若干历史时刻信号的线性组合来估计,通过使实际语音的采样值和线性预测的采样值之间达到均方差最小,即可得到一组线性预测系数。求解LPC系数可以采用自相关法、协方差法、格型法等快速算法。
\begin{note}
语音信号的数字表示可以分为两类:\lstinline{波形表示}和\lstinline{参数表示},波形表示仅通过采样和量化保存模拟信号的波形;而参数表示将语音信号表示为某种语音产生模型的输出,是对数字化语音进行分析和处理之后得到的。
\end{note}
\begin{note}
利用同态处理方法,对语音信号求离散傅里叶变换之后取对数,再求反变换就可以得到倒谱系数。其中,LPC倒谱(LPCCEP)是建立在LPC谱上的,而梅尔倒谱系数(Mel Frequency Cepstrum Coefficient,MFCC)则是基于梅尔频谱的。
\end{note}
\item LPCC。LPCC特征假定信号存在一种线性预测的结构,这对于周期特性的浊音描述比较准确,而对于辅音则相当于强加了一种错误的结构。MFCC相邻帧特征近乎独立,所以能够比较好地描述辅音,但忽略了信号可能的内在结构,如相邻帧之间的关联,经验表明MFCC更好用,并且经常会加入差分特征以减弱其独立性。
\begin{note}
线性预测倒谱系数(LPCC)是根据声管模型建立的特征参数,是对声道响应的特征表征。梅尔频谱倒谱系数(MFCC)是基于人类听觉机理提取出的特征参数,是对人耳听觉的特征表征。
\end{note}
\end{enumerate}
对于一段1秒的波形,假设采样率16kHz,采样位深16bit,则包含样本点 $1\times 16000=16000$ 个,所占容量 $1\times 16000\times 16 /8=32000$ 字节(B)。
\chapter{语音特征提取}
原始信号是不定长的时序信号,不适合作为机器学习的输入。因此一般需要将原始波形转换为特定的特征向量表示,该过程称为语音特征提取。
\section{预处理}
包括预加重、分帧和加窗。
\subsection{预加重}
语音经过说话人的口唇辐射发出,受到唇端辐射抑制,高频能量明显降低。一般来说,当语音信号的频率提高两倍时,其功率谱的幅度下降约6dB,即语音信号的高频部分受到的抑制影响较大。在进行语音信号的分析和处理时,可采用预加重(pre-emphasis)的方法补偿语音信号高频部分的振幅,在傅里叶变换操作中避免数值问题,本质是施加高通滤波器。假设输入信号第 $n$ 个采样点为 $x[n]$ ,则预加重公式如下:
\begin{equation}
x'[n]=x[n]-a\times x[n-1]
\end{equation}
其中, $a$ 是预加重系数,一般取 $a=0.97$ 或 $a=0.95$ 。
\subsection{分帧}
语音信号是非平稳信号,考虑到发浊音时声带有规律振动,即基音频率在短时范围内时相对固定的,因此可以认为语音信号具有短时平稳特性,一般认为10ms~50ms的语音信号片段是一个准稳态过程。短时分析采用分帧方式,一般每帧帧长为20ms或50ms。假设语音采样率为16kHz,帧长为20ms,则一帧有 $16000\times 0.02=320$ 个样本点。
相邻两帧之间的基音有可能发生变化,如两个音节之间,或者声母向韵母过渡。为确保声学特征参数的平滑性,一般采用重叠取帧的方式,即相邻帧之间存在重叠部分。一般来说,帧长和帧移的比例为 $1:4$ 或 $1:5$ 。
\subsection{加窗}
分帧相当于对语音信号加矩形窗,矩形窗在时域上对信号进行截断,在边界处存在多个旁瓣,会发生频谱泄露。为了减少频谱泄露,通常对分帧之后的信号进行其它形式的加窗操作。常用的窗函数有:汉明(Hamming)窗、汉宁(Hanning)窗和布莱克曼(Blackman)窗等。
汉明窗的窗函数为:
\begin{equation}
W_{ham}[n]=0.54-0.46\mathop{cos}(\frac{2\pi n}{N}-1)
\end{equation}
其中, $0\leq n\leq N-1$ ,$N$ 是窗的长度。
汉宁窗的窗函数为:
\begin{equation}
W_{han}[n]=0.5[1-\mathop{cos}(\frac{2\pi n}{N}-1)]
\end{equation}
其中, $0\leq n\leq N-1$ , $N$ 是窗的长度。
\section{短时傅里叶变换}
人类听觉系统与频谱分析紧密相关,对语音信号进行频谱分析,是认识和处理语音信号的重要方法。声音从频率上可以分为纯音和复合音,纯音只包含一种频率的声音(基音),而没有倍音。复合音是除了基音之外,还包含多种倍音的声音。大部分语音都是复合音,涉及多个频率段,可以通过傅里叶变换进行频谱分析。
每个频率的信号可以用正弦波表示,采用正弦函数建模。基于欧拉公式,可以将正弦函数对应到统一的指数形式:
\begin{equation}
e^{jwn}=\mathop{cos}(wn)+j\mathop{sin}(wn)
\end{equation}
正弦函数具有正交性,即任意两个不同频率的正弦波乘积,在两者的公共周期内积分等于零。正交性用复指数运算表示如下:
\begin{equation}
\int_{-\infty}^{+\infty}e^{j\alpha t}e^{-j\beta t}dt=0,\quad if\ \alpha\neq \beta
\end{equation}
基于正弦函数的正交性,通过相关处理可以从语音信号分离出对应不同频率的正弦信号。对于离散采样的语音信号,可以采用离散傅里叶变换(DFT)。DFT的第 $k$ 个点计算如下:
\begin{equation}
X[k]=\sum_{n=0}^{N-1} x[n]e^{-\frac{j2\pi kn}{K}},\quad k=0,1,...,K-1
\end{equation}
其中, $x[n]$ 是时域波形第 $n$ 个采样点值, $X[k]$ 是第 $k$ 个傅里叶频谱值, $N$ 是采样点序列的点数, $K$ 是频谱系数的点数,且 $K\geq N$ 。利用DFT获得的频谱值通常是复数形式,这是因为上式中,
\begin{equation}
e^{-\frac{j2\pi kn}{K}}=\mathop{cos}(\frac{2\pi kn}{K})-j\mathop{sin}(\frac{2\pi kn}{K})
\end{equation}
则
\begin{equation}
X[k]=X_{real}[k]-jX_{imag}[k]
\end{equation}
其中,
\begin{equation}
X_{real}[k]=\sum_{n=0}^{N-1}x[n]\mathop{cos}(\frac{2\pi kn}{K})
\end{equation}
\begin{equation}
X_{imag}[k]=\sum_{n=0}^{N-1}x[n]\mathop{sin}(\frac{2\pi kn}{K})
\end{equation}
$N$ 个采样点序列组成的时域信号经过DFT之后,对应 $K$ 个频率点。经DFT变换得到信号的频谱表示,其频谱幅值和相位随着频率变化而变化。
在语音信号处理中主要关注信号的频谱幅值,也称为振幅频谱/振幅谱:
\begin{equation}
X_{magnitude}[k]=\sqrt{X_{real}[k]^2+X_{imag}[k]^2}
\end{equation}
能量频谱/能量谱是振幅频谱的平方:
\begin{equation}
X_{power}[k]=X_{real}[k]^2+X_{imag}[k]^2
\end{equation}
各种声源发出的声音大多由许多不同强度、不同频率的声音组成复合音,在复合音中,不同频率成分与能量分布的关系称为声音的频谱,利用频谱图表示各频率成分与能量分布之间的关系,频谱图横轴是频率(Hz),纵轴是幅度(dB)。
通过对频域信号进行逆傅里叶变换(IDFT),可以恢复时域信号:
\begin{equation}
x[n]=\frac{1}{K}\sum_{k=0}^{K-1}X[k]e^{\frac{j2\pi kn}{N}},\quad n=0,1,...,N-1
\end{equation}
离散傅里叶变换(DFT)的计算复杂度为 $O(N^2)$ ,可以采用快速傅里叶变换(FFT),简化计算复杂度,在 $O(N\mathop{log}_2 N)$ 的时间内计算出DFT。在实际应用中,对语音信号进行分帧加窗处理,将其分割成一帧帧的离散序列,可视为短时傅里叶变换(STFT):
\begin{equation}
X[k,l]=\sum_{n=0}^{N-1} x_l[n]e^{-\frac{j2\pi nk}{K}}=\sum_{n=0}^{N-1} w[n]x[n+lL]e^{-\frac{j2\pi nk}{K}}
\end{equation}
其中, $K$ 是DFT后的频率点个数, $k$ 是频率索引, $0\leq k< K$ 。$X[k,l]$ 建立起索引为 $lL$ 的时域信号,与索引为 $k$ 的频域信号之间的关系。
\section{听觉特性}
\subsection{梅尔滤波}
人类对不同频率的语音有不同的感知能力:
\begin{enumerate}
\item 1kHz以下,人耳感知与频率成线性关系。
\item 1kHz以上,人耳感知与频率成对数关系。
\end{enumerate}
因此,人耳对低频信号比高频信号更为敏感。因此根据人耳的特性提出了一种mel刻度,即定义1个mel刻度相当于人对1kHz音频感知程度的千分之一,mel刻度表达的是,从线性频率到“感知频率”的转换关系:
\begin{equation}
mel(f)=2595\mathop{lg}(1+\frac{f}{700})
\end{equation}
\begin{lstlisting}
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0, 5000, 50000)
y = 2595*np.log10(1+x/700)
x0 = 1000
y0 = 2595*np.log10(1+x0/700)
plt.plot(x, y)
plt.scatter(x0, y0)
plt.plot([x0, x0], [0, y0], 'k--')
plt.plot([0, x0], [x0, y0], 'k--')
plt.xlabel('f (Hz)')
plt.ylabel('Mel(f)')
plt.title('relationship between linear and mel scale')
plt.xlim(0, x[-1])
plt.ylim(0, y[-1])
plt.savefig('mel_vs_f.png')
plt.show()
\end{lstlisting}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{mel_vs_f.png}
\caption{mel刻度和频率之间的关系 \label{fig:mel_vs_f}}
\end{figure}
人们根据一系列心理声学实验得到了类似耳蜗作用的滤波器组,用于模拟人耳不同频段声音的感知能力,也就是多个三角滤波器组成的mel频率滤波器组。每个滤波器带宽不等,线性频率小于1000Hz的部分为线性间隔,而线性频率大于1000Hz的部分为对数间隔。同样地,将梅尔频率转换到线性频率的公式为:
\begin{equation}
f_{mel}^{-1}=700\cdot (10^{\frac{f_{mel}}{2595}}-1)
\end{equation}
\subsection{Bark滤波}
声音的响度,反映人对不同频率成分声强/声音强弱的主观感受。响度与声强、频率的关系可以用\lstinline{等响度轮廓曲线}表示。
人耳对响度的感知有一个范围,当声音低于某个响度时,人耳是无法感知到的,这个响度值称为听觉阈值,或称听阈。在实际环境中,但一个较强信号(掩蔽音)存在时,听阈就不等于安静时的阈值,而是有所提高。这意味着,邻近频率的两个声音信号,弱响度的声音信号会被强响度的声音信号所掩蔽(Mask),这就是\lstinline{频域掩蔽}。
根据听觉频域分辨率和频域掩蔽的特点,定义能够引起听觉主观变化的频率带宽为一个\lstinline{临界频带}。一个临界频带的宽度被称为一个Bark,Bark频率 $Z(f)$ 和线性频率 $f$ 的对应关系定义如下:
\begin{equation}
Z(f)=6\mathop{ln}(\frac{f}{600}+((\frac{f}{600})^2+1)^{\frac{1}{2}})
\end{equation}
其中,线性频率 $f$ 的单位为Hz,临界频带 $Z(f)$ 的单位为Bark。
\section{倒谱分析}
语音信号的产生模型包括发生源(Source)和滤波器(Filter)。人在发声时,肺部空气受到挤压形成气流,气流通过声门(声带)振动产生声门源激励 $e[n]$ 。对于浊音,激励 $e[n]$ 是以基音周期重复的单位冲激;对于清音, $e[n]$ 是平稳白噪声。该激励信号 $e[n]$ 经过咽喉、口腔形成声道的共振和调制,特别是舌头能够改变声道的容积,从而改变发音,形成不同频率的声音。气流、声门可以等效为一个激励源,声道等效为一个时变滤波器,语音信号 $x[n]$ 可以被看成激励信号 $e[n]$ 与时变滤波器的单位响应 $v[n]$ 的卷积:
\begin{equation}
x[n]=e[n]*v[n]
\end{equation}
已知语音信号 $x[n]$ ,待求出上式中参与卷积的各个信号分量,也就是解卷积处理。除了线性预测方法外,还可以采用\lstinline{倒谱分析}实现解卷积处理。倒谱分析,又称为\lstinline{同态滤波},采用时频变换,得到对数功率谱,再进行逆变换,分析出倒谱域的倒谱系数。
同态滤波的处理过程如下:
\begin{enumerate}
\item 傅里叶变换。将时域的卷积信号转换为频域的乘积信号:
\begin{equation}
{\rm DFT}(x[n])=X[z]=E[z]V[z]
\end{equation}
\item 对数运算。将乘积信号转换为加性信号:
\begin{equation}
{\rm log} X[z]={\rm log}E[z]+{\rm log}V[z]=\hat{E}[z]+\hat{V}[z]=\hat{X}[z]
\end{equation}
\item 傅里叶反变换。得到时域的语音信号\lstinline{倒谱}。
\begin{equation}
Z^{-1}(\hat{X}[z])=Z^{-1}(\hat{E}[z]+\hat{V}[z])=\hat{e}[n]+\hat{v}[z]\approx \hat{x}[n]
\end{equation}
\end{enumerate}
在实际应用中,考虑到离散余弦变换(DCT)具有最优的去相关性能,能够将信号能量集中到极少数的变换系数上,特别是能够将大多数的自然信号(包括声音和图像)的能量都集中在离散余弦变换后的低频部分。一般采用DCT反变换代替傅里叶反变换,上式可以改写成:
\begin{equation}
\hat{c}[m]=\sum_{k=1}^N{\rm log}X[k]{\rm cos}(\frac{\pi (k-0.5)m}{N}),\quad m=1,2,...,M
\end{equation}
其中,$X[k]$是DFT变换系数, $N$ 是DFT系数的个数, $M$ 是DCT变换的个数。
此时, $\hat{x}[n]$ 是复倒谱信号,可采用逆运算,恢复出语音信号,但DCT不可逆,从倒谱信号 $\hat{c}[m]$ 不可还原出语音 $x[n]$ 。
\section{常见的声学特征}
在语音合成中,常用的声学特征有梅尔频谱(Mel-Spectrogram)/滤波器组(Filter-bank,Fank),梅尔频率倒谱系数(Mel-Frequency Cepstral Coefficient,MFCC)等。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{text_to_speech_acoustic_feature.png}
\caption{常用的声学特征 \label{fig:acoustic_feature}}
\end{figure}
接下来重点介绍FBank和MFCC的计算过程。
\subsection{FBank}
FBank的特征提取过程如下:
\begin{enumerate}
\item 将信号进行预加重、分帧、加窗,然后进行短时傅里叶变换(STFT)获得对应的\lstinline{频谱}。
\item 求频谱的平方,即\lstinline{能量谱}。进行梅尔滤波,即将每个滤波频带内的能量进行叠加,第 $k$ 个滤波器输出功率谱为 $X[k]$ 。
\item 将每个滤波器的输出取对数,得到相应频带的对数功率谱。
\begin{equation}
Y_{\rm FBank}[k]={\rm log}X[k]
\end{equation}
\end{enumerate}
FBank特征本质上是对数功率谱,包括低频和高频信息。相比于语谱图,FBank经过了梅尔滤波,依据人耳听觉特性进行了压缩,抑制了一部分人耳无法感知的冗余信息。
\subsection{MFCC}
MFCC和FBank唯一的不同就在于,获得FBank特征之后,再经过反离散余弦变换,就得到 $L$ 个MFCC系数。在实际操作中,得到的 $L$ 个MFCC特征值可以作为\lstinline{静态特征},再对这些静态特征做一阶和二阶差分,得到相应的静态特征。
\section{具体操作}
\subsection{利用librosa读取音频}
\begin{lstlisting}
from matplotlib import pyplot as plt
import numpy as np
import librosa
# 利用librosa读取音频
input_wav_path = r'test.wav'
y, sr = librosa.load(input_wav_path)
y_num = np.arange(len(y))
# 截取前0.3s的音频
sample_signal = y[0:int(sr*0.3)]
sample_num = np.arange(len(sample_signal))
plt.figure(figsize=(11, 7), dpi=500)
plt.subplot(211)
plt.plot(y_num/sr, y, color='black')
plt.plot(sample_num/sr, sample_signal, color='blue')
plt.xlabel('Time (sec)')
plt.ylabel('Amplitude')
plt.title('Waveform')
plt.subplot(212)
plt.plot(sample_num/sr, sample_signal, color='blue')
plt.xlabel('Time (sec)')
plt.ylabel('Amplitude')
plt.title('0~0.3s waveform')
plt.tight_layout()
plt.savefig('waveform.png', dpi=500)
plt.show()
\end{lstlisting}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{waveform.png}
\caption{波形图 \label{fig:waveform}}
\end{figure}
音频有不同的编码类型,librosa默认采取浮点格式读取,即读取的样本点均是 $[-1,-1]$ 之间的浮点值。更详细的文档参见\href{http://sox.sourceforge.net/sox.html}{SoX}的\lstinline{Input & Output File Format Options}部分。
\begin{table}[htbp]
\centering
\caption{SoX音频格式}
\begin{tabular}{llll}
\toprule
选项 & 描述 & 常见可选项 \\
\midrule
b & 每个编码样本所占的数据位数(位深) & 8/16/32 \\
c & 音频文件包含的通道数 & 1/2 \\
e & 音频文件的编码类型 & signed-integer/unsigned-integer/floating-point \\
r & 音频文件的采样率 & 16k/16000/22050 \\
t & 音频文件的文件类型 & raw/mp3 \\
\bottomrule
\end{tabular}
\end{table}
\subsection{提取梅尔频谱}
\begin{lstlisting}
sample_rate = 16000
preemphasis = 0.97
n_fft = 1024
frame_length = 0.05 # ms
frame_shift = 0.01 # ms
fmin = 0
fmax = sample_rate/2
eps = 1e-10
n_mel = 80
win_length = int(sample_rate*frame_length)
hop_length = int(sample_rate*frame_shift)
mel_basis = librosa.filters.mel(
sample_rate, n_fft, n_mel, fmin=fmin, fmax=fmax)
def get_spectrogram(input_wav_path):
y, sr = librosa.load(input_wav_path)
y = np.append(y[0], y[1:]-preemphasis*y[:-1])
linear = librosa.stft(
y=y, n_fft=n_fft, hop_length=hop_length, win_length=win_length)
mag = np.abs(linear)
mel = np.dot(mel_basis, mag)
mel = np.log10(np.maximum(eps, mel))
mel = mel.T.astype(np.float32) # (T,n_mels)
return mel
# plt.switch_backend('agg')
def plot_spectrogram(spectrogram, file_path):
spectrogram = spectrogram.T
fig = plt.figure(figsize=(16, 9))
plt.imshow(spectrogram, aspect='auto', origin='lower')
plt.colorbar()
plt.xlabel('frames')
plt.tight_layout()
plt.savefig(file_path, dpi=500)
plt.show()
mel_spec = get_spectrogram(input_wav_path)
plot_spectrogram(mel_spec, 'mel_spectrogram.png')
\end{lstlisting}
\begin{figure}[htbp]
\centering
\includegraphics[width=0.6\textwidth]{mel_spectrogram.png}
\caption{梅尔频谱 \label{fig:mel_spectrogram}}