Skip to main content

High-performance Python DSP toolkit built on C++ libraries via nanobind

Project description

nanodsp

High-performance Python DSP toolkit built on C++ libraries via nanobind. All processing uses float32 in a planar [channels, frames] layout with block-based APIs that accept and return AudioBuffer objects.

Backends

Library License What it provides
signalsmith-dsp MIT Filters, FFT, delay, envelopes, spectral processing, rates, mix
DaisySP MIT Oscillators, effects, dynamics, drums, physical modeling, noise
STK MIT Physical modeling instruments, generators, filters, delays, effects
madronalib MIT FDN reverbs, resampling, generators, projections, windows
HISSTools Library BSD-3 Convolution, spectral processing, statistical analysis, windows
CHOC ISC FLAC codec (read/write)
GrainflowLib MIT Granular synthesis (grain collections, panning, recording, phasor)

Requirements

  • Python >= 3.10
  • numpy
  • C++17 compiler
  • CMake >= 3.15

Install

pip install nanodsp

Or if you prefer to build from source (requires uv and cmake):

git clone https://github.com/shakfu/nanodsp.git
cd nanodsp
uv sync            # install dependencies + build extension
uv run pytest      # run tests
uv build           # build wheel

Use make help for additional targets (build, test, lint, format, typecheck, qa, coverage, etc.).

CLI

nanodsp ships with a command-line interface accessible via nanodsp or python -m nanodsp.

# File info
nanodsp info drums.wav
nanodsp info drums.wav --json

# Process with effect chain (single file)
nanodsp process input.wav -o output.wav \
  -f highpass:cutoff_hz=80 \
  -f compress:ratio=4,threshold=-18 \
  -f normalize_peak:target_db=-1

# Apply a preset
nanodsp process vocals.wav -o out.wav -p vocal_chain
nanodsp process input.wav -o out.wav -f lowpass:cutoff_hz=12000 -p master

# Batch mode -- process multiple files to a directory
nanodsp process *.wav -O out/ -f lowpass:cutoff_hz=2000

# Dry run -- show chain without reading/writing files
nanodsp process input.wav -n -f highpass:cutoff_hz=80 -f compress:ratio=4

# Verbose / quiet
nanodsp -v process input.wav -o out.wav -f lowpass:cutoff_hz=1000
nanodsp -q process input.wav -o out.wav -p master

# Analyze
nanodsp analyze input.wav loudness
nanodsp analyze input.wav pitch --fmin=80 --fmax=800
nanodsp analyze input.wav onsets --json
nanodsp analyze input.wav info

# Synthesize
nanodsp synth tone.wav sine --freq=440 --duration=2.0
nanodsp synth kick.wav drum --type=analog_bass_drum --freq=60
nanodsp synth melody.wav note --instrument=clarinet --freq=440 --duration=1.0
nanodsp synth seq.wav sequence --instrument=flute \
  --notes='[{"freq":440,"start":0,"dur":0.5},{"freq":554,"start":0.5,"dur":0.5}]'

# Convert
nanodsp convert input.wav output.flac
nanodsp convert input.wav output.wav --sample-rate=44100 --channels=1 -b 24

# Presets
nanodsp preset list
nanodsp preset list spatial
nanodsp preset info master
nanodsp preset apply master input.wav output.wav target_lufs=-16

# Pipe (stdin/stdout streaming)
cat input.wav | nanodsp pipe -f lowpass:cutoff_hz=1000 > output.wav
cat input.wav | nanodsp pipe -p telephone > output.wav
nanodsp pipe -f highpass:cutoff_hz=80 < in.wav | nanodsp pipe -f compress:ratio=4 > out.wav

# Benchmark
nanodsp benchmark lowpass:cutoff_hz=1000
nanodsp benchmark compress:ratio=4,threshold=-20 -n 100 --duration=2.0
nanodsp benchmark reverb:preset=hall --channels=2 --json

# List available functions
nanodsp list
nanodsp list filters
nanodsp list effects

Presets

30 built-in presets across 8 categories:

Category Presets
mastering master, master_pop, master_hiphop, master_classical, master_edm, master_podcast
voice vocal_chain
spatial room, hall, plate, cathedral, chamber
dynamics gentle_compress, heavy_compress, brick_wall
creative radio, underwater, megaphone, tape_warmth, shimmer, vaporwave, walkie_talkie
lofi telephone, lo_fi, vinyl, 8bit
cleanup dc_remove, de_noise, normalize, normalize_lufs

Quick start

