我目前正在实现一种使用python同步回放和记录功能的算法。该算法将用于测量麦克风和扬声器之间的时滞或延迟,因此在内部延迟和软件执行时间方面,时序必须非常准确。 我能够使用线程模块在python中实现这些函数的同步。但是,我不确定这是否是最好的选择,因为其他模块如多线程就在那里。由于我缺乏python中多线程(异步/同步)模块的专业知识和经验,我只实现了线程模块的基础知识,如下面的脚本所示。另外,我知道它有锁定功能,但这对我的应用程序有用吗?
正如我之前提到的,准确的时间对我的应用至关重要。我试图对执行记录和回放功能的实例进行时间标记,到目前为止,我只是在将数据/样本输入每个缓冲区之前调用time.time()。但我发现time.clock()和time.process_time()可能会给我一个更准确的时间戳。但我很确定可能会有更好的解决方案。
#!/usr/bin/env python3
import pyaudio
import numpy as np
import time
import glob
import wave
import threading
rec_start=0.0
play_start=0.0
rec_signal = np.array([],dtype=np.float64)
def record():
RATE = 16000
DURATION = 0.5
CHUNKSIZE_REC = 2**12
global rec_signal
global rec_start
#initialize portaudio
p_rec = pyaudio.PyAudio()
stream = p_rec.open(format=pyaudio.paInt16,
channels=1,rate=RATE,
input=True,frames_per_buffer=CHUNKSIZE_REC)
frames = []
rec_start = time.time()
for _ in range(0,int(RATE/CHUNKSIZE_REC*DURATION)):
data = stream.read(CHUNKSIZE_REC)
frames.append(np.fromstring(data,dtype=np.int16))
#convert the list of numpy-arrays into a 1D array (column-wise)
numpydata = np.hstack(frames)
#close stream
stream.stop_stream()
stream.close()
p_rec.terminate()
rec_signal = numpydata
#end def
#-----------------------------------------------------------------------------
def playback():
CHUNKSIZE_PLAY = 2**12
global play_start
wf =wave.open('AC_PRN_Signal.wav','rb')
p_play = pyaudio.PyAudio()
stream = p_play.open(format=p_play.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
playData = wf.readframes(CHUNKSIZE_PLAY)
time.sleep(0.005)
play_start =time.time()
while playData !='':
stream.write(playData)
playData = wf.readframes(CHUNKSIZE_PLAY)
stream.stop_stream()
stream.close()
p_play.terminate()
#end def
#-----------------------------------------------------------------------
def play_while_recording():
rec_thread = threading.Thread(target=record)
play_thread = threading.Thread(target=playback)
'''start recording while playing back signal'''
rec_thread.start()
play_thread.start()
'''stop both threads before exiting func.'''
play_thread.join()
rec_thread.join()
#end def
#---------------------------------------------------------------------
if __name__ == "__main__":
play_while_recording()
global rec_signal
global rec_start
global play_start
print("rec start @ "+str(rec_start))
print("play start @ "+str(play_start))
print("time_delta: "+str((play_start-rec_start)*1000.0)+"ms")
要添加,我还在python中使用subproces模块实现并测试了调用linux alsa aplay和arecord,如下所示,然后使用scipy.io.wavefile读取这些wave文件并执行后期处理。但是我发现很难获得执行的时间实例或者甚至是时间标记它。
def playback():
global play_start
time.sleep(0.005)
play_start =time.time()
subprocess.Popen(["/usr/bin/aplay","test_audio.wav"])
#end def
答案 0 :(得分:1)
你可以找到关于时间戳执行的太多争论。 我可以很快分享我的2美分:
如果您想要对您的代码进行分析,您可以使用cProfile,它还可以让您选择使用的时钟,挂钟时间或处理时间