私は現在、Pythonを使って再生と記録の機能を同期させるアルゴリズムを実装しています。このアルゴリズムは、マイクロホンとスピーカーの間のタイムラグや遅延を測定するために使用されるため、内部レイテンシとソフトウェア実行時間の観点から、タイミングは非常に正確でなければなりません。 私は、スレッド化モジュールを使って、これらの関数を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")
、私はまた、以下に示すように、LinuxのALSAのはaplayとarecordを呼び出し、その後、scipy.io.wavefileを使用して、それらの波ファイルを読み込み、ポストを実行するためにpythonでsubprocesモジュールに実装され、テストされています処理。しかし、私はそれが実際に実行の時間インスタンスを取得するか、またはタイムスタンプを取得することは本当に難しいと思っています。
def playback():
global play_start
time.sleep(0.005)
play_start =time.time()
subprocess.Popen(["/usr/bin/aplay","test_audio.wav"])
#end def