我在PyAudio网站上看到了有关录制固定长度录音的教程,但我想知道如何使用非固定录音实现相同的操作?基本上,我想创建按钮来启动和结束录音,但我没有找到任何相关信息。 有什么想法吗?我不想使用其他库。
我在PyAudio网站上看到了有关录制固定长度录音的教程,但我想知道如何使用非固定录音实现相同的操作?基本上,我想创建按钮来启动和结束录音,但我没有找到任何相关信息。 有什么想法吗?我不想使用其他库。
stream_callback=my_callback
如果my_callback是一个常规函数,声明为
def my_callback(in_data, frame_count, time_info, status)
in_data
包含您想要记录的输入。在这个例子中,in_data
只是与pyaudio.paContinue
一起以元组的形式返回。这意味着从输入设备传入的缓冲区被放置/复制回发送到输出设备的输出缓冲区(它们是同一设备,因此实际上是将输入路由到输出,也就是线)。有关更多解释,请参见API文档:http://people.csail.mit.edu/hubert/pyaudio/docs/#pyaudio.PyAudio.open
所以在这个函数中,您可以做类似于以下代码的事情(这是我编写的一些代码的摘录,不完整:我使用了一些未显示的函数。另外,我在一个通道上播放正弦波,在另一个通道上播放噪声,以24位格式进行)。
record_on = False
playback_on = False
recorded_frames = queue.Queue()
def callback_play_sine(in_data, frame_count, time_info, status):
if record_on:
global recorded_frames
recorded_frames.put(in_data)
if playback_on:
left_channel_data = mysine.next_block(frame_count) * MAX_INT24 * gain
right_channel_data = ((np.random.rand(frame_count) * 2) - 1) * MAX_INT24 * gain
data = interleave_channels(max_nr_of_channels, (left_output_channel, left_channel_data), (right_output_channel, right_channel_data))
data = convert_int32_to_24bit_bytestream(data)
else:
data = np.zeros(frame_count*max_nr_of_channels).tostring()
if stop_callback:
callback_flag = pyaudio.paComplete
else:
callback_flag = pyaudio.paContinue
return data, callback_flag
record_on
和playback_on
设置为True
或False
,从而独立启动或停止录制和播放,而不会中断流。我将in_data
复制到一个(线程安全的)队列
中,另一个线程用它来写入磁盘,否则队列会在一段时间后变得很大。import pyaudio
import wave
import pygame, sys
from pygame.locals import *
pygame.init()
scr = pygame.display.set_mode((640, 480))
recording = True
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
while True:
if recording:
data = stream.read(CHUNK)
frames.append(data)
for event in pygame.event.get():
if event.type == KEYDOWN and recording:
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
recording = False
if event.type == QUIT:
pygame.quit(); sys.exit()
当我将其编译为exe时,这就是我想到的。将参数传递给
exeparser = argparse.ArgumentParser()
parser.add_argument('-t', dest='time', action='store')
args = parser.parse_args()
time = int(args.time)