Skip to content

Repository files navigation

LabSoundPy

Python bindings for the LabSound audio engine.

This project is very much work in progress and does not yet compile. It's published in case anyone wants to pitch in to help write it.

Overview

LabSoundPy provides a Pythonic interface to LabSound's audio processing capabilities, making it as simple and intuitive to use as JavaScript-based Web Audio API while leveraging Python's strengths and ecosystem.

Features

  • Pythonic Interface: A wrapper that feels natural to Python developers
  • Graph-Based Audio Processing: Node-based programming model for audio processing
  • NumPy Integration: Seamless integration with NumPy for audio data manipulation
  • Comprehensive Node Types: Support for all standard Web Audio API node types
  • Custom Processing: Create custom audio processing with Python functions
  • Context Management: Use Python's context managers for resource handling

Installation

# Coming soon
pip install labsoundpy

Quick Start

importlabsoundasls# Create an audio context with context managerwithls.AudioContext() asctx:
# Create nodesosc=ctx.create_oscillator()
gain=ctx.create_gain()
# Set parametersosc.frequency.value=440# A4 notegain.gain.value=0.5# Half volume# Connect nodesctx.connect(osc, gain)
ctx.connect(gain, ctx.destination)
# Start and stop the oscillatorosc.start(0)
osc.stop(2)
# Wait for completionctx.wait(2.5)

Node Types

LabSoundPy supports the following node types:

  • AnalyzerNode: For real-time frequency and time-domain analysis
  • AudioBufferSourceNode: For playing back pre-recorded audio
  • BiquadFilterNode: For filtering audio with various filter types
  • ChannelMergerNode: For combining multiple audio channels
  • ChannelSplitterNode: For splitting audio into multiple channels
  • ConstantSourceNode: For generating a constant value
  • ConvolverNode: For applying convolution effects (e.g., reverb)
  • DelayNode: For delaying audio
  • DynamicsCompressorNode: For dynamic range compression
  • FunctionNode: For custom audio processing with Python functions
  • GainNode: For controlling audio volume
  • OscillatorNode: For generating audio tones
  • PannerNode: For 3D audio positioning
  • StereoPannerNode: For simple stereo panning
  • WaveShaperNode: For non-linear distortion effects

It's intended that all LabSound nodes will be wrapped. Please see STATUS.md for details.

Examples

Spatial Audio

importtimeimportmathfromlabsoundimportAudioContext# Create an audio contextwithAudioContext() ascontext:
# Create an oscillator as our sound sourceoscillator=context.create_oscillator()
oscillator.frequency.value=440# A4 note# Create a panner node for 3D positioningpanner=context.create_panner()
panner.panning_model="HRTF"# Head-related transfer function# Connect the oscillator to the panner, and the panner to the destinationcontext.connect(oscillator, panner)
context.connect(panner, context.destination)
# Start the oscillatoroscillator.start()
# Move the sound source in a circle around the listenerradius=5# 5 units away from the listenerforiinrange(100):
angle= (i*0.1) % (2*math.pi)
x=radius*math.sin(angle)
z=radius*math.cos(angle)
# Update the panner positionpanner.set_position(x, 0, z)
# Wait a bit before the next updatetime.sleep(0.1)
# Stop the oscillatoroscillator.stop()

Custom Processing with NumPy

importnumpyasnpfromlabsoundimportAudioContext# Create an audio contextwithAudioContext() ascontext:
# Create an oscillator as our sound sourceoscillator=context.create_oscillator()
oscillator.frequency.value=220# A3 note# Create a function node for custom processingfunction_node=context.create_function(channels=1)
# Define a custom processing functiondefbit_crusher(channel, buffer):
# Apply a bit crusher effect (reduces bit depth)bits=4# Reduced bit depthstep=2.0** (bits-1)
foriinrange(len(buffer)):
# Quantize the sample to the reduced bit depthbuffer[i] =np.floor(buffer[i] *step) /step# Set the processing functionfunction_node.set_process_function(bit_crusher)
# Connect the nodescontext.connect(oscillator, function_node)
context.connect(function_node, context.destination)
# Start the oscillatoroscillator.start()
# Let it play for 3 secondscontext.wait(3)

Documentation

For more detailed documentation, see the API Reference and Examples.

Development

Building from Source

There are two ways to build LabSoundPy from source:

Option 1: Using Git Submodules (Recommended)

This approach automatically fetches and builds the required dependencies (nanobind and LabSound) as git submodules.

# Clone the repository with submodules
git clone --recursive https://github.com/yourusername/labsoundpy.git
cd labsoundpy
# Or if you've already cloned without --recursive
git submodule update --init --recursive
# Install development dependencies
pip install -e ".[dev]"# Build the extension (this will use submodules by default)
python setup.py build_ext --inplace

Option 2: Using Installed Dependencies

If you prefer to use system-installed versions of the dependencies:

# Clone the repository
git clone https://github.com/yourusername/labsoundpy.git
cd labsoundpy
# Install development dependencies
pip install -e ".[dev]"# Build using installed dependencies
USE_SUBMODULES=0 python setup.py build_ext --inplace

Note: This approach requires that you have LabSound installed and findable by CMake.

Running Tests

pytest

License

LabSoundPy is licensed under the same license as LabSound. See the LICENSE file for details.

Acknowledgements

LabSoundPy is built on top of LabSound, a C++ audio engine.

About

Python bindings for LabSound

Resources

Contributing

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages