10

I'm currently experimenting with generating sounds in Python, and I'm curious how I can take a n array representing a waveform (with a sample rate of 44100 hz), and play it. I'm looking for pure Python here, rather than relying on a library that supports more than just .wav format.

Jordan Scales
  • 2,687
  • 4
  • 28
  • 37

5 Answers5

10

or use the sounddevice module. Install using pip install sounddevice, but you need this first: sudo apt-get install libportaudio2

absolute basic:

import numpy as np
import sounddevice as sd

sd.play(myarray) 
#may need to be normalised like in below example
#myarray must be a numpy array. If not, convert with np.array(myarray)

A few more options:

import numpy as np
import sounddevice as sd

#variables
samplfreq = 100   #the sampling frequency of your data (mine=100Hz, yours=44100)
factor = 10       #incr./decr frequency (speed up / slow down by a factor) (normal speed = 1)

#data
print('..interpolating data')
arr = myarray

#normalise the data to between -1 and 1. If your data wasn't/isn't normalised it will be very noisy when played here
sd.play( arr / np.max(np.abs(arr)), samplfreq*factor)
mjp
  • 1,618
  • 2
  • 22
  • 37
6

You should use a library. Writing it all in pure python could be many thousands of lines of code, to interface with the audio hardware!

With a library, e.g. audiere, it will be as simple as this:

import audiere
ds = audiere.open_device()
os = ds.open_array(input_array, 44100)
os.play()

There's also pyglet, pygame, and many others..


Edit: audiere module mentioned above appears no longer maintained, but my advice to rely on a library stays the same. Take your pick of a current project here:

https://wiki.python.org/moin/Audio/

https://pythonbasics.org/python-play-sound/

The reason there's not many high-level stdlib "batteries included" here is because interactions with the audio hardware can be very platform-dependent.

wim
  • 338,267
  • 99
  • 616
  • 750
  • `audiere` appears to be a very old project... last released in 2006, and the readme for the Python binding is dated 2002 and references Python 2.2... – Karl Knechtel Jan 03 '12 at 05:00
  • I have used it myself on python 2.7 and it was still working fine. The audiere module is from http://pyaudiere.org/ , possibly you were looking at http://audiere.sourceforge.net/ . pyaudiere uses the Audiere API – wim Jan 03 '12 at 05:17
  • 1
    The pyaudiere website no longer exists, and audiere still hasn't been updated since 2006. This is no longer a good answer. – John Lyon Apr 05 '12 at 00:24
4

To play sound given array input_array of 16 bit samples. This is modified example from pyadio documentation page

import pyaudio

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

# open stream (2), 2 is size in bytes of int16
stream = p.open(format=p.get_format_from_width(2),
                channels=1,
                rate=44100,
                output=True)

# play stream (3), blocking call
stream.write(input_array)

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

# close PyAudio (5)
p.terminate()
ivan_onys
  • 2,282
  • 17
  • 21
4

I think you may look this list http://wiki.python.org/moin/PythonInMusic It list many useful tools for working with sound.

Valentin Briukhanov
  • 1,263
  • 9
  • 13
0

Here's a snippet of code taken from this stackoverflow answer, with an added example to play a numpy array (scipy loaded sound file):

from wave import open as waveOpen
from ossaudiodev import open as ossOpen
from ossaudiodev import AFMT_S16_NE
import numpy as np
from scipy.io import wavfile

# from https://stackoverflow.com/questions/307305/play-a-sound-with-python/311634#311634
# run this: sudo modprobe snd-pcm-oss
s = waveOpen('example.wav','rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')

print(nc,sw,fr,nf,comptype, compname)

_, snp = wavfile.read('example.wav')
print(snp)

dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()

dsp.write(snp.tobytes())
dsp.write(data)
dsp.close()

Basically you can just call the tobytes() method; the returned bytearray then can be played.

P.S. this method is supa fast

Viktor Tóth
  • 423
  • 6
  • 12