I would like to play a sound in a jupyter notebook each time a specific condition is met. After browsing through similar questions on stackoverflow, I managed to almost achieve this, especially thanks to this thread: Playing audio in jupyter, in a for loop. The notebook would look something like this:
import IPython.display as ipd
import ipywidgets as widgets
import numpy as np
output = widgets.Output()
display(output)
# Define sinewave to produce sound
sr = 44100
T = 2 # seconds
t = np.linspace(0, T, int(T*sr), endpoint=False) # sample sine wave
freqs = [329.63,440.0,466.16,554.37,587.33]
for i in range(0,len(freqs)):
if (i<2):
x = 0.5*np.sin(2*np.pi*freqs[i]*t)
with output:
ipd.display(ipd.Audio(x, rate=sr,autoplay=True))
However a major problem remains: each time the condition is met, a new widget appears in the cell where the output is displayed; Given that a sound could potentially be played hundreds of times, this leads to a massive slowdown after some time. In addition, I don't need any widget to be displayed at all in the first place, since I simply want the sound to be played automatically. I have tried using "output.clear_output()", but doing so too early will interrupt any sound currently playing, and anyway I guess it takes ressources to clear and reload widgets constantly, so it's not a solution if used that way. Is there a way to just update the widget so that only one is displayed? Is it possible to make this work without widgets?
P.S: in the end I'd like to provide an online version of the notebook through MyBinder, so it should work there as well.
Edit: the use of "clear_output(wait=True)" after displaying the display kind of works for short sounds. Still, this is not optimal, and more importantly does not work if I want several sounds to be played simultaneously.