Skip to main content

audiolab

PyPI Tests License

audiolab is a compact Python toolkit for loading, transforming, streaming, inspecting, and saving audio. It accepts local files, URLs, encoded bytes, and file-like objects, and returns NumPy arrays with a consistent channels-first layout.

Common operations such as resampling, mono conversion, dtype conversion, speed changes, and pitch shifts use optimized processing paths automatically. You describe the result you want; audiolab chooses the implementation.

Highlights

  • Decode WAV, FLAC, MP3, AAC, M4A, WebM, and other formats supported by the installed audio libraries.
  • Read from paths, URLs, bytes, and binary file-like objects.
  • Resample, convert to mono, change dtype, alter speed, and shift pitch through one high-level API.
  • Process complete files, decoded PCM chunks, or incoming encoded byte streams.
  • Apply advanced audio filters when the high-level transforms are not enough.
  • Write NumPy audio to files and file-like objects.
  • Inspect audio metadata from Python or the audi command.

Installation

pip install audiolab

Python 3.10 or newer is required.

Quick start

Load and transform audio

import numpy as np

from audiolab import load_audio

audio, sample_rate = load_audio(
    "speech.mp3",
    offset=7.0,
    duration=23.0,
    sample_rate=16_000,
    to_mono=True,
    dtype=np.float32,
)

print(audio.shape)  # (channels, samples); here channels == 1
print(sample_rate)  # 16000

By default, decoded arrays are two-dimensional and channels-first: (channels, samples). Set always_2d=False if you want mono audio returned as a one-dimensional array.

Change speed and pitch

from audiolab import load_audio

# 25% faster, with the original pitch preserved.
faster, sample_rate = load_audio("speech.wav", speed=1.25)

# Two semitones higher, with approximately the original duration preserved.
higher, sample_rate = load_audio("speech.wav", pitch_shift=2)

# Both operations can be combined.
transformed, sample_rate = load_audio("speech.wav", speed=0.9, pitch_shift=-3)

speed must be positive. Values above 1 shorten the audio; values below 1 lengthen it. pitch_shift is measured in semitones and does not change the reported sample rate.

Save audio

import numpy as np

from audiolab import save_audio

sample_rate = 44_100
time = np.arange(sample_rate * 5) / sample_rate
tone = np.sin(2 * np.pi * 440 * time).astype(np.float32)

save_audio("tone.wav", tone, sample_rate)

Choose the right interface

Input and goal Use Result
Decode a complete source into memory load_audio One NumPy array and its sample rate
Iterate through a file or URL as decoded chunks Reader An iterator of (audio, sample_rate)
Decode encoded bytes as they arrive StreamReader Pulled decoded chunks
Transform NumPy PCM chunks AudioPipe Pulled transformed chunks
Save one complete NumPy array save_audio An audio file or file-like object
Write NumPy PCM chunks incrementally Writer A streamed audio output
Inspect metadata info or audi Codec, duration, rate, channels, and more
flowchart LR
    A[Complete file, URL, or bytes] --> B{Need the whole signal?}
    B -->|Yes| C[load_audio]
    B -->|No| D[Reader]
    E[Incoming encoded bytes] --> F[StreamReader]
    G[NumPy PCM chunks] --> H[AudioPipe]
    C --> I[NumPy audio]
    D --> I
    F --> I
    H --> I
    I --> J{Write output?}
    J -->|Complete array| K[save_audio]
    J -->|Chunk by chunk| L[Writer]

Processing model

The same high-level transform arguments work with load_audio, Reader, StreamReader, and AudioPipe:

Argument Meaning
sample_rate / output_sample_rate Target sample rate in Hz
to_mono Mix all input channels into one channel
dtype Target NumPy dtype, such as np.float32 or np.int16
speed Playback-speed multiplier while preserving pitch
pitch_shift Pitch change in semitones while preserving duration

The public API does not require selecting a resampler or processing engine:

flowchart LR
    A[Decoded audio] --> B{Requested operations}
    B -->|Rate, channels, dtype, speed, pitch| C[Optimized built-in processing]
    B -->|Custom filters| D[Advanced filter processing]
    C --> E[Framing and buffering]
    D --> E
    E --> F[NumPy output]

