Skip to content

AudioBuffer

The central data type. A 2D float32 numpy array with shape [channels, frames] plus metadata (sample_rate, channel_layout, label).

Usage examples

Construction

import numpy as np
from nanodsp.buffer import AudioBuffer

# From a numpy array
arr = np.zeros((2, 44100), dtype=np.float32)
buf = AudioBuffer(arr, sample_rate=44100)

# From file
buf = AudioBuffer.from_file("input.wav")

# Factory methods
buf = AudioBuffer.sine(440.0, channels=1, frames=44100, sample_rate=44100)
buf = AudioBuffer.noise(channels=2, frames=44100, seed=42)
buf = AudioBuffer.impulse(channels=1, frames=1024)
buf = AudioBuffer.zeros(channels=1, frames=4096, sample_rate=48000)
buf = AudioBuffer.ones(channels=2, frames=1024)

Inspecting properties

buf = AudioBuffer.sine(440.0, frames=48000, sample_rate=48000)

buf.channels      # 1
buf.frames        # 48000
buf.sample_rate   # 48000.0
buf.duration      # 1.0 (seconds)
buf.channel_layout  # 'mono'
buf.data.shape    # (1, 48000)

Channel operations

stereo = AudioBuffer.noise(channels=2, frames=44100)

# Downmix
mono = stereo.to_mono("mean")       # average channels
mono = stereo.to_mono("left")       # take left channel

# Upmix
stereo = mono.to_channels(2)        # duplicate mono to stereo

# Split into individual channels
left, right = stereo.split()

# Stack channels
merged = AudioBuffer.concat_channels(left, right)

Arithmetic

buf = AudioBuffer.sine(440.0, frames=4096)

quiet = buf * 0.5                    # scale amplitude
boosted = buf.gain_db(6.0)           # +6 dB
inverted = -buf                      # phase invert
mixed = buf_a + buf_b                # sum two buffers
diff = buf_a - buf_b                 # difference

Pipeline processing

from nanodsp.effects import filters, dynamics

result = (
    AudioBuffer.from_file("input.wav")
    .pipe(filters.highpass, cutoff_hz=80.0)
    .pipe(filters.lowpass, cutoff_hz=12000.0)
    .pipe(dynamics.compress, threshold=-18.0, ratio=4.0)
)
result.write("output.wav")

Slicing

buf = AudioBuffer.sine(440.0, frames=48000, sample_rate=48000)

# Time slice (view, no copy)
first_half = buf.slice(0, 24000)

# Channel indexing
ch0 = buf[0]              # 1D numpy array (channel 0)
samples = buf[0, 100:200] # numpy slice of channel 0, frames 100-199

API reference

AudioBuffer

AudioBuffer(
    data: ArrayLike | AudioBuffer,
    sample_rate: float = 48000.0,
    channel_layout: str | None = None,
    label: str | None = None,
)

A 2D [channels, frames] float32 audio buffer with metadata.

PARAMETER DESCRIPTION
data

Audio samples. 1D input is normalised to [1, N].

TYPE: array - like or AudioBuffer

sample_rate

Sample rate in Hz. Must be positive (> 0).

TYPE: float DEFAULT: 48000.0

channel_layout

E.g. 'mono', 'stereo'. Inferred from channel count when None.

TYPE: str or None DEFAULT: None

label

Free-form label carried as metadata.

TYPE: str or None DEFAULT: None

RAISES DESCRIPTION
ValueError

If data is not 1D or 2D, or if sample_rate is not positive.

data property

data: ndarray

Raw 2D [channels, frames] float32 array.

sample_rate property

sample_rate: float

channels property

channels: int

frames property

frames: int

duration property

duration: float

Duration in seconds.

channel_layout property

channel_layout: str | None

label property

label: str | None

dtype property

dtype: dtype

mono property

mono: ndarray

1D numpy view -- only valid when channels == 1.

channel

channel(i: int) -> np.ndarray

Return a 1D numpy view of channel i.

__getitem__

__getitem__(key: int) -> np.ndarray
__getitem__(key: slice) -> AudioBuffer
__getitem__(key: tuple[int, slice]) -> np.ndarray
__getitem__(
    key: int | slice | tuple[int, slice],
) -> np.ndarray | AudioBuffer

__len__

__len__() -> int

Number of frames (not channels).

zeros classmethod

zeros(
    channels: int,
    frames: int,
    sample_rate: float = 48000.0,
    **kw,
) -> AudioBuffer

ones classmethod

ones(
    channels: int,
    frames: int,
    sample_rate: float = 48000.0,
    **kw,
) -> AudioBuffer

impulse classmethod

impulse(
    channels: int = 1,
    frames: int = 1024,
    sample_rate: float = 48000.0,
    **kw,
) -> AudioBuffer

Unit impulse at frame 0 in every channel.

sine classmethod

sine(
    freq: float,
    channels: int = 1,
    frames: int = 4096,
    sample_rate: float = 48000.0,
    **kw,
) -> AudioBuffer

noise classmethod

noise(
    channels: int = 1,
    frames: int = 4096,
    sample_rate: float = 48000.0,
    seed: int | None = None,
    **kw,
) -> AudioBuffer

from_numpy classmethod

from_numpy(
    arr: ndarray, sample_rate: float = 48000.0, **kw
) -> AudioBuffer

Explicit alias for the constructor.

from_file classmethod

from_file(path: str) -> AudioBuffer

Read an audio file (WAV/FLAC, detected by extension).

write

write(path: str, bit_depth: int = 16) -> None

Write this buffer to an audio file (WAV/FLAC, detected by extension).

to_mono

to_mono(
    method: Literal[
        "mean", "left", "right", "sum"
    ] = "mean",
) -> AudioBuffer

Mix down to mono.

method: 'mean' (default), 'left', 'right', 'sum'.

to_channels

to_channels(n: int) -> AudioBuffer

Upmix mono to n channels by copying, or error if incompatible.

split

split() -> list[AudioBuffer]

Split into a list of mono AudioBuffers, one per channel.

concat_channels staticmethod

concat_channels(*buffers: AudioBuffer) -> AudioBuffer

Stack channels from multiple AudioBuffers.

slice

slice(start_frame: int, end_frame: int) -> AudioBuffer

Return a view (no copy) of frames [start_frame:end_frame].

gain_db

gain_db(db: float) -> AudioBuffer

Return a new buffer scaled by 10**(db/20).

pipe

pipe(
    fn: Callable[..., AudioBuffer],
    *args: Any,
    **kwargs: Any,
) -> AudioBuffer

Chain a DSP function: buf.pipe(dsp.lowpass, 5000).

Calls fn(self, *args, **kwargs) and validates the return type.

copy

copy() -> AudioBuffer

Deep copy with independent numpy storage.

ensure_1d

ensure_1d(channel: int = 0) -> np.ndarray

Return a contiguous 1D float32 view for 1D C++ bindings.

ensure_2d

ensure_2d() -> np.ndarray

Return the contiguous 2D float32 array for 2D C++ bindings.