4

I am using librosa library to do data analysis on an audio file in .wav format. But it seems librosa can only read or write audio file in form of an array apart from feature extraction. I would also like to play the audio file with my analysis code.

In Ipython notebook, I can use Ipython.display.audio to play audio directly in Ipython ntoebook, but when I convert code to .py, I doesn't work, so I need something that can be used for the same purpose.

Deep
  • 616
  • 1
  • 9
  • 17
  • Does this answer your question? [how to play wav file in python?](https://stackoverflow.com/questions/17657103/how-to-play-wav-file-in-python) – Xaser Apr 28 '20 at 07:51
  • It doesn't work for me, as I don't know chunk size for streaming, also I don't want to add any overhead like that. I would to see if there is any library already in place like Ipython.display.audio which can do same task with less overhead. – Deep Apr 28 '20 at 07:53
  • 1
    The answer presented by @Xaser has actually less "overhead" than the IPython solution. Also, `chunk_size` you define yourself, it's nothing you have to know in advance. It's just number of bytes that will be read in one go. If by "overhead" you mean "I don't want to type that much", consider e.g. https://pypi.org/project/playsound/ – Lukasz Tracewski Apr 28 '20 at 12:34

2 Answers2

2

You could use pydub to load the audio file (mp3, wav, ogg, raw) and simpleaudio for playback. Just do

sound = pydub.AudioSegment.from_wav('audiofile.wav')
playback = simpleaudio.play_buffer(
    sound.raw_data, 
    num_channels=sound.channels, 
    bytes_per_sample=sound.sample_width, 
    sample_rate=sound.frame_rate
    )

And voila! you finally got your beats going. To stop just call playback.stop()

droptop
  • 1,372
  • 13
  • 24
  • this works however its async meaning code to actually render the audio happens in a new thread (under the covers) and program execution continues along which is fine if above code is in a game or server however in a terminal program you will only hear a tiny pop of audio because the program may have finished before time needed to listen to the audio file ... wonder if it can be told to play sync ... elsewise it will work under this use case by putting a sleep step afterwards – Scott Stensland May 07 '20 at 09:04
0

If you want to use a blacking mode where the execution will wait until the streaming is finished you can use pyaudio blocking mode full documentation

example:

"""PyAudio Example: Play a wave file."""

import pyaudio
import wave
import sys

CHUNK = 1024

if len(sys.argv) < 2:
    print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
    sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')

# instantiate PyAudio (1)
p = pyaudio.PyAudio()

# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=wf.getframerate(),
                output=True)

# read data
data = wf.readframes(CHUNK)

# play stream (3)
while len(data) > 0:
    stream.write(data)
    data = wf.readframes(CHUNK)

# stop stream (4)
stream.stop_stream()
stream.close()

# close PyAudio (5)
p.terminate()
Ahmed
  • 11
  • 1