想训练一套自己的语音识别系统(命令词识别系统),首先得准备一套自己的语料库,发动身边的帅哥美女们帮忙进行录音。Python无所不能,很多工具包能给让我们的工作变的简单、优雅。
今天就给大家分享一下基于PyAudio的录音工具,可以方便的利用我们的笔记本电脑进行录音。首先需要准备好环境,安装PyAudio:pip install pyaudio(pyhook不再累述),创建Python文件record.py:
#-*- coding:utf-8 -*-
#-*- author yangdengqiang -*-
import os
import sys
import threading
from time import ctime,sleep
import pyHook
import pythoncom
from pyaudio import PyAudio, paInt16
import numpy as np
from datetime import datetime
import wave
flag = False
NUM_SAMPLES = 1024*4 #pyaudio内置缓冲大小
SAMPLING_RATE = 16000 #取样频率,kaldi识别仅支持16KHz,16-bit位深
LEVEL = 500 #声音保存的阈值
COUNT_NUM = 20 #NUM_SAMPLES个取样之内出现COUNT_NUM个大于LEVEL的取样则记录声音
SAVE_LENGTH = 8 #声音记录的最小长度:SAVE_LENGTH * NUM_SAMPLES 个取样
TIME_COUNT = 20 #录音时间,单位s
Voice_String = []
SPEAKER_NO = '001' #录音者id,1,2,...,10
WAV_ID = 0 #录音文件ID
CONTENT = [] #录音内容list
SPEAKER_NAME = 'default'
def speech_recogniton(func):
for i in range(2):
print ("I was at the %s! %s" %(func,ctime()))
sleep(5)
def startHookManager():
# 创建一个:钩子“管理对象
hm = pyHook.HookManager()
# 监听所有的键盘事件
hm.KeyDown = onKeyboardEvent
#设置键盘”钩子“
hm.HookKeyboard()
# 进入循环侦听,需要手动进行关闭,否则程序将一直处于监听的状态。可以直接设置而空而使用默认值
pythoncom.PumpMessages()
def savewav(filename):
wf = wave.open(filename, 'wb')
wf.setnchannels(1)
wf.setsampwidth(2)#2
wf.setframerate(SAMPLING_RATE)
wf.writeframes(np.array(Voice_String).tostring())
# wf.writeframes(self.Voice_String.decode())
wf.close()
def recoder():
global flag, Voice_String;
pa = PyAudio()
stream = pa.open(format=paInt16, channels=1, rate=SAMPLING_RATE, input=True,
frames_per_buffer=NUM_SAMPLES)
save_count = 0
save_buffer = []
time_count = TIME_COUNT
while flag:
print('...')
time_count -= 1
# print time_count
# 读入NUM_SAMPLES个取样
string_audio_data = stream.read(NUM_SAMPLES)
# 将读入的数据转换为数组
audio_data = np.fromstring(string_audio_data, dtype=np.short)
# 计算大于LEVEL的取样的个数
large_sample_count = np.sum( audio_data > LEVEL )
# print(np.max(audio_data))
# 如果个数大于COUNT_NUM,则至少保存SAVE_LENGTH个块
if large_sample_count > COUNT_NUM:
save_count = SAVE_LENGTH
else:
save_count -= 1
if save_count < 0:
save_count = 0
Voice_String = save_buffer
if save_count > 0 :
# 将要保存的数据存放到save_buffer中
#print save_count > 0 and time_count >0
save_buffer.append( string_audio_data )
Voice_String = save_buffer
else:
#print save_buffer
# 将save_buffer中的数据写入WAV文件,WAV文件的文件名是保存的时刻
#print "debug"
if len(save_buffer) > 0 :
Voice_String = save_buffer
save_buffer = []
print("Recode a piece of voice successfully!")
return True
if time_count==0:
if len(save_buffer)>0:
Voice_String = save_buffer
save_buffer = []
print("Recode a piece of voice successfully!")
return True
else:
return False
stream.stop_stream()
stream.close()
pa.terminate()
def onKeyboardEvent(event):
global flag, WAV_ID, CONTENT, SPEAKER_NO
if event.Key == "Space": # 点击空格
if flag == False:
print("=======开始录音=======");
threading.Thread(target=recoder).start();
flag = True;
else:
WAV_ID = WAV_ID + 1
curSeq = '00' + str(WAV_ID)
wavename = str(SPEAKER_NO) + '_' + curSeq[-3:] + '.wav'
savewav(wavename);
print("========结束录音======");
print(wavename + '保存成功')
print("======================")
flag = False
if WAV_ID > len(CONTENT)-1:
print("录音完毕,程序将退出!")
exit()
print("下一条:" + CONTENT[WAV_ID])
return True
else:
if event.Key == "Q":
print("退出录音")
exit();
else:
return True
def printOneLine():
global CONTENT
fh = open("xiaozhi2.txt", "r", encoding="utf-8")
CONTENT = fh.readlines()
print("命令总长度为:%s"%len(CONTENT))
print("第%s条:%s"%(WAV_ID,CONTENT[WAV_ID]))
os.chdir(SPEAKER_NAME)
if __name__ == "__main__":
if len(sys.argv) != 3:
print("usage: python record.py username startIndex....")
exit()
SPEAKER_NAME = sys.argv[1] #用户名,用于保存目录
WAV_ID = int(sys.argv[2])#开始录音index
if os.path.exists(SPEAKER_NAME):
print("your dir is already exists...")
else:
try:
os.mkdir(SPEAKER_NAME)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise
print("it will started from: %s"%WAV_ID)
printOneLine() #读取录音内容
startHookManager(); #开始录音
保存文件,直接执行python record.py即可进行录音操作,按一次空格键录一条语音,可以方便快速的完成实验所需的语料库录音工作。
欢迎语音识别爱好者一起学习交流。