from nanodsp.buffer import AudioBuffer
from nanodsp import effects, analysis

# Read, process, write
buf = (
    AudioBuffer.from_file("input.wav")
    .pipe(effects.highpass, freq=80.0)
    .pipe(effects.compress, threshold=-18.0, ratio=4.0)
    .pipe(analysis.normalize_lufs, target_lufs=-14.0)
)
buf.write("output.wav")

Modules

nanodsp.buffer -- AudioBuffer

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

from nanodsp.buffer import AudioBuffer

# Construction
buf = AudioBuffer(np.zeros((2, 44100), dtype=np.float32), sample_rate=44100)
buf = AudioBuffer.from_file("input.wav")       # read WAV/FLAC
buf = AudioBuffer.sine(440.0, channels=1, frames=44100, sample_rate=44100)
buf = AudioBuffer.noise(channels=2, frames=44100, sample_rate=44100)
buf = AudioBuffer.zeros(channels=1, frames=1024, sample_rate=44100)
buf = AudioBuffer.impulse(channels=1, frames=1024, sample_rate=44100)

# Properties
buf.channels        # number of channels
buf.frames          # number of frames
buf.sample_rate     # sample rate in Hz
buf.duration        # duration in seconds
buf.mono            # 1D view (mono buffers only)
buf.channel(0)      # 1D view of channel 0

# Channel operations
buf.to_mono("mean")                    # downmix
buf.to_channels(2)                     # upmix mono to stereo
AudioBuffer.concat_channels(a, b)      # stack channels

# Arithmetic
buf + other          # add
buf * 0.5            # scale
buf.gain_db(-6.0)    # apply dB gain

# I/O
buf.write("output.wav")                # write WAV/FLAC (detected by extension)
buf.write("output.flac", bit_depth=24)

# Pipeline
buf.pipe(effects.lowpass, freq=1000.0)

nanodsp.io -- Audio file I/O

Read and write WAV (8/16/24/32-bit PCM) and FLAC (16/24-bit) files. Zero external dependencies for WAV (uses stdlib wave); FLAC uses the CHOC codec.

from nanodsp import io

buf = io.read("file.wav")          # auto-detect by extension
buf = io.read("file.flac")
io.write("out.wav", buf)           # 16-bit default
io.write("out.flac", buf, bit_depth=24)

# Format-specific
buf = io.read_wav("file.wav")
io.write_wav("out.wav", buf, bit_depth=24)
buf = io.read_flac("file.flac")
io.write_flac("out.flac", buf, bit_depth=16)

# Byte-level (for stdin/stdout/pipe workflows)
buf = io.read_wav_bytes(raw_bytes)           # parse WAV from bytes
raw = io.write_wav_bytes(buf, bit_depth=16)  # serialize to WAV bytes

nanodsp.ops -- Core DSP operations

Low-level building blocks: delay, envelopes, FFT, convolution, sample rates, mixing, panning, normalization, cross-correlation, Hilbert transform, median filter, LMS adaptive filter.

from nanodsp import ops

# Delay
ops.delay(buf, delay_samples=100)
ops.delay_varying(buf, delays=delay_curve)

# Envelopes
ops.box_filter(buf, length=64)
ops.box_stack_filter(buf, size=32, layers=4)
ops.peak_hold(buf, length=128)
ops.peak_decay(buf, length=256)

# FFT
spectra = ops.rfft(buf)                        # forward real FFT
buf = ops.irfft(spectra, size=1024, sample_rate=44100)  # inverse

# Convolution
ops.convolve(buf, ir, normalize=True)

# Sample rates
ops.upsample_2x(buf)
ops.oversample_roundtrip(buf)

# Mixing
ops.hadamard(buf)              # Hadamard matrix mixing
ops.householder(buf)           # Householder reflection
ops.crossfade(buf_a, buf_b, x=0.5)
ops.mix_buffers(a, b, c, gains=[1.0, 0.5, 0.8])

# LFO
lfo_signal = ops.lfo(frames=44100, low=0.0, high=1.0, rate=2.0)

# Normalization
ops.normalize_peak(buf, target_db=-1.0)
ops.trim_silence(buf, threshold_db=-60.0)

# Fades
ops.fade_in(buf, duration_ms=10.0)
ops.fade_out(buf, duration_ms=50.0, curve="exp")

# Panning and stereo
ops.pan(buf, position=0.3)     # equal-power pan
ops.mid_side_encode(buf)
ops.mid_side_decode(buf)
ops.stereo_widen(buf, width=1.5)

