树莓派基于pyaudio实现录音功能

因为在做一个语音识别机器人,需要用到录音模块,本来想直接用arecord命令:

os.system('arecord -d 4 -r 16000 -c 1 -t wav -f S16_LE -D plughw:1,0 record.wav')

但每次运行结束后再次运行就会出现“arecord”资源被占用,输入ps -aux|grep python查看进程发现我的robot.py虽然已停止,但必须得kill -9 PID才能再次运行。这个问题至今还没找到答案,如果有知道的伙伴麻烦告知一声,感激不尽。

基于以上原因,我决定用pyaudio录音,参考了一些博主的代码进行加工。

环境:python2.7

需要导入的包: wave 和 pyaudio

pyaudio怎么安装请自行百度,直接上代码

#_*_ coding:UTF-8 _*_

import wave
from pyaudio import PyAudio,paInt16

# 设置采样参数
NUM_SAMPLES = 2000
TIME = 2
chunk = 1024

# 读wav文件
def read_wave_file(filename):	
    fp = wave.open(filename,'rb')
    nf = fp.getnframes()     #获取采样点数量
    f_len = nf*2
    audio_data = fp.readframes(nf)

# 保存wav音频文件 
def save_wave_file(filename,data):  
    wf = wave.open(filename,'wb')
    wf.setnchannels(1)  
    wf.setsampwidth(2)     
    wf.setframerate(16000) 
    wf.writeframes(b"".join(data))  
    wf.close()

# 录音
def record():
    pa = PyAudio()   
    # 打开输入流并设置音频采样参数 1 channel 16K framerate 
    stream = pa.open(format = paInt16,
                     channels=1,
                     rate=16000,
                     input=True,
                     frames_per_buffer=NUM_SAMPLES)	
    audioBuffer = []   # 录音缓存数组
    count = 0	
    # 录制40s语音
    while count<TIME*20:
        string_audio_data = stream.read(NUM_SAMPLES) #一次性录音采样字节的大小
        audioBuffer.append(string_audio_data)
        count +=1
        print('.'),  #加逗号不换行输出	
    # 保存录制的语音文件到record_voice.wav中并关闭流
    save_wave_file('record_voice.wav',audioBuffer)
    pathname='record_voice.wav'
    stream.close()
    return pathname

# 播放后缀为wav的音频文件
def play(pathname):
    wf = wave.open(pathname,'rb') 
    p = PyAudio()               	
    # 打开流
    stream = p.open( format=p.get_format_from_width(wf.getsampwidth()),
                     channels=wf.getnchannels(),
                     rate=wf.getframerate(),
                     output=True)
    # 播放音频
    while True:
        data = wf.readframes(chunk)
        if data == "":break
        stream.write(data)	
    # 释放IO
    stream.stop_stream()
    stream.close()
    p.terminate()


 if __name__ == '__main__': 
    print('record ready...')
    pathname=record()
    print('record over!') 
    play(pathname)

你可能感兴趣的:(树莓派,语音识别,python)