merlin語音合成框架,關於合成部分的流程記錄
代碼基於github:CSTR-Edinburgh/merlin
merlin合成(中文)的流程可分爲以下5個部分:
- 漢字轉phone
- phone轉爲duration model的輸入
- duration model的輸出轉爲acoustic model的輸入
- acoustic model的輸出轉爲WORLD的輸入
- WORLD生成音頻
下面分別記錄一下時長模型和聲學模型的合成流程:
duration model
- 加載問題集
- questions-mandarin.hed中的每一行轉爲若干個正則,QS439行,CQS28行
- 解析lab,prompt-lab/.lab --> gen-lab/.labbin
- 對原始lab中的每一行內容,先用439個QS的正則去search,只要某個QS其中有一個正則search到了,就置爲1,否則置爲0,於是得到(1, 439)維的one-hot向量
- 同理,對CQS,匹配該行lab中相關的數字,search到了就置爲該數字,否則置爲-1,得到(1, 28)的正數向量
- 合併上述兩個向量,得到(1, 467)
- 最終得到(lab行數, 467)的矩陣,存入gen-lab/.labbin
- remove_silence, 然後min_max_norm, prompt-lab/.lab + gen-lab/.labbin --> gen-lab/.lab
- 從prompt-lab/.lab得到不包含sil的行(其實就只有首尾兩行是sil),保留gen-lab/.labbin的這些行,存入gen-lab/.lab
- duration_model/inter_module/label_norm_HTS_467.dat 得到(934, 1)的向量,(該文件在train時find_min_max_values後寫入),分別爲467維的min_vector和max_vector,用於歸一化
- run model
- 從gen-lab/.lab讀取數據作爲input, 假設lab文件有58行(已去除首尾靜音行),則輸入爲(58, 467), 輸出爲(58, 1)
- 將輸出存爲gen-lab/.cmp
- 從duration_model/inter_module/norm_info__dur_1_MVN.dat中獲的cmp_min_vector與cmp_max_vector兩個數值
- 對gen-lab/.cmp的內容進行均值方差歸一化,重新存入
- 對gen-lab/.cmp進行四捨五入,存入gen-lab/.dur
- 對gen-lab/.dur的每個值*5*10000,作爲相應行phone的持續時間,根據prompt-lab/.lab和時間信息一起寫入gen-lab/.lab,這樣lab就帶時間了(最終得到的gen-lab/.lab含靜音行,與prompt-lab/.lab行數一致)
acoustic model
- 將gen-lab/01.lab每一phone轉爲若干個幀(默認幀移爲5ms),每一幀的維度爲471(對應的phone維度467+4維的cc_feat_matrix),4維的最後一維是通過時長計算出的幀數。如一個(58, 467)的lab,轉換後的維度爲(1211, 471), 1211 爲所有phones的幀數之和,存入 wav/01.labbin(幀)
- 幀級別的remove_silence,刪除首尾的各60幀靜音,gen-lab/.lab + wav/.labbin --> wav/.lab(1211-60*2, 471)
- acoustic_model/inter_module/label_norm_HTS_471.dat得到max_vector和min_vector,維度均爲471,用於歸一化,重新存入wav/.lab(1211, 471)
- run_model
Tips
- wav/.cmp生成.mgc、.lf0、.bap時,這兒需要用到解矩陣方程, 爲了提高計算效率,使用的是BandMat類型的矩陣,是否需要解方程由參數do_MLPG(默認爲true)控制
- 合成的完整 c++ code後續會放到github
附:醜陋的流程圖(數字表示被處理成的維度)
duration model | acoustic model |
---|---|