# Cross-correlation
corr = ops.xcorr(buf_a, buf_b)        # cross-correlation
auto = ops.xcorr(buf)                  # autocorrelation

# Hilbert / envelope
env = ops.hilbert(buf)                 # analytic signal envelope
env = ops.envelope(buf)                # alias for hilbert

# Median filter
ops.median_filter(buf, kernel_size=5)

# LMS adaptive filter
output, error = ops.lms_filter(buf, ref, filter_len=32, step_size=0.01)

nanodsp.effects -- Filters, effects, dynamics, mastering

53 functions covering signalsmith biquad filters, DaisySP effects/filters/dynamics, composed effects, reverbs, mastering chains, STK effects, and automatic gain control.

Biquad filters (signalsmith)

All filter functions take freq in Hz, auto-converted to normalized frequency.

from nanodsp import effects

effects.lowpass(buf, freq=1000.0, q=0.707)
effects.highpass(buf, freq=80.0)
effects.bandpass(buf, freq=1000.0, q=2.0)
effects.notch(buf, freq=50.0)
effects.peak(buf, freq=1000.0, gain=2.0, q=1.0)
effects.peak_db(buf, freq=1000.0, db=6.0)
effects.high_shelf(buf, freq=8000.0, gain=1.5)
effects.high_shelf_db(buf, freq=8000.0, db=3.0)
effects.low_shelf(buf, freq=200.0, gain=0.8)
effects.low_shelf_db(buf, freq=200.0, db=-2.0)
effects.allpass(buf, freq=1000.0)

DaisySP effects

effects.autowah(buf, wah=0.5)
effects.chorus(buf, rate=1.0, depth=0.5)
effects.decimator(buf, downsample_factor=0.5, bitcrush_factor=0.5)
effects.flanger(buf, rate=0.2, depth=0.5, feedback=0.5)
effects.overdrive(buf, drive=0.7)
effects.phaser(buf, rate=0.3, depth=0.5, feedback=0.5)
effects.pitch_shift(buf, semitones=12.0)
effects.sample_rate_reduce(buf, factor=0.5)
effects.tremolo(buf, rate=5.0, depth=0.8)
effects.wavefold(buf, gain=2.0)
effects.bitcrush(buf, bits=8)
effects.fold(buf, gain=2.0)
effects.reverb_sc(buf, feedback=0.8, lpfreq=10000.0)
effects.dc_block(buf)

DaisySP filters

effects.svf_lowpass(buf, freq=1000.0, res=0.5)
effects.svf_highpass(buf, freq=200.0, res=0.5)
effects.svf_bandpass(buf, freq=1000.0, res=0.7)
effects.svf_notch(buf, freq=1000.0, res=0.5)
effects.svf_peak(buf, freq=1000.0, res=0.8)
effects.ladder_filter(buf, freq=800.0, res=0.6, mode="lp24")
effects.moog_ladder(buf, freq=1000.0, res=0.7)
effects.tone_lowpass(buf, freq=2000.0)
effects.tone_highpass(buf, freq=100.0)
effects.modal_bandpass(buf, freq=440.0, q=50.0)
effects.comb_filter(buf, freq=500.0, revtime=0.5)

Dynamics

effects.compress(buf, threshold=-20.0, ratio=4.0, attack=0.01, release=0.1)
effects.limit(buf, threshold=-1.0)

Composed effects

effects.saturate(buf, drive=0.7, mode="soft")    # soft, hard, or tape
effects.exciter(buf, freq=3000.0, drive=0.4)
effects.de_esser(buf, freq=6000.0, threshold=-20.0)
effects.parallel_compress(buf, mix=0.5, threshold=-24.0, ratio=8.0)
effects.noise_gate(buf, threshold_db=-40.0)
effects.stereo_delay(buf, delay_l=0.25, delay_r=0.375, feedback=0.4, ping_pong=True)
effects.multiband_compress(buf, crossovers=[200.0, 2000.0, 8000.0])

Reverb

effects.reverb(buf, preset="hall", decay=2.0, mix=0.3)
# Presets: room, hall, plate, chamber, cathedral

Mastering and vocal chains

effects.master(buf, target_lufs=-14.0)
effects.vocal_chain(buf, de_ess_freq=6000.0, comp_threshold=-18.0)

STK effects

effects.stk_reverb(buf, algorithm="freeverb", decay=1.5, mix=0.3)
effects.stk_chorus(buf, mod_depth=0.02, mod_freq=1.0, mix=0.5)
effects.stk_echo(buf, delay=0.25, max_delay=1.0, mix=0.5)

