【问题标题】:Time-stamp execution of a function and threading in PythonPython中函数和线程的时间戳执行
【发布时间】:2016-03-29 02:08:59
【问题描述】:

我目前正在实施一种算法,该算法使用 python 同步播放和记录功能。该算法将用于测量麦克风和扬声器之间的时间滞后或延迟,因此就内部延迟和软件执行时间而言,计时必须非常准确。 我能够使用 threading 模块在 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

【问题讨论】:

    标签: python multithreading time timestamp subprocess


    【解决方案1】:

    您会发现太多关于时间戳执行的争论。 我可以很快分享我的 2 美分:

    • time() - 更适合在 linux/unix 上使用
    • clock() - 更适合在 Windows 上使用
    • process_time() - 仅计算系统和用户 CPU 时间,但不包括任何睡眠时间
    • 如果您想要一个跨平台的解决方案,“timeit”模块就是您需要使用的模块。除了直接在代码中调用,还可以在命令行中调用,非常有好处。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多