For advanced effects, pass an ordered filters list. Common transforms should stay in the high-level arguments so they can use the optimized path.

from audiolab import load_audio
from audiolab.av.filter import highpass

audio, sample_rate = load_audio(
    "speech.wav",
    filters=[highpass(f=200)],
    sample_rate=16_000,
    to_mono=True,
)

See Audio processing and filters for transform semantics, filter composition, and performance guidance.

Streaming

Use Reader when the source is already available but the decoded signal should not be held entirely in memory:

from audiolab import Reader, Writer

with Reader("input.flac", sample_rate=16_000, to_mono=True, frame_size=4096) as reader:
    with Writer("output.wav", reader.output_sample_rate) as writer:
        for audio, _ in reader:
            writer.write(audio)

Use AudioPipe when you already have NumPy chunks:

from audiolab import AudioPipe

pipe = AudioPipe(input_sample_rate=48_000, output_sample_rate=16_000, to_mono=True)

for input_chunk in pcm_chunks:
    pipe.push(input_chunk)
    for output_chunk, output_rate in pipe.pull():
        consume(output_chunk, output_rate)

# Flush delayed samples and finalize the pipe exactly once.
for output_chunk, output_rate in pipe.pull(partial=True):
    consume(output_chunk, output_rate)

See the streaming guide for Reader, StreamReader, AudioPipe, finalization, buffering, and incremental writing.

Inspect audio

From Python:

from audiolab import info

metadata = info("audio.m4a")
print(metadata.sample_rate, metadata.num_channels, metadata.duration)
print(metadata)
metadata.close()

From the command line:

audi audio.m4a            # Show all available metadata
audi -r -c audio.wav      # Show sample rate and channel count
audi -d audio.wav         # Show human-readable duration
audi -D audio.wav         # Show duration in seconds
audi --help               # Show every option

API at a glance

API Purpose
load_audio(source, **options) Eagerly decode and transform a complete source
Reader(source, **options) Incrementally decode and transform an available source
StreamReader(**options) Incrementally decode pushed encoded bytes
AudioPipe(input_sample_rate, **options) Transform pushed NumPy PCM chunks
save_audio(destination, audio, sample_rate, ...) Save a complete NumPy array
Writer(destination, sample_rate, ...) Write NumPy chunks incrementally
info(source, ...) Read source metadata
encode(audio, ...) Encode audio as a base64 data string or raw PCM base64

Low-level frame, format, and advanced filter helpers remain available under audiolab.av for specialized integrations; ordinary applications should prefer the high-level interfaces above.

Breaking changes and upgrade examples are tracked in the changelog and migration guide.

Development

python -m pip install -e ".[dev]"
python -m pytest -q --cov=audiolab --cov-fail-under=85
ruff check .
ruff format --check .
python benchmarks/processing.py

License

Apache License 2.0

Metadata

Release files for audiolab 0.5.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for audiolab 0.5.2
File Size Uploaded
audiolab-0.5.2.tar.gz 46.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for audiolab 0.5.2
File Interpreter ABI Platform
audiolab-0.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 108.6 kB

Release files / audiolab-0.5.2.tar.gz

Download URL audiolab-0.5.2.tar.gz
Size 46.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f9e8da42784dfd40595bd4fbda24ad96a7e07d261cf4caac74d15bb161293ba6
BLAKE2b-256 checksum
How to use checksums
35e4465891822307e4ab4a7665fab9c3b5059ecc3d8e39f033b6d05392400bdb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / audiolab-0.5.2-py3-none-any.whl

Download URL audiolab-0.5.2-py3-none-any.whl
Size 61.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
657cbabc358d6ff04b69f13d52ffa53288acf4cbcbc792c1cc8b112b670749da
BLAKE2b-256 checksum
How to use checksums
94815bff5f43003dc2b72497c85c391cb87e1a9ff0b55c359bdf774fe8779c36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

1 release file

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

0.0.9

1 release file

0.0.8

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page