Play, Record, Process live audio with Numpy

PyGame, PyAudio and PySoundDevice are three of the best currently maintained packages for playing audio from Python, including from Numpy arrays or streaming sources. For these examples, we will use this common sinewave-generating code in a Numpy array.

import numpy as np
fs = 8000 # Hz
T = 1. # second, arbitrary length of tone

# 1 kHz sine wave, 1 second long, sampled at 8 kHz
t = np.arange(0, T, 1/fs)
x = 0.5 * np.sin(2*np.pi*1000*t)   # 0.5 is arbitrary to avoid clipping sound card DAC
x  = (x*32768).astype(np.int16)  # scale to int16 for sound card

PySoundDevice has the simplest syntax for Python audio play/record packages.

import sounddevice
import time

sounddevice.play(x, fs)  # releases GIL
time.sleep(1)  # NOTE: Since sound playback is async, allow sound playback to finish before Python exits

PyGame is for building games and does much more than audio. I find PyGame to be very robust across a wide variety of systems (including embedded systems) to play audio from Python.

pip install pygame

uses pre-compiled .whl binary wheel.

import pygame
from time import sleep

pygame.mixer.pre_init(fs, size=-16, channels=1)
pygame.mixer.init()
sound = pygame.sndarray.make_sound(x)

sound.play()

sleep(0.01) # NOTE: Since sound playback is async, allow sound playback to start before Python exits

The PyAudio and PySoundDevice packages are PortAudio based.

PyAudio uses PortAudio to allow easy playback of Numpy arrays. If you find that you’re not able to install PortAudio, consider using PyGame instead of PyAudio.

import pyaudio

# PyAudio doesn't seem to have context manager
P = pyaudio.PyAudio()

stream = P.open(rate=fs, format=pyaudio.paInt16, channels=1, output=True)
stream.write(x.tobytes())

stream.close() # this blocks until sound finishes playing

P.terminate()

Oct2Py doesn’t work as temporary files are needed. Example PyGame program: audio_pygame.py. Advanced PyGame setup.