CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-simpleaudio

Simple, asynchronous audio playback for Python 3.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Simpleaudio

Simple, asynchronous audio playback for Python 3. Provides cross-platform, dependency-free audio playback capability for Python 3 on macOS, Windows, and Linux through a simple object-oriented API.

Package Information

  • Package Name: simpleaudio
  • Language: Python
  • Installation: pip install simpleaudio
  • Platforms: Linux (ALSA), macOS (CoreAudio), Windows (WinMM)

Core Imports

import simpleaudio as sa

For function checks and testing:

import simpleaudio.functionchecks as fc

Basic Usage

import simpleaudio as sa

# Load and play a wave file
wave_obj = sa.WaveObject.from_wave_file("path/to/file.wav")
play_obj = wave_obj.play()
play_obj.wait_done()  # Wait until playback finishes

# Play raw audio buffer
audio_data = b'\x00\x01' * 44100  # Sample audio data
play_obj = sa.play_buffer(audio_data, 2, 2, 44100)
play_obj.wait_done()

# Stop all audio playback
sa.stop_all()

Capabilities

Wave Object Creation and Playback

Load audio from files or create from raw data, then control playback.

class WaveObject:
    def __init__(self, audio_data, num_channels=2, bytes_per_sample=2, sample_rate=44100):
        """
        Create a WaveObject from raw audio data.
        
        Args:
            audio_data (bytes): Raw audio data buffer
            num_channels (int): Number of audio channels (1=mono, 2=stereo)
            bytes_per_sample (int): Bytes per audio sample (1, 2, 3, or 4)
            sample_rate (int): Sample rate in Hz (must be multiple of 11025)
        """
    
    def play(self):
        """
        Start playback of this wave object.
        
        Returns:
            PlayObject: Object for controlling this playback instance
        """
    
    @classmethod
    def from_wave_file(cls, wave_file):
        """
        Load a wave object from a WAV file.
        
        Args:
            wave_file (str): Path to WAV file
            
        Returns:
            WaveObject: New wave object loaded from file
        """
    
    @classmethod
    def from_wave_read(cls, wave_read):
        """
        Create a wave object from an open wave.Wave_read object.
        
        Args:
            wave_read: Open wave.Wave_read object from wave.open()
            
        Returns:
            WaveObject: New wave object from wave reader
        """
    
    def __str__(self):
        """
        String representation showing audio format details.
        
        Returns:
            str: Format description (channels, bit depth, sample rate)
        """

Playback Control

Control individual audio playback instances.

class PlayObject:
    def __init__(self, play_id):
        """
        Internal constructor for playback control object.
        
        Args:
            play_id (int): Internal ID for tracking this playback
        """
    
    def stop(self):
        """
        Stop this specific audio playback.
        """
    
    def wait_done(self):
        """
        Block until this audio playback completes.
        Polls playback status every 50ms.
        """
    
    def is_playing(self):
        """
        Check if this audio is currently playing.
        
        Returns:
            bool: True if still playing, False if stopped or finished
        """

Direct Buffer Playback

Play audio directly from raw buffer data without creating a WaveObject.

def play_buffer(audio_data, num_channels, bytes_per_sample, sample_rate):
    """
    Play audio from raw buffer data.
    
    Args:
        audio_data (bytes): Raw audio data buffer
        num_channels (int): Number of channels (1 or 2)
        bytes_per_sample (int): Bytes per sample (1, 2, 3, or 4)
        sample_rate (int): Sample rate in Hz (must be multiple of 11025)
        
    Returns:
        PlayObject: Object for controlling this playback
        
    Raises:
        ValueError: Invalid parameters (channels not 1-2, invalid bytes_per_sample, 
                   or sample_rate not multiple of 11025)
    """

Global Playback Control

Stop all audio playback at once.

def stop_all():
    """
    Stop all currently playing audio streams.
    """

Function Checks and Testing

Built-in audio functionality tests for verifying installation and hardware.

class FunctionCheckBase:
    @classmethod
    def run(cls, countdown=3):
        """
        Run this function check with optional countdown.
        
        Args:
            countdown (int): Seconds to wait before starting (default: 3)
        """

class LeftRightCheck(FunctionCheckBase):
    """Tests stereo playback by playing left channel then right channel."""

class OverlappingCheck(FunctionCheckBase):
    """Tests overlapping playback with three notes spaced half-second apart."""

class StopCheck(FunctionCheckBase):
    """Tests stopping individual playback streams."""

class StopAllCheck(FunctionCheckBase):
    """Tests stopping all playback streams at once."""

class IsPlayingCheck(FunctionCheckBase):
    """Tests the is_playing() method functionality."""

class WaitDoneCheck(FunctionCheckBase):
    """Tests the wait_done() method functionality."""

def run_all(countdown=0):
    """
    Run all function checks in sequence.
    
    Args:
        countdown (int): Seconds to wait before each check (default: 0)
    """

Usage Examples

Basic Wave File Playback

import simpleaudio as sa

# Load and play a wave file
wave_obj = sa.WaveObject.from_wave_file("audio.wav")
play_obj = wave_obj.play()

# Wait for playback to finish
play_obj.wait_done()

Overlapping Audio Streams

import simpleaudio as sa
from time import sleep

# Load multiple audio files
wave1 = sa.WaveObject.from_wave_file("note1.wav")
wave2 = sa.WaveObject.from_wave_file("note2.wav")
wave3 = sa.WaveObject.from_wave_file("note3.wav")

# Play them with overlapping timing
play1 = wave1.play()
sleep(0.5)
play2 = wave2.play()
sleep(0.5) 
play3 = wave3.play()

# Wait for all to finish
play1.wait_done()
play2.wait_done()
play3.wait_done()

Raw Buffer Playback

import simpleaudio as sa
import numpy as np

# Generate a sine wave
sample_rate = 44100
duration = 2.0
frequency = 440

t = np.linspace(0, duration, int(sample_rate * duration), False)
sine_wave = np.sin(2 * np.pi * frequency * t)

# Convert to 16-bit integers
audio_data = (sine_wave * 32767).astype(np.int16).tobytes()

# Play the generated audio
play_obj = sa.play_buffer(audio_data, 1, 2, sample_rate)
play_obj.wait_done()

Function Testing

import simpleaudio.functionchecks as fc

# Run a specific test
fc.LeftRightCheck.run()

# Run all tests
fc.run_all(countdown=3)

Error Handling

The package raises ValueError exceptions for invalid parameters:

  • Channels: Must be 1 (mono) or 2 (stereo)
  • Bytes per sample: Must be 1, 2, 3, or 4
  • Sample rate: Must be a multiple of 11025 Hz (e.g., 11025, 22050, 44100, 88200)
import simpleaudio as sa

try:
    # This will raise ValueError - invalid sample rate
    sa.play_buffer(b'\x00' * 1000, 2, 2, 44101)
except ValueError as e:
    print(f"Invalid parameters: {e}")

Platform-Specific Details

  • Linux: Uses ALSA (Advanced Linux Sound Architecture)
  • macOS: Uses CoreAudio framework with minimum macOS 10.6 support
  • Windows: Uses Windows Multimedia API (WinMM)

The package automatically detects the platform and uses the appropriate audio backend. No platform-specific code is required from the user.

docs

index.md

tile.json