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.
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.
- 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
# Coming soon
pip install labsoundpyimportlabsoundasls# 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)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.
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()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)For more detailed documentation, see the API Reference and Examples.
There are two ways to build LabSoundPy from source:
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 --inplaceIf 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 --inplaceNote: This approach requires that you have LabSound installed and findable by CMake.
pytestLabSoundPy is licensed under the same license as LabSound. See the LICENSE file for details.
LabSoundPy is built on top of LabSound, a C++ audio engine.