Automatic gain control

effects.agc(buf, target_level=1.0, max_gain_db=60.0, average_len=100, attack=0.01, release=0.01)

nanodsp.spectral -- STFT and spectral processing

Short-time Fourier transform, spectral utilities, and spectral transforms.

from nanodsp import spectral

# STFT
spec = spectral.stft(buf, window_size=2048, hop_size=512)
buf = spectral.istft(spec)

# Spectral utilities
mag = spectral.magnitude(spec)
ph = spectral.phase(spec)
spec = spectral.from_polar(mag, ph)
spec = spectral.apply_mask(spec, mask)
spec = spectral.spectral_gate(spec, threshold_db=-40.0)
spec = spectral.spectral_emphasis(spec, low_db=-3.0, high_db=3.0)
freq = spectral.bin_freq(bin_index=10, fft_size=2048, sample_rate=44100)
b = spectral.freq_to_bin(freq=1000.0, fft_size=2048, sample_rate=44100)

# Spectral transforms
stretched = spectral.time_stretch(buf, rate=0.5)        # half speed
locked = spectral.phase_lock(spec)                       # identity phase-locking
frozen = spectral.spectral_freeze(buf, frame_index=10)   # frozen texture
morphed = spectral.spectral_morph(spec_a, spec_b, x=0.5)
shifted = spectral.pitch_shift_spectral(buf, semitones=5.0)
denoised = spectral.spectral_denoise(buf, noise_frames=10)

# EQ matching
matched = spectral.eq_match(source_buf, target_buf, strength=1.0)

nanodsp.synthesis -- Oscillators, noise, drums, physical modeling

Sound generators using DaisySP and STK backends.

from nanodsp import synthesis

# Oscillators
synthesis.oscillator(freq=440.0, waveform="saw", frames=44100)
synthesis.fm2(freq=440.0, ratio=2.0, index=1.0, frames=44100)
synthesis.formant_oscillator(freq=440.0, formant_freq=800.0, frames=44100)
synthesis.bl_oscillator(freq=440.0, waveform="saw", frames=44100)

# Noise
synthesis.white_noise(frames=44100, amp=0.5)
synthesis.clocked_noise(freq=1000.0, frames=44100)
synthesis.dust(density=100.0, frames=44100)

# Drums
synthesis.analog_bass_drum(freq=60.0, frames=44100)
synthesis.analog_snare_drum(freq=200.0, frames=44100)
synthesis.hihat(freq=3000.0, frames=44100)
synthesis.synthetic_bass_drum(freq=60.0, frames=44100)
synthesis.synthetic_snare_drum(freq=200.0, frames=44100)

# Physical modeling
synthesis.karplus_strong(buf, freq=440.0, brightness=0.5, damping=0.5)
synthesis.modal_voice(freq=440.0, frames=44100)
synthesis.string_voice(freq=440.0, frames=44100)
synthesis.pluck(freq=440.0, frames=44100)
synthesis.drip(freq=1000.0, frames=44100)

# STK synthesis
synthesis.synth_note("clarinet", freq=440.0, amplitude=0.8, duration=1.0)
synthesis.synth_sequence("flute", notes=[
    {"freq": 440.0, "amp": 0.8, "start": 0.0, "dur": 0.5},
    {"freq": 554.37, "amp": 0.7, "start": 0.5, "dur": 0.5},
])

Available STK instruments: clarinet, flute, brass, bowed, plucked, sitar, stifkarp, saxofony, recorder, blowbotl, blowhole, whistle.

nanodsp.analysis -- Loudness, spectral features, pitch, onsets, resampling

from nanodsp import analysis

# Loudness (ITU-R BS.1770-4)
lufs = analysis.loudness_lufs(buf)
buf = analysis.normalize_lufs(buf, target_lufs=-14.0)

# Spectral features
centroid = analysis.spectral_centroid(buf)
bandwidth = analysis.spectral_bandwidth(buf)
rolloff = analysis.spectral_rolloff(buf, percentile=0.85)
flux = analysis.spectral_flux(buf, rectify=True)
flatness = analysis.spectral_flatness_curve(buf)
chroma = analysis.chromagram(buf, n_chroma=12, tuning_hz=440.0)

# Pitch detection (YIN algorithm)
f0, confidence = analysis.pitch_detect(buf, method="yin", fmin=50.0, fmax=2000.0)

# Onset detection
onsets = analysis.onset_detect(buf, method="spectral_flux", threshold=0.5)

