赞
踩
使用商业TTS合成语音,再格式化,这样的录音没有爆破音、回音、底躁。
这里分享一个已经合成好的拼音集 baidu5003-sec-wav.tar.gz 百度网盘 请输入提取码,提取码:9f6f(下同),使用这个音调的拼音集可以跳过下述的 1~7 步直接执行第8、9步。如果要使用其他音调,需要执行 1~ 9步。
1、从 http://xh.5156edu.com
爬取拼音列表
htmlshell.jar - 使用jsoup编写的java组件包,见 htmlshell.jar(百度网盘 请输入提取码)
- #!/bin/bash
-
- pinyinfile=pinyin.txt
- pinyinbase=http://xh.5156edu.com
- pinyinurl=$pinyinbase/pinyi.html
-
- pinyin=`java -jar htmlshell.jar $pinyinurl fontbox html out | awk -F '"' '{print "'"$pinyinbase/"'"$4}'`
-
- echo -en > $pinyinfile
- for url in $pinyin;
- do
- java -jar htmlshell.jar $url font_14 text | grep -v "未分类" >> $pinyinfile
- done
爬取下来的拼音有1317个,其中有两组重复出现的拼音,即有效拼音为 1315 个。爬取的结果如下:
- ā
- á
- ǎ
- à
- āi
- ái
- ǎi
- ài
- ān
- án
2、脱敏某些拼音,并在每行上加上句号“。”,即:
bi 的拼音会识别为“敏感”音
- bī
- bí
- bǐ
- bì
- # 把上面的拼音脱敏成以下内容
- 偪。
- 比。
- 笔。
- 闭。
shun 的拼音会识别为“敏感”音
- shūn
- shǔn
- shùn
- # 把上面的拼音脱敏成以下内容
- 楯。
- 吮。
- 顺。
“nun。o。” 的发出错,发成连音,不就方便语音切割
- # 这样的组合会使百度发音出错,出现连音
- nún。
- ō。
- # 改为即可
- 黁。
- ō。
3、使用https://ai.baidu.com/tech/speech/tts_online
百度在线免费语音合成,每次最多可以合成200个UTF-8字符。
百度付费版 tts 支持直接返回二进制音频数据,百度在线免费版返回的是音频的 base64 编码数据。
使用百度在线免费试用版时,使用curl 命令如下:
- curl 'https://ai.baidu.com/aidemo' \
- -H 'Connection: keep-alive' \
- -H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"' \
- -H 'sec-ch-ua-mobile: ?0' \
- -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36' \
- -H 'sec-ch-ua-platform: "Windows"' \
- -H 'Content-Type: application/x-www-form-urlencoded' \
- -H 'Accept: */*' \
- -H 'Origin: https://ai.baidu.com' \
- -H 'Sec-Fetch-Site: same-origin' \
- -H 'Sec-Fetch-Mode: cors' \
- -H 'Sec-Fetch-Dest: empty' \
- -H 'Referer: https://ai.baidu.com/tech/speech/tts_online' \
- -H 'Accept-Language: zh-CN,zh;q=0.9' \
- --data-raw 'type=tns&per=4003&spd=5&pit=5&vol=9&aue=6&tex=n%C3%BC%C3%A8%E3%80%82%0Anu%C3%B3%E3%80%82%0Anu%C3%B2%E3%80%82%0A%E9%BB%81%E3%80%82%0A%C5%8D%E3%80%82%0A%C3%B3%E3%80%82%0A%C5%8Du%E3%80%82%0A%C7%92u%E3%80%82%0A%C3%B2u%E3%80%82%0Ap%C4%81%E3%80%82%0Ap%C3%A1%E3%80%82%0Ap%C3%A0%E3%80%82%0Ap%C4%81i%E3%80%82%0Ap%C3%A1i%E3%80%82%0Ap%C7%8Ei%E3%80%82%0Ap%C3%A0i%E3%80%82%0Ap%C4%81n%E3%80%82%0Ap%C3%A1n%E3%80%82%0Ap%C7%8En%E3%80%82%0Ap%C3%A0n%E3%80%82%0Ap%C4%81ng%E3%80%82%0Ap%C3%A1ng%E3%80%82%0Ap%C7%8Eng%E3%80%82%0Ap%C3%A0ng%E3%80%82%0Ap%C4%81o%E3%80%82%0Ap%C3%A1o%E3%80%82%0Ap%C7%8Eo%E3%80%82%0Ap%C3%A0o%E3%80%82%0Ap%C4%93i%E3%80%82%0Ap%C3%A9i%E3%80%82%0Ap%C4%9Bi%E3%80%82%0A' \
- --compressed
-
- # tex 即是需要合成文本的URL编码

