我试图在Python中同时运行两个方法。其中一个播放声音,另一个录制它。这两种方法都运行良好但我无法弄清楚如何在尝试多处理和线程的同时启动它们。虽然我现在几乎可以肯定它无法用线程解决。
def listen_to_audio()
def play_audio()
有什么想法吗? (他们不必同时完成,但他们都应该在一秒钟内完成。)
这是代码,抱歉不在开头发布:
import pyaudio
import wave
import sys
import time
from math import *
from getopt import *
import threading
def make_sin(f0=1000.,ampl=30000,rate=22050,length=5.):
a = 2. * pi * f0/rate
n = int(rate * length)
wav=''
for i in range(0, n):
f = int(ampl*sin(a*i))
wav += chr(f & 0xFF) + chr((f & 0xFF00) >> 8)
return wav
def play_audio(forHowLong):
data = make_sin(f0=1000.,ampl=30000,rate=22050,length=5.)
p = pyaudio.PyAudio() #sets up portaudio system
stream = p.open(format=p.get_format_from_width(2),
channels=1,
rate=22050,
output=True)
start = time.time()
while time.time() < start + forHowLong*0.5:
stream.write(data)
stream.stop_stream()
stream.close()
p.terminate()
def listen_to_audio(forHowLong):
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = forHowLong
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 = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
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()
def main():
#start play_audio and record_audio here at the same time
if __name__ == "__main__":
main()
答案 0 :(得分:5)
import threading,time
def play1():
while time.time() <= start_time:
pass
threading.Thread(target=listen_to_audio).start()
def play2():
while time.time() <= start_time:
pass
threading.Thread(target=play_audio).start()
start_time=time.time()+20
threading.Thread(target=play1).start()
threading.Thread(target=play2).start()
这应该适合你,它启动每个函数,并在每个函数中等待,直到它是正确的时间:))
答案 1 :(得分:2)
我会使用线程:
import threading
threads = []
threads.append(threading.Thread(target=listen_to_audio))
threads.append(threading.Thread(target=play_audio))
map(lambda x: x.start(), threads)
编辑:不确定地图是否会同时启动绝对主题,但它应该非常接近
答案 2 :(得分:2)
你可以从:
开始import threading
threading.Thread(target=listen_to_audio).start()
threading.Thread(target=play_audio).start()
答案 3 :(得分:1)
谢谢IT忍者,
你的代码完成了这项工作,但我不得不将其改为:
def main():
start_time=time.time()+1
def play1():
while time.time() < start_time:
pass
threading.Thread(target=listen_to_audio(5)).start()
def play2():
while time.time() < start_time:
pass
threading.Thread(target=play_audio(5)).start()
threading.Thread(target=play1).start()
threading.Thread(target=play2).start()
现在它有效:) 谢谢大家!!
答案 4 :(得分:0)
为什么要使用线程启动这两个函数?你可以简单地调用第一个函数,并在第一个函数中使用线程启动第二个函数。
import threading
def play_audio():
threading.Thread(target=listen_to_audio).start()
#rest of code for play_audio
我认为这里的延迟会非常少。
答案 5 :(得分:0)
线程可能同时启动,但由于Windows的限制,播放/录制不会同时开始。在场景后面实际上有一个缓冲区导致(未知或可控制的)延迟。
执行此操作的最佳方法是创建异步读/写流(一个同时执行读写操作的流)。也就是说,使用回调函数创建一个流并定义input = True和output = True(我在这里假设是pyaudio)。
我不确定pyaudio如何在幕后实现线程,特别是如果它阻止音频,但另一个问题是GIL(全局解释器锁)。我没有充分研究当前的状态以及在不同的python实现下的行为,但是IIRC只有一个线程可以在给定的时间运行python代码,所以python在很大程度上不是非常多线程友好的时刻AFAIK
答案 6 :(得分:-1)
我创建一个def startBoth()
来包装这两个函数,根据需要导入listen_to_audio和play_audio。启动startBoth()
后,它会调用这两个函数。