Richard
Richard

Reputation: 61479

Read and play audio in Python3

I have some audio files on my computer. I want to do some analysis on them in Python3, part of which will include playing snippets of the audio files back.

I'm interested in AMR files. An example file is here, but any file will do.

Here's my workflow so far:

#!/usr/bin/env python3
import audioread
import numpy as np
fin = audioread.audio_open('test.amr') 
dat  = [x for x in fin]          #Generate list of bytestrings
dat  = b''.join(dat)             #Join bytestrings into a single urbytestring
ndat = np.fromstring(dat, '<i2') #Convert from audioread format to numbers

#Generate a wave file in memory
import scipy.io.wavfile
import io
memory_file = io.BytesIO() #Buffer to write to
scipy.io.wavfile.write(memory_file, fin.samplerate, ndat) 

#Play the wave file
import simpleaudio
wave_obj = simpleaudio.WaveObject(memory_file.getvalue())
play_obj = wave_obj.play()
play_obj.wait_done()

Problem is, when I go for the playback, I some very high-pitched, fast-sounding noise. I suspect a conversion's gone wrong somewhere, but am not sure where.

Trying to use wave produces similar results:

#Generate a wave file in memory using wave
import wave
import io
memory_file = io.BytesIO() #Buffer to write to
wave_file = wave.open(memory_file, 'w')
wave_file.setparams((fin.channels, 2, fin.samplerate, 0, 'NONE', 'not compressed'))
wave_file.writeframes(ndat.astype('<i2').tostring())
wave_file.close()

Both with and without the astype.

I suspected perhaps the audio backend used by audioread wasn't working, so I converted from AMR to WAV and then read in the file. That didn't fix things.

Writing the wave file to disk and playing with with a standard audio player did resolve things, so the problem seems to be simpleaudio.

Upvotes: 1

Views: 1969

Answers (1)

Richard
Richard

Reputation: 61479

It turned out I was using simpleaudio incorrectly. The following works:

#!/usr/bin/env python3
import audioread
import numpy as np
fin  = audioread.audio_open('test_justin.amr') 
dat  = [x for x in fin]          #Generate list of bytestrings
dat  = b''.join(dat)             #Join bytestrings into a single urbytestring
ndat = np.fromstring(dat, '<i2') #Convert from audioread format to numbers

#Generate a wave file in memory
import scipy.io.wavfile
import io
memory_file = io.BytesIO() #Buffer to write to
scipy.io.wavfile.write(memory_file, fin.samplerate, ndat) 

#Play the wave file
import simpleaudio
wave_obj = simpleaudio.WaveObject.from_wave_file(memory_file)
play_obj = wave_obj.play()
play_obj.wait_done()

Upvotes: 2

Related Questions