I have two pieces of audio: (1) 15 heartbeat clips and (2) 15 frequency noises. The frequency noises are only 1 second and shorter in duration than the heartbeat clips (generated on-the-fly, variable length).
I'm able to successfully play both pieces through different speakers but only in series (one at a time), not in parallel (together). I'm doing this through sounddevice
as follows:
import sounddevice as sd
import sound file as sf
for i, clip in enumerate(user_heartbeats):
clip.export("temp.wav", format="wav")
audio_data, sample_rate = sf.read("temp.wav", dtype='float32')
sd.play(audio_data, sample_rate, device=heartbeat_speaker_id)
sd.wait()
t = np.linspace(0.0, freq_duration_sec, int(freq_duration_sec * sampling_freq), endpoint=False)
waveform = (volume) * np.sin(2.0 * np.pi * frequencies_to_play[i] * t)
sd.play(waveform, sampling_freq, device=frequency_speaker_id)
sd.wait()
I looked into the threading
library to play both simultaneously but I'm not able to get the intended result:
def play_audio_pairing(audio, delay, device):
# load heartbeat sound
audio_data, sample_rate = sf.read(audio, dtype='float32')
if delay > 0:
padding = np.zeros((int(delay * sample_rate), audio_data.shape[1]))
audio_data = np.concatenate((padding, audio_data), axis=0)
# Play audio file on the specified sound device
sd.play(audio_data, sample_rate, device=device)
sd.wait()
max_audio_duration = max([sf.info(file).duration for file in heartbeat_sounds + frequencies_to_play])
threads = []
for i in range(len(heartbeat_sounds)):
heartbeat_sound = heartbeat_sounds[i]
frequency_noise = frequencies_to_play[i % len(frequencies_to_play)]
heartbeat_delay = max_audio_duration - sf.info(heartbeat_sound).duration
frequency_delay = max_audio_duration - sf.info(frequency_noise).duration
thread = threading.Thread(target=play_audio_pairing, args=(heartbeat_sound, heartbeat_delay - frequency_delay, heartbeat_speaker_id))
threads.append(thread)
thread.start()
thread = threading.Thread(target=play_audio_pairing, args=(frequency_noise, 0, frequency_speaker_id))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
Any help on how to merge these so that each frequency noise starts and plays with its corresponding heartbeat sound, in different speakers, would be really helpful.