使用百度付费版 tts 时如下:
- # cuid 用户唯一标识,用来计算UV值。建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内。
- # token 开放平台获取到的开发者access_token(见上面的“鉴权认证机制”段落)。参见:https://cloud.baidu.com/doc/SPEECH/s/Pk38y8m7k
- # 其他参数说明请参见:https://cloud.baidu.com/doc/SPEECH/s/Qk38y8lrl
- # tex 即是需要合成拼音的URL编码
-
- curl "https://tsn.baidu.com/text2audio?lan=zh&vol=10&per=5003&cuid=$cuid&ctp=1&aue=3&tok=$token&tex=n%C3%BC%C3%A8%E3%80%82nu%C3%B3%E3%80%82nu%C3%B2%E3%80%82%E9%BB%81%E3%80%82%C5%8D%E3%80%82%C3%B3%E3%80%82%C5%8Du%E3%80%82%C7%92u%E3%80%82%C3%B2u%E3%80%82p%C4%81%E3%80%82p%C3%A1%E3%80%82p%C3%A0%E3%80%82p%C4%81i%E3%80%82p%C3%A1i%E3%80%82p%C7%8Ei%E3%80%82p%C3%A0i%E3%80%82p%C4%81n%E3%80%82p%C3%A1n%E3%80%82p%C7%8En%E3%80%82p%C3%A0n%E3%80%82p%C4%81ng%E3%80%82p%C3%A1ng%E3%80%82p%C7%8Eng%E3%80%82p%C3%A0ng%E3%80%82p%C4%81o%E3%80%82p%C3%A1o%E3%80%82p%C7%8Eo%E3%80%82p%C3%A0o%E3%80%82p%C4%93i%E3%80%82p%C3%A9i%E3%80%82p%C4%9Bi%E3%80%82%E3%80%82%0A" -o baidutts/mp3/25.mp3
将爬取的拼音拆分为长度小于150个字符,并将其转换成URL编码,我采用java程序开发,源码可参见BaiduTTS.java(百度网盘 请输入提取码) 。
将 BaiduTTS.jar 输出的 URL 编码集输出拷贝到 pinyin_url.txt 文件。用于做语音合成请求用。
语音合成请求采用的是shell脚本:
- index=0
- mkdir baidutts/mp3
- cat pinyin_url.txt | while read line
- do
- id=`printf "%02d" index`
- curl "https://tsn.baidu.com/text2audio?lan=zh&vol=10&per=5003&cuid=$cuid&ctp=1&aue=3&tok=$token&tex=$line" -o baidutts/mp3/$id.mp3
- let "index=index+1"
- done
注:本人使用的是付费版tts,每150个字符为一组进行识别,共花费了 ¥0.38 识别费用,生成 47 个语音文件。
- .
- ├── 00.mp3
- ├── 01.mp3
- ……
- ├── 45.mp3
- └── 46.mp3
4、使用 ffmpeg 将 mp3 转换成 wav。关于 ffmpeg 的安装与使用请参考《FFmpeg的安装与基础使用教程 - ZL Asica的博客》
- mkdir -p baidutts/wav
-
- cd baidutts/mp3
- for file in `ls *.mp3`
- do
- ffmpeg -i $file -f wav ../wav/${file%%.*}.wav
- done
- cd -
5、进行语音检测
使用 libfvad(百度网盘 请输入提取码)进行有效语音检测
下载、编译
- # 下载(可以直接使用百度云共享的zip包)
- git clone https://github.com/dpirch/libfvad.git
-
- # 编译
- cd libfvad
- # 创建编译目录
- mkdir build
- cd build
- cmake ..
- make
-
- # 将编译出来的 libfvad.a 拷入 libfvad/examples/ 目录下
- cp ./src/libfvad.a ../examples/
-
- # 进入 examples 目录
- cd ../examples
-
- # 编译 examples
- gcc -o fvadwav fvadwav.c -I../include -L. -lfvad -lsndfile

