2016-03-29 6 views
0

Ich implementiere derzeit einen Algorithmus, der eine Wiedergabe-und Record-Funktionalität mit Python synchronisiert. Dieser Algorithmus wird verwendet, um die Zeitverzögerung oder Verzögerungen zwischen einem Mikrofon und einem Lautsprecher zu messen, daher muss das Timing in Bezug auf interne Latenz und Softwareausführungszeit sehr genau sein. Ich konnte die Synchronisation dieser Funktionen in Python mit dem Threading-Modul erreichen. Aber ich bin mir nicht sicher, ob dies die besten Optionen sind und andere Module wie Multithreading verfügbar machen. Aufgrund meiner mangelnden Expertise und Erfahrung mit Multi-Threading-Modulen (async/sync) in Python habe ich nur die Grundlagen des Threading-Moduls implementiert, wie unten in meinem Skript gezeigt. Ich weiß auch, dass es eine Sperrfunktion gibt, aber wäre das nützlich für meine Anwendung?Zeitstempel Ausführung einer Funktion und Threading in Python

Wie ich bereits erwähnt habe, ist das genaue Timing für meine Anwendung entscheidend. Ich versuche die Instanz mit Zeitstempel zu versehen, dass sowohl die Aufnahme- als auch die Wiedergabe-Funktion ausgeführt wird. Bisher habe ich einfach time.time() aufgerufen, bevor Daten/Samples in jeden Puffer eingegeben werden. Aber ich bin gekommen, um zu finden, dass time.clock() und time.process_time() mir einen genaueren Zeitstempel geben können. Aber ich bin mir ziemlich sicher, dass es vielleicht noch bessere Lösungen gibt. auch umgesetzt und mit subproces Modul in Python getestet auf Linux ALSA aplay und arecord zu nennen

#!/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") 

hinzuzufügen, habe ich, wie unten dargestellt, und dann diese Wellen Dateien mit scipy.io.wavefile lesen und die Post durchführen wird bearbeitet. Aber ich habe es sehr schwer gefunden, die Zeit Instanz der Ausführung oder gerade Zeitstempel zu erhalten.

def playback(): 
    global play_start 
    time.sleep(0.005) 
    play_start =time.time() 
    subprocess.Popen(["/usr/bin/aplay","test_audio.wav"]) 
#end def 

Antwort

1

Sie können viel zu viele Debatten über die Ausführung von Zeitmarken finden. besser verwenden, um auf Linux/Unix

  • clock() - - besser nutzen unter Windows
  • process_time() -

    • time() berechnet nur System- und Benutzer: Ich kann meine 2 Cent kurz teilen CPU-Zeit, aber keine Schlafzeit ausgeschlossen
    • Wenn Sie eine plattformübergreifende Lösung wünschen, ist das Modul "timeit" das, das Sie verwenden müssen. Sie können es nicht nur direkt aus dem Code aufrufen, sondern auch über die Befehlszeile aufrufen. Das ist ein großer Vorteil.

    Wenn Sie möchten, um Ihren Code-Profil können Sie cProfile verwenden, mit denen Sie auch die Uhr wählen, zu verwenden, Wanduhr Zeit oder Prozesszeit