实现功能
系统可分为两部分:
- 发送端实现读取excel中的内容,合成连续语音;
- 接收端读取该音频,识别后重新生成excel文件;
发送端
- 从定好格式的excel文件中读取需要的信息;
- 根据第1步得到的数据,生成语音;
- play the radio or not。
百度语音合成
- 语音合成部分用到了百度AIP,该功能需要连网。
一个教程 - 进入’百度AI’主页
- 在右上角的“控制台”上,点击“语音技术”按钮,打开控制台的登录界面。这里需要你登录自己的百度账号,且需要实名。
- 点击页面的“创建应用”按钮。选择需要调用的借口(也就是AI程序),其中语音识别和语音合成是必选的;语音包名不需要(我们要用python调用,所以不需要)。
- 保存之后,就进入应用管理,查看自己的应用的APPID、APPKEY,还有SECRET KEY。
from pydub import AudioSegment
from pydub.playback import play
from aip import AipSpeech
#安装库的时候搜索:baidu-aip
def voice_gen_online(text):
APP_ID = 'xx'
API_KEY ='xx'
SECRET_KEY = 'xx'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
# 语音合成
result = client.synthesis(text, 'zh', 1, {
'vol': 5, 'spd': 1, 'pit': 5, 'per': 1
})
if not isinstance(result, dict):
filename = 'test'
with open(filename + '.mp3', 'wb') as f:
f.write(result)
sound = AudioSegment.from_mp3(filename + '.mp3')
# 播放
# play(sound)
# covert to *.wav
sound.export('online_' + filename + '.wav', format="wav")
- 因为我们只针对10个数字,数据量不算大。所以,我们首先在联网时,依次产生10个数字的独立音频,建立自己的语音元素库。独立音频根据需要拼接起来就是连续的音频。这样可以实现离线生成连续语音。
本地语音合成
#自己做了个词典
dict = {'0': '0.wav',
...
'i': 'i.wav'}
def voice_gen(string:data, filename):
sounds = []
for s in data:
a = dict[s]
filepath = './dict/' + dict[s]
sounds.append(AudioSegment.from_wav(filepath))
playlist = AudioSegment.empty()
for sound in sounds:
playlist += sound
playlist.export(filename + '.wav', format="wav")
接收端
- 监听麦克风,有音频输入就录下来;
- 对得到的录音进行识别;
- 识别结果填表。
一些注意事项:
- 对每个音频,识别一次就够了。不要一直陷在循环里;
- 有时候会录到一些杂七杂八的音频,比如说提示音之类的。不需要强行填表;
- th是麦克风输入信号的判定阈值,超过th,认为是信号。我用的是2k;
- 循环的次数:5 & 30要根据采样频率做些调整;
- filename用当前时间组合的,为了避免重复(查看之前博文)。
监听麦克风并录音
连续语音分割
我用的google出的webrtcvad里面的方法。
孤立词语音识别
我用的是HMM-GMM的模型进行识别。
识别出的存成一个list:‘results’,用逗号分割。
results = [‘1’, ‘7’, ‘3’, ‘5’, ‘7’, ‘2’, … , ‘9’]
写入到Excel文件*.xlsx
- 输入是一个list,包含:一些乱码 + 起始标识符 ‘s’ + 表头 + 数据 + 结束标识符’t’ + 一些乱码。其中header长度固定,data长度不定,但最长为100*4(4个数字一组填到一个cell里);
- 首先将乱码去除,只截取入list中‘s’和‘t’之间的部分;
- 然后将表头’header’和数据’data’分别截取出来;
- 生成的excel有固定的格式,其中data部分最长为100。不足100的部分在excel中由‘0000’补足;
import openpyxl
def write_excel_xlsx(path, sheet_name, value):
#输入数据很长,但我设置了flag,认为有用的只有‘s’和‘t’之间的部分
start_index = 0
end_index = 0
for i in range(len(value)):
cur = value[i]
if(cur is 's'):
start_index = i + 1
if(cur is 't'):
end_index = i
value = value[start_index: end_index]
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = sheet_name
#写入固有值,和value无关的,类目名称之类的
content = ['1xx','2xx', ...]
for i in range(10):
sheet.cell(1, i + 1, content[i])
#先把data不足400的部分补0
#L是输入的真实数据长度
data = ['0'] * 400
data[0: L] = data_0
#再把长为400的data分为100组
group_data = []
index = 0
group = ''
a = len(data)
for i in range(401):
#这个写的奇奇怪怪,凑合用,有空再改改b
if (index is 4):
group_data.append(group)
group = ''
index = 0
if(i < 400):
cur = data[i]
group = group + cur
index = index + 1
index= 0
#最后把分好组的data填入excel
for i in range(10):
for j in range(0, 10):
sheet.cell(row=i+6, column=j+1, value=str(group_data[index]))
index = index + 1
workbook.save(path)
print("create a *.xlsx file")