将编译生成的 examples/fvadwav
拷贝至 baidutts
目录下
使用 shell 命令进行 vad 检测
- cd baidutts
- mkdir -p dur
-
- # vad检测
- for ((i=0;$i<=46;i++))
- do
- id=`printf "%02d" $i`
- # -l 表示输出检测结果写入文件
- ./fvadwav -l dur/$id.txt wav/$id.wav;
- done
-
- # 查看检测出来的有效语音和无效语音片段数
- # grep "voice segments" | grep -v non
检测结果标签文件样式如下,1 代表“有效语音”,0 代表“无效语音”
- 0
- 0
- 0
- 1
- 1
- 1
- 1
- 0
- 0
6、爬取下来的拼音进行格式化,转换成 ascii 码拼音表示法。例:hāo
转换为 hao1
这个转换工具采用 java 语言编写,源码参见 RepleacePinyin.java
(百度网盘 请输入提取码)。
使用 shell 命令批转换原始拼音,shell URL编解码请参考shell 下 urlencode/urldecode 编码/解码的方法:
- index=0
- mkdir baidutts/subpinyin-format
- cat pinyin_url.txt | while read line
- do
- pinyinfile=`printf "subpinyin-format/%02d.txt" $index`
- printf $(echo -n "$line" | sed 's/\\/\\\\/g;s/\(%\)\([0-9a-fA-F][0-9a-fA-F]\)/\\x\2/g') > $pinyinfile;
- # 转换后的拼音文件为后缀 “-conv.txt” 的文件
- java -jar RepleacePinyin.jar $pinyinfile
- let "index=index+1"
- done
7、进行语音切割
确定wav语音数据的位置:以二进制方式查看 wav 文件。关于wav文件头定义说明参见《wav头文件详解》
- 00000000: 5249 4646 c690 0a00 5741 5645 666d 7420 RIFF....WAVEfmt
- 00000010: 1000 0000 0100 0100 803e 0000 007d 0000 .........>...}..
- 00000020: 0200 1000 4c49 5354 1a00 0000 494e 464f ....LIST....INFO
- 00000030: 4953 4654 0e00 0000 4c61 7666 3537 2e38 ISFT....Lavf57.8
- 00000040: 332e 3130 3000 6461 7461 8090 0a00 0000 3.100.data......
- 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
可以看出 0x0 ~ 0x4E 为wave文件头,即 78 个字节为wav文件的头。
wavcut 为使用c++开发的wav剪切工具,源码见wave-cut.cpp
(百度网盘 请输入提取码) 。编译命令:g++ -g -o wavcut wave-cut.cpp
,生成 wavcut
可执行程序。将可执行程序拷贝到 baidutts
目录下。
使用前步 vad 生成的 dur/*.txt 标签文件和wav语音文件切割成 pcm 片段
- cd baidutts
-
- for ((i=0;i<=46;i++))
- do
- id=`printf "%02d" $i`
- echo "./wavcut dur/$id.txt wav/$id.wav subpinyin-format/$id.txt-conv.txt"
- ./wavcut "dur/$id.txt" "wav/$id.wav" "subpinyin-format/$id.txt-conv.txt"
- done
生成的 pcm 语音片段文件位于 baidutts
目录下,使用 mv 命令进行整理
- cd baidutts
- mkdir pcm
- mv *.pcm pcm/
使用 ffmpeg 将 pcm 转换成 wav 文件,并打包
- cd baidutts
- mkdir secs-wave
-
- for file in `pcm/*.pcm`
- do
- name=${file##*/}
- ffmpeg -i $file -f wav secs-wave/${name%%.*}.wav
- done
-
- tar -czvf baidu-secs-wave.tar.gz secs-wave
8、将第7步生成的子片段 wav 文件集移入 ekho 的 ekho-data 目录下
- cd ekho/ekho-data
-
- # 将 baidu-secs-wave.tar.gz 拷贝到当前目录下,然后解压
- tar -xvf baidu-secs-wave.tar.gz
- # 创建软链接
- ln -s secs-wave pinyin
-
- # 拷贝生成 de5.wav
- cp pinyin/de1.wav pinyin/de5.wav -rf
9、删除 ekho-data 目录下的 pinyin.index、pinyin.voice文件,然后使用命令测试并初始化 ekho 组件。(可以参考:如何为Ekho添加新的声音)
- cd ekho/ekho-data
- rm -rf pinyin.*
-
- cd ..
- # 测试并初始化
- ./bin/ekho 0123456789 -vpinyin -o test.ogg -t ogg
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。