# Resampling
buf_48k = analysis.resample(buf, target_sr=48000.0)       # madronalib backend
buf_22k = analysis.resample_fft(buf, target_sr=22050.0)   # FFT-based

# GCC-PHAT delay estimation
delay_sec, corr = analysis.gcc_phat(buf, ref)

nanodsp.stream -- Real-time streaming infrastructure

Block-based processing, ring buffers, and processor chains for streaming audio.

from nanodsp.stream import (
    RingBuffer, BlockProcessor, CallbackProcessor, ProcessorChain, process_blocks
)

# Ring buffer
rb = RingBuffer(channels=2, capacity=8192)
rb.write(frame_data)
chunk = rb.read(512)

# Block processor
class MyProcessor(BlockProcessor):
    def process_block(self, block):
        return block * 0.5

proc = MyProcessor(block_size=512)
out = proc.process(buf)

# Callback processor
proc = CallbackProcessor(block_size=512, fn=lambda b: b * 0.5)

# Chain processors
chain = ProcessorChain([proc1, proc2, proc3])
out = chain.process(buf)

# Process with overlap-add
out = process_blocks(buf, block_size=2048, hop_size=512, fn=my_spectral_fn)

nanodsp._core.grainflow -- Granular synthesis (low-level)

Direct access to GrainflowLib's granular synthesis engine.

from nanodsp._core import grainflow as gf

# Create a buffer and fill with audio data
buf = gf.GfBuffer(4096, 1, 48000)
buf.set_data(audio_array)  # [channels, frames] float32

# Create a grain collection
gc = gf.GrainCollection(num_grains=8, samplerate=48000)
gc.set_buffer(buf, gf.BUF_BUFFER, 0)  # 0 = set for all grains

# Set parameters (enum-based or string reflection)
gc.param_set(0, gf.PARAM_RATE, gf.PTYPE_BASE, 1.0)
gc.param_set_str(0, "delayRandom", 10.0)

# Generate a clock and process
phasor = gf.Phasor(rate=10.0, samplerate=48000)
clock = phasor.perform(256).reshape(1, 256)
traversal = np.linspace(0, 0.5, 256, dtype=np.float32).reshape(1, 256)
fm = np.zeros((1, 256), dtype=np.float32)
am = np.zeros((1, 256), dtype=np.float32)

# Returns 8-element tuple: (output, state, progress, playhead, amp, envelope, buf_ch, stream_ch)
result = gc.process(clock, traversal, fm, am, 48000)
grain_output = result[0]  # [num_grains, block_size]

# Pan grains to stereo
panner = gf.Panner(in_channels=8, out_channels=2, pan_mode=gf.PAN_STEREO)
panner.set_pan_spread(0.5)
stereo = panner.process(grain_output, result[1], out_channels=2)  # [2, block_size]

nanodsp._core -- C++ bindings (low-level)

Direct access to the C++ extension module with 13 submodules. All high-level Python modules build on these.

Submodule Backend Contents
filters signalsmith Biquad with 16 filter designs, BiquadDesign enum
fft signalsmith FFT (complex), RealFFT (real)
delay signalsmith Delay (linear), DelayCubic (cubic interpolation)
envelopes signalsmith CubicLfo, BoxFilter, BoxStackFilter, PeakHold, PeakDecayLinear
spectral signalsmith STFT (multi-channel analysis/synthesis)
rates signalsmith Oversampler2x
mix signalsmith Hadamard, Householder, cheap_energy_crossfade
daisysp DaisySP 9 submodules, ~60 classes (oscillators, filters, effects, dynamics, drums, noise, physical modeling, control, utility)
stk STK 5 submodules, 39 classes (instruments, generators, filters, delays, effects)
madronalib madronalib FDN reverbs, resampling, generators, 18 projection functions, 6 window functions
hisstools HISSTools Convolution (mono/multi), spectral processing, 24 statistics functions, 28 window functions, partial tracking
choc CHOC FLAC read/write
grainflow GrainflowLib GfBuffer, GrainCollection, Panner, Recorder, Phasor, 37 enum constants
from nanodsp._core import filters, fft, delay, daisysp, stk, madronalib, hisstools, grainflow

# Example: direct biquad usage
bq = filters.Biquad()
bq.lowpass(0.1, 0.707)
out = bq.process(input_array)

# Example: direct FFT
f = fft.RealFFT(1024)
spectrum = f.fft(signal)

# Example: DaisySP oscillator
osc = daisysp.oscillators.Oscillator()
osc.init(44100.0)
osc.set_freq(440.0)
samples = osc.process(1024)

