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