实现功能

系统可分为两部分:

  1. 发送端实现读取excel中的内容,合成连续语音;
  2. 接收端读取该音频,识别后重新生成excel文件;
    结构图。SPK和MIC用音频线连接

发送端

  1. 从定好格式的excel文件中读取需要的信息;
  2. 根据第1步得到的数据,生成语音;
  3. play the radio or not。
百度语音合成
  1. 语音合成部分用到了百度AIP,该功能需要连网。
    一个教程
  2. 进入’百度AI’主页
  3. 在右上角的“控制台”上,点击“语音技术”按钮,打开控制台的登录界面。这里需要你登录自己的百度账号,且需要实名。
  4. 点击页面的“创建应用”按钮。选择需要调用的借口(也就是AI程序),其中语音识别和语音合成是必选的;语音包名不需要(我们要用python调用,所以不需要)。
  5. 保存之后,就进入应用管理,查看自己的应用的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")

接收端

  1. 监听麦克风,有音频输入就录下来;
  2. 对得到的录音进行识别;
  3. 识别结果填表。

一些注意事项:

  • 对每个音频,识别一次就够了。不要一直陷在循环里;
  • 有时候会录到一些杂七杂八的音频,比如说提示音之类的。不需要强行填表;
  • 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")
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