Full type stubs are provided in _core.pyi for IDE autocompletion and type checking.

Architecture

nanodsp/
  __init__.py          # package root (__version__ only)
  __main__.py          # CLI entry point (argparse, subcommand handlers)
  _cli.py              # function/preset registries, fx parser, type coercion
  _core.cpython-*.so   # compiled C++ extension (nanobind)
  _core.pyi            # type stubs for C++ extension
  _helpers.py          # shared private utilities
  buffer.py            # AudioBuffer class
  io.py                # audio file I/O (WAV + FLAC)
  ops.py               # delay, envelopes, FFT, convolution, rates, mix, pan, xcorr, hilbert, median, LMS
  effects.py           # filters, effects, dynamics, reverb, mastering, AGC
  spectral.py          # STFT, spectral transforms, eq_match
  synthesis.py         # oscillators, noise, drums, physical modeling
  analysis.py          # loudness, spectral features, pitch, onsets, resample, gcc_phat
  stream.py            # ring buffer, block processors, overlap-add

Demos

16 demo scripts in demos/ showcase the full API surface. Run them all at once:

make demos                              # uses demos/s01.wav
make demos DEMO_INPUT=my_audio.wav      # use a custom input file

Or run individual demos:

uv run python demos/demo_filters.py demos/s01.wav
uv run python demos/demo_reverb.py demos/s01.wav -o /tmp/reverb-output
uv run python demos/demo_distortion.py demos/s01.wav --no-normalize
uv run python demos/demo_synthesis.py                # no input file needed
uv run python demos/demo_analysis.py demos/s01.wav   # prints to stdout
Script Variants What it demonstrates
demo_filters.py 13 Lowpass, highpass, bandpass, notch, peak EQ, high/low shelf
demo_modulation.py 10 Chorus, flanger, phaser, tremolo
demo_distortion.py 14 Overdrive, wavefold, bitcrush, decimator, saturation, fold
demo_reverb.py 12 FDN presets, ReverbSc, STK freeverb/jcrev/nrev/prcrev
demo_dynamics.py 9 Compression, limiting, noise gate, parallel/multiband compression
demo_delay.py 8 Stereo delay, ping-pong, slapback, STK echo
demo_pitch.py 10 Time-domain and spectral pitch shifting
demo_spectral.py 12 Time stretch, phase lock, spectral gate, tilt EQ, freeze
demo_daisysp_filters.py 21 SVF, ladder, moog, tone, modal, comb filters
demo_composed.py 13 Autowah, SR reduce, DC block, exciter, de-esser, vocal chain, mastering, STK chorus
demo_spectral_extra.py 8 Spectral denoise, EQ match, spectral morph
demo_ops.py 29 Delay, vibrato, convolution, envelopes, fades, panning, stereo widening, crossfade
demo_resample.py 6 Madronalib and FFT resampling at 22k/48k/96k
demo_synthesis.py 44 Oscillators, FM, noise, drums, physical modeling, STK instruments (no input file)
demo_analysis.py -- Loudness, spectral features, pitch, onsets, chromagram (stdout only)
demo_grainflow.py 7 Granular clouds (basic, dense), pitch shift, sparse stochastic, stereo panning, recorder

File-processing scripts share the same interface:

usage: demo_*.py [-h] [-o OUT_DIR] [-n] infile

positional arguments:
  infile                Input .wav file

options:
  -o, --out-dir DIR     Output directory (default: build/demo-output)
  -n, --no-normalize    Skip peak normalization (may clip on PCM output)

demo_synthesis.py generates sounds from scratch (no input file; takes -o and -n only). demo_analysis.py prints measurements to stdout (no audio output). demo_grainflow.py processes an input file through granular synthesis.

Development

