import pyaudio
import wave
import time
from speechlib import *
1.导入库函数
2.定义数据流参数信息
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 5
nframes = int(RATE / CHUNK * RECORD_SECONDS)
WAVE_OUTPUT_FILENAME = "C2_1_y_1.wav"
CHUNK = 1024 #wav文件是由若干个CHUNK组成的,CHUNK我们就理解成数据包或者数据片段 FORMAT = pyaudio.paInt16 #pyaudio.paInt16表示我们使用量化位数 16位来进行录音 CHANNELS = 1 #电脑采集的频道为1 1是麦克风 #声道,这里使用的单声道 2双声道 RATE = 16000 #采样率 16k 每秒采样16000个点 RECORD_SECONDS = 5 #录制时间这里设定了5秒 nframes = int(RATE / CHUNK * RECORD_SECONDS) #计算出所需采集帧的数量 #采样率*秒数 -->总点数
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
3.# 实例化一个Pyaudio对象 p = pyaudio.PyAudio() # 使用该对象打开声卡,并用上述参数信息对数据流进行赋值 #使用pyaudio.PyAudio.open(),录制或播放音频 #stream 这块是个模型,套路
print("* recording")
frames = []
for i in range(0, nframes):#前期已定义采帧数量
#nframes = int(RATE / CHUNK * RECORD_SECONDS)
data = stream.read(CHUNK)
frames.append(data)
#利用循环不断把 数据加到frames 中
print("* done recording")
# 关闭数据流,声卡;终止Pyaudio
stream.stop_stream()
#使用pyaudio.Stream.stop_stream()暂停播放/录制
stream.close()
#pyaudio.Stream.close()终止流。
p.terminate()
#使用pyaudio.PyAudio.terminate()终止portaudio会话
# 设定存储录音的WAV文件的基本信息
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
WAVE_OUTPUT_FILENAME 在第二个代码块中提到的 保存音频的文件名
关于wave.open 函数
#wave.open(file, mode=None) #如果 file 是一个字符串,打开对应文件名的文件。 #mode 两种形式:'rb'只读模式。'wb'只写模式。注意不支持同时读写WAV文件。 #mode 设为 'rb' 时返回一个 Wave_read 对象,而 mode 设为 'wb' 时返回一个 Wave_write 对象。 #open返回一个的是一个Wave_read类的实例,通过调用它的方法读取WAV文件的格式和数据
# 实例化一个pyaudio对象
p = pyaudio.PyAudio()
# 定义回调函数
def callback(in_data, frame_count, time_info, status):
data = wf.readframes(frame_count)
return (data, pyaudio.paContinue)
# 以回调函数的形式打开声卡,创建数据流
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
stream_callback=callback)
# 打开数据流
stream.start_stream()
# 等待数据流停止
while stream.is_active():
time.sleep(0.1)
# 停止数据流,关闭声卡、音频文件;终止Pyaudio
stream.stop_stream()
stream.close()
wf.close()
p.terminate()
回调函数:在write之后stream就会阻塞,开始播放音频,如果这个音频文件有三分钟,那么程序就会停在write这三分钟,直到把整个音频播放完毕,再继续往下执行。 然而在很多应用中,我们需要的是实时问答,中途可以打断对话,也就是说不应该一次性把一整段话都write进来,应该分批写入。 pyaudio自然也考虑到了这个问题,它已经有了可用的解决方案——回调函数callback。 定义回调函数 固定格式 callback(in_data, # 如果input=True,in_data就是录制的数据,否则为None frame_count, # 帧的数量,表示本次回调要读取几帧的数据 time_info, # 一个包含时间信息的dict status_flags): # 状态标志位
(fs, sound) = wavfile.read(WAVE_OUTPUT_FILENAME)
t = np.array([i/fs for i in range(sound.size)])
plt.plot(t, sound)
plt.title('录制信号')
plt.xlabel('时间/s')
plt.ylabel('幅度')
plt.show()