I am using sd.playrec() to determine transfer functions. So I want to play a file with my setup and record the output.
import sounddevice as sd
from scipy import signal
from scipy.io import wavfile
import numpy as np
def record_audio(st_data, output_filename):
sample_rate = 44100
channels = 1
audio_data = sd.playrec(st_data,sample_rate, channels,dtype='float32',blocking=True) # range of wav-file is ± 1.0 here, float32
wavfile.write(output_filename, sample_rate, audio_data) # Save the recording as a WAV file
print("File saved: " + output_filename)
return [st_data,audio_data]
timeVecSweep = np.arange(0, 10, 1/44100)
sw = signal.chirp(timeVecSweep, # t[]
20, #freq_start
10, #t_end
20000, #freq_end
'logarithmic',
phi=-90)
input,output = record_audio(sw,'test.wav')
The stimulus is a sine sweep from 20 to 20k Hz with fs=44.1 kHz.
I expected this function to be in sync, but: playback starts late and stops to early, so the last around 0.2s of the playback file are not played and get cut off. So the high frequencies are not getting recorded, which is not good.
Is this a bug or wanted? This behaviour is really unexpected for me.
Is there any flag or kwarg I can use to avoid this behaviour?
I know that I could just use files with added silence at the end as a workaround, but I want to avoid to recreate them all and wonder if this module could be 'fixed'.
When I record the same file manually Expected Sweep Spectrum Actual Result
I also tried using sd.rec() and sd.play() seperately with different configs for blocking or with added delays like time.sleep() but this didn't work at all.
Related Question: Slight delay in beginning of recording, and end gets cut off with low level streams in python-sounddevice
EDIT: It gets better with kwarg latency = 'low'
. But a few crackles appear sometimes.
I would wish for a flag to extend the recording duration for a little bit.
This could also account for latency issues related to BT-devices.
I am using macOS Ventura Version 13.4.1 (c) (22F770820d) on MacBookAir M1.