Python中函数和线程的时间戳执行

时间:2016-03-29 02:09:00

标签: python multithreading time timestamp subprocess

我目前正在实现一种使用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

1 个答案:

答案 0 :(得分:1)

你可以找到关于时间戳执行的太多争论。 我可以很快分享我的2美分:

  • time() - 最好在linux / unix上使用
  • clock() - 最好在Windows上使用
  • process_time() - 仅计算系统和用户CPU时间,但不包括任何休眠时间
  • 如果您需要跨平台解决方案,则需要使用“timeit”模块。除了直接从代码中调用它之外,您还可以从命令行调用它,这是一个很大的好处。

如果您想要对您的代码进行分析,您可以使用cProfile,它还可以让您选择使用的时钟,挂钟时间或处理时间