make build    # rebuild extension after C++ changes
make test     # run 1163 tests
make demos    # run all 16 demo scripts
make qa       # test + lint + typecheck + format
make coverage # tests with coverage report

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nanodsp-0.1.3.tar.gz (36.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nanodsp-0.1.3-cp314-cp314-win_amd64.whl (737.4 kB view details)

Uploaded CPython 3.14Windows x86-64

nanodsp-0.1.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (819.5 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanodsp-0.1.3-cp314-cp314-macosx_11_0_arm64.whl (691.7 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

nanodsp-0.1.3-cp314-cp314-macosx_10_15_x86_64.whl (758.1 kB view details)

Uploaded CPython 3.14macOS 10.15+ x86-64

nanodsp-0.1.3-cp313-cp313-win_amd64.whl (715.5 kB view details)

Uploaded CPython 3.13Windows x86-64

nanodsp-0.1.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (819.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanodsp-0.1.3-cp313-cp313-macosx_11_0_arm64.whl (691.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nanodsp-0.1.3-cp313-cp313-macosx_10_15_x86_64.whl (757.8 kB view details)

Uploaded CPython 3.13macOS 10.15+ x86-64

nanodsp-0.1.3-cp312-cp312-win_amd64.whl (715.6 kB view details)

Uploaded CPython 3.12Windows x86-64

nanodsp-0.1.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (819.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanodsp-0.1.3-cp312-cp312-macosx_11_0_arm64.whl (691.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nanodsp-0.1.3-cp312-cp312-macosx_10_15_x86_64.whl (758.0 kB view details)

Uploaded CPython 3.12macOS 10.15+ x86-64

nanodsp-0.1.3-cp311-cp311-win_amd64.whl (715.3 kB view details)

Uploaded CPython 3.11Windows x86-64

nanodsp-0.1.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (819.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanodsp-0.1.3-cp311-cp311-macosx_11_0_arm64.whl (692.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nanodsp-0.1.3-cp311-cp311-macosx_10_15_x86_64.whl (753.9 kB view details)

Uploaded CPython 3.11macOS 10.15+ x86-64

nanodsp-0.1.3-cp310-cp310-win_amd64.whl (715.1 kB view details)

Uploaded CPython 3.10Windows x86-64

nanodsp-0.1.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (819.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanodsp-0.1.3-cp310-cp310-macosx_11_0_arm64.whl (691.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

nanodsp-0.1.3-cp310-cp310-macosx_10_15_x86_64.whl (753.5 kB view details)

Uploaded CPython 3.10macOS 10.15+ x86-64

File details

Details for the file nanodsp-0.1.3.tar.gz.

File metadata

  • Download URL: nanodsp-0.1.3.tar.gz
  • Upload date:
  • Size: 36.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3.tar.gz
Algorithm Hash digest
SHA256 3b8b76fe79b719d5ec51b68bbb094d8a86b61972dbbc5493feff74570e6138da
MD5 7a8cab6dcc2394313f5b291b54b3b76d
BLAKE2b-256 86b2983a0729635eb88765288dd603e05ee7ef56f6c543c1f359498ed32ba96b

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: nanodsp-0.1.3-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 737.4 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 a7d43d7b334e1311c1570facbe1725b461392db306d06b2e3e496ef6913508e9
MD5 c7ee0c2bc6bb1cdea8e6f51adaca1b82
BLAKE2b-256 752421f651405a4f45cb88f19fb53cec0cc51d682d42e58663cf799d05ef1bab

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2c9318ada69f7e5e8246807cab9468f64cd89e01b6d3577bacdd7ac2c415fc76
MD5 0c99544df4370ca402f40159b13ed364
BLAKE2b-256 a7c008e4a8ce26ef0fc5a51337c45829faf9eea20b18f3edc9177c243946a359

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8c7b1a38874b299b3b23ea0f01406fe8db8daff2186f9b3318e6719f0fd325b0
MD5 3d3be3027e68f4f7669c79e8bf73d85b
BLAKE2b-256 432bae56e76cbfa5f242bf655bae01918bd4845a71b2e4b1ddcfd13d65ae5104

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp314-cp314-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp314-cp314-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 b015935584f53dfcaaa435b54ffacc7f97b5fff4b345fdf23539839a02f58b36
MD5 2b7c43611903c7eee268aa3c5889676b
BLAKE2b-256 9184c89c0836a7858502c108d27cc66571f1ac1282c7b6e00d127f39f5185237

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nanodsp-0.1.3-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 715.5 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 ce4f55671120ebb6b485d056ba7bb2b008290790f2fb892552adeb96e2974161
MD5 bc2fdbc468184225bb31fdf405a0fbc9
BLAKE2b-256 cb54bf0189e3e17520448b10a366b3c28a3bf2569d057d1649ede83dc640db35

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cf5c20370907e152de44dd850f4e268ccc9b29b2959093de3e5f28ee138e2bc9
MD5 568b8cb0d4ba40050b83874ce19c5fc8
BLAKE2b-256 83a5acecd9a1ab11602d3211bf33e2b2399bfa91702268e161d8f6085c57c972

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e476d315fcb7bec9da9054edf61f421214472b1b339d3b1fd8059589795d8fb7
MD5 fb8425a9111dbb2a1cd6a15698e5fbd3
BLAKE2b-256 358dcb40da8624a8c2f0fc3623659b283adb80e454c04723f6bb5b29e72ad32b

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp313-cp313-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp313-cp313-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 a9c2201f3dbcecf6595812d433657317f23d1e68b813689723fdc5c7c1128277
MD5 f3bae261716795866605ff7c4867ceaf
BLAKE2b-256 153cc9ae7b5f1220dba5f4aa633357f356591cdacd2baf37beaf32293b881e5b

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: nanodsp-0.1.3-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 715.6 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2569ef97c5005a7c4c7b9ff9482b48959c5451abbf9ca9974964b60f47a314a6
MD5 d039df2b450ae8352c2631a5605bd13d
BLAKE2b-256 6bcaa56b19cb1e2f8172c0d760d4d92950ee457d0936562870c275bb90cdc071

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d0c3be0fdc759ba1276711b524b636baf51cf569486a40b2312f0f66b5a6bbac
MD5 f1daeb4cd1197a38af8f7f46a654c5c5
BLAKE2b-256 22b8c62cad3939cfbd13d924eb596959541334b2d55dc643e19f4736163e3078

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 897f30fcac208a4e49d5164dd636a0168907f88cdb422ecb02517ce47bc7902c
MD5 ae951758a30226a959635c7f9db3eaf3
BLAKE2b-256 87d612f715343155a268e9691d4234f96641bfda51bbf023d9a0e3c90b609e10

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp312-cp312-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp312-cp312-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 6cbf0140605ce2052327d9d10bcb4f4afd2cf0b6a3e0398b1808dcefc12c4bf8
MD5 44b150dfebb4170aa27d671293fca78e
BLAKE2b-256 1fd62a33b8088534294fe66132d17e63dca8a8108d41de7cdee3b131880ead40

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: nanodsp-0.1.3-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 715.3 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 78d187cc1e6b8b0c8c8564ca8a3018f14cdc40ae2536a9fc841c5472f77d5070
MD5 887245f0914f9a36688f2e9064491dcc
BLAKE2b-256 9fdfe2477baa95c10360658aba6b1f38b78424992b784ff34953e28dec3f0994

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2dbc6859be5fa2a8053b3c8fb84353e5bcc6969183eb29d517de8dda51f824eb
MD5 8ccadd786963b39649b997b63602e7c0
BLAKE2b-256 179f91f0b1fc254b0e7602351d887ba20d7fef4957b6fb585bc881ec572a76a2

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f182aaaa2142cae9762723ae091ae09f1f1589684412dd3928a678d544ecba04
MD5 ebafb8d0bf3712658f80454cfb0e47c2
BLAKE2b-256 4d41b9cd855f7d66f62e8ca37ca6e947343b0aa49725f59c888506a924f87593

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp311-cp311-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp311-cp311-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 c0a008dead1196418e72b6d20f29db1763b531d4bdbe896776e21a40cbd6dc6b
MD5 ee6bd883315342ff3fb7ad430123c669
BLAKE2b-256 680111530569fe3c8d38f991a64f3eec72de62889a25bb3429afade14965a983

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: nanodsp-0.1.3-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 715.1 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanodsp-0.1.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 86f31db8aedb4c445c70da23d39635ba9ab6c95cd11a67f41e43e0ad8e4b4632
MD5 7be41c7f084e81a54bd0dc08639568f7
BLAKE2b-256 69e00c11e8285f7c4e4da578cc4c7b55b2995615ff8acab09c56b5791a55ea00

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 97b89d9dd1b8880d1a50db66ce5831274ab9d0ab625a8e266241273fe5d0378e
MD5 a591bcbf6bb99f6706cb09031b3034c0
BLAKE2b-256 7047ee99a6c9b91fdaf796723d556971436bb6942f30c23390ec15c1f61e1124

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c44042c6e59128ded06e190a6b61a743493532489fe6eb19138aaf5bb1e00fc5
MD5 e1dc86c2bcf8253301ed61d6923a1267
BLAKE2b-256 479b7a8bacd7c96fc1af01d12463455e31b049bc77c48ef99e8cbce2dd06d9a4

See more details on using hashes here.

File details

Details for the file nanodsp-0.1.3-cp310-cp310-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nanodsp-0.1.3-cp310-cp310-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 1a32530fd70b6191a0923bfedc0c35343d73d210e66207dc6f9bdb2f477608d3
MD5 98f960aa307ef29b047b4a5fa986f3cc
BLAKE2b-256 b1c031b330798596aa2218a1641f7a025a8f2a8dc0cdbefdbb05b7e7833ee7d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page