Using IPython.display.audio to play audio in jupyter notebook not working when used inside a function
Asked Answered
S

4

14

When using the code below the sound plays:

import IPython.display as ipd
import numpy

sr = 22050 # sample rate
T = 0.5    # seconds
t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array

But when I use it inside a function it stops working:

import IPython.display as ipd
import numpy

def SoundNotification():
    sr = 22050 # sample rate
    T = 0.5    # seconds
    t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
    x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
    ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array

SoundNotification()

I've tried to assign the audio to a variable and return it which works:

import IPython.display as ipd
import numpy

def SoundNotification():
    sr = 22050 # sample rate
    T = 0.5    # seconds
    t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
    x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
    sound = ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array
    return sound
sound = SoundNotification()
sound

But I want to use the sound in a different function:

import IPython.display as ipd
import numpy

def SoundNotification():
    sr = 22050 # sample rate
    T = 0.5    # seconds
    t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
    x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
    sound = ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array
    return sound

def WhereIWantToUseTheSound():    
    sound = SoundNotification()
    sound

WhereIWantToUseTheSound()

How do I make this work and what causes this behavior? The kernel for the notebook is Python 3.

Edit: I want to play the sound in a scheduled event:

import IPython.display as ipd
import numpy
import sched, time

sound = []
def SoundNotification():
    sr = 22050 # sample rate
    T = 0.5    # seconds
    t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
    x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
    sound = ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array
    return sound


def do_something(sc): 
    print("Doing stuff...")
    # do your stuff
    sound_ = SoundNotification()
    s.enter(interval, 1, do_something, (sc,))
    return sound_


s = sched.scheduler(time.time, time.sleep)
interval = int(input("Interval between captures in seconds: "))
s.enter(0, 1, do_something, (s,))
s.run()

I don't know how to return the sound and schedule the next event within the same function.

Sakmar answered 3/5, 2020 at 11:48 Comment(0)
A
33

I was having this same problem, the sound was played when I called:

from IPython.display import Audio 
Audio('/path/beep.mp3', autoplay=True)

But it didn't work when it was inside a function. The problem is that the function call doesn't really play the sound, it's actually played by the resulting HTML that is returned to Jupyter output.

So to overcome this, you can force the function to render the HTML using display( ) function from IPython. This will work:

from IPython.display import Audio 
from IPython.core.display import display
def beep():
    display(Audio('/path/beep.mp3', autoplay=True))
beep();
Apparent answered 30/9, 2020 at 14:1 Comment(2)
Brilliant! This solves it cleanly.During
Hi, I am wondering how to save fileLeatrice
G
4

2 Things:

  1. You've to make your audio object (sound) global because you are returning values in that object and it's not accessible from outside of function
  2. In WhereIWantToUseTheSound() you are not returning anything

Code:

import IPython.display as ipd
import numpy
sound = []
def SoundNotification():
    global sound
    sr = 22050 # sample rate
    T = 0.5    # seconds
    t = numpy.linspace(0, T, int(T*sr), endpoint=False) # time variable
    x = 0.5*numpy.sin(2*numpy.pi*440*t)              # pure sine wave at 440 Hz
    sound = ipd.Audio(x, rate=sr, autoplay=True) # load a NumPy array

    return sound

def WhereIWantToUseTheSound():    
    sound = SoundNotification()
    return sound


WhereIWantToUseTheSound()

I would suggest to use another object/var(sound) name in WhereIWantToUseTheSound()

Grassgreen answered 4/5, 2020 at 7:45 Comment(1)
This works but I don't think I can return a variable in my implementation, I've edited my original question to show where I want to use the codeSakmar
B
1

You can also implement the Ipython.display.display() in a loop like this:

    import IPython.display as ipd
    import time
    wavs = ['1.wav', '2.wav']
    for wav in wavs:
        ipd.display(ipd.Audio(wav, autoplay=True))
        time.sleep(5) # next autoplay starts in 5s

It works on Jupyter Notebook. I also tested it on VS Code. The player widget appeared and the audio could be played manually. But the autoplay functionality is not working for now. I expect it will be fixed soon.

Bismuthous answered 5/1, 2023 at 15:42 Comment(0)
J
0

What worked for me:

%matplotlib inline

Forcing the inline plotting with the %matplotlib magic function at the top of the notebook helped me to render the plots even if show() function of plot object or the display() function for Audio is not called.

It should be noted that this problem does not appear on other jupyter installations

Jule answered 10/3, 2022 at 14:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.