Skip to main content

Trumpet Activity Detection (TAD) for real-time audio streams

Project description

trublib

Trumpet Activity Detection for real-time audio streams.

trublib strips all non-trumpet audio from a microphone stream in real time, passing only confirmed trumpet audio downstream. It is the signal-routing layer inside TRUB.AI, an AI-powered trumpet teaching assistant, sitting between the microphone and the Moshi speech model + MERT audio encoder.

[microphone]  →  TADProcessor.process(chunk)  →  TADResult.masked_audio

Latency: 9.3 ms mean, 39 ms worst case per 80 ms chunk. Well within the 80 ms real-time budget.


Installation

pip install trublib

trublib requires Python ≥ 3.11. The ONNX classifier model (trumpet_scorer_v1.onnx) ships inside the package.

Optional — faster resampling:

pip install soxr          # recommended: high-quality, fast
# pip install resampy     # fallback if soxr is unavailable

Optional — ONNX inference:

pip install onnxruntime   # required for TrumpetScorer (included transitively via trublib[full])

Quickstart

from trublib import TADProcessor, TADConfig
import numpy as np

# One processor per audio stream — not thread-safe
tad = TADProcessor(TADConfig(input_sample_rate=44100, threshold=0.6))

# Your microphone loop — 80ms chunks at whatever sample rate you record at
for chunk in mic_stream:                      # np.ndarray, shape (N,) or (N, 2)
    result = tad.process(chunk)

    # On ACTIVE entry: retroactive attack frames are flushed
    if result.flush:
        for frame in result.flush:
            downstream.send(frame)            # 512-sample raw frames, graduated gain

    # Every chunk: clean gated audio (silence when not playing)
    if result.is_trumpet:
        downstream.send(result.masked_audio)  # original dynamics, no normalisation

    # For UI / diagnostics
    print(result.state, f"P={result.confidence:.3f}")

TADResult fields

Field Type Description
masked_audio np.ndarray Gated audio at original dynamics (silence when not ACTIVE)
state TADState Current state: SILENT, ONSET, ACTIVE, TRAILING
is_trumpet bool True only when state is ACTIVE
confidence float Raw P(trumpet) in [0, 1]
flush list[np.ndarray] | None Retroactive attack frames on ACTIVE entry; None otherwise

Configuration

from trublib import TADConfig

cfg = TADConfig(
    input_sample_rate = 44100,   # your mic's sample rate
    threshold         = 0.6,     # P(trumpet) cutoff — raise to reduce false alarms
    onset_chunks      = 3,       # consecutive chunks above threshold to enter ACTIVE
    trailing_chunks   = 4,       # consecutive chunks below threshold to exit ACTIVE
    lookback_frames   = 3,       # retroactive flush depth on ACTIVE entry
    muted_mode        = False,   # set True for Harmon/wah-wah mutes
    target_rms        = 0.1,     # internal normalisation target for feature extraction
)

Threshold guide:

Threshold Use case
0.4–0.5 Quiet playing, student mic, low gain
0.6 Default — most practice room conditions
0.7–0.8 Noisy environment, reduce false alarms

State machine

SILENT → ONSET → ACTIVE → TRAILING → SILENT
              ↘ (confidence drops before onset_chunks)  → SILENT
                              TRAILING → ACTIVE  (confidence recovers)
  • SILENT: output muted. Frames accumulate in the ring buffer silently.
  • ONSET: first confirmed chunk above threshold. Accumulating evidence over onset_chunks — "hard to start".
  • ACTIVE: trumpet confirmed. masked_audio passes through at original level. flush emitted once on entry with the note attack frames from the ring buffer.
  • TRAILING: confidence dropped. Hold-off for trailing_chunks before silencing — "slow to stop". Gain fades linearly. Confidence recovery snaps back to ACTIVE without re-entering ONSET.

Custom model

from pathlib import Path
from trublib import TADProcessor, TADConfig

tad = TADProcessor(
    config=TADConfig(),
    model_path=Path("path/to/your_model.onnx"),
)

The model must accept float32 input of shape (N, 106) and output class probabilities of shape (N, 2)[P(non_trumpet), P(trumpet)]. See scripts/train_classifier.py for how the bundled model was trained.


Running the demo server

pip install fastapi uvicorn python-multipart onnxruntime
python -m uvicorn tad_demo.app:app --port 8000

Open http://localhost:8000 — drag-and-drop any audio file (any format, via ffmpeg), adjust threshold and hysteresis sliders, compare original vs processed audio side by side, download the cleaned WAV.

Windows / Anaconda: always use python -m uvicorn, never bare uvicorn. Install onnxruntime in the same Python environment: python -m pip install onnxruntime.


Development

git clone https://github.com/your-org/trublib
cd trublib
pip install -e ".[dev]"
pytest tests/ -v

127 tests, 4 test files covering frame extraction, feature correctness, acoustic separation, state machine transitions, and the full pipeline.


Architecture

See docs/architecture.md for the full pipeline breakdown, feature family descriptions, and design decisions.

For retraining the classifier on your own data, see docs/training.md.


Licence

Source code: MIT

Bundled model weights: Non-commercial / research / educational use only. The model was trained on datasets that carry NonCommercial upstream terms (IRMAS, ESC-50, good-sounds). See docs/data.md for full attribution and NOTICE for the summary.

To produce commercially-usable weights, retrain using only CC0 / CC BY sources. See docs/training.md for instructions.

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

trublib-0.1.0.tar.gz (274.6 kB view details)

Uploaded Source

Built Distribution

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

trublib-0.1.0-py3-none-any.whl (259.6 kB view details)

Uploaded Python 3

File details

Details for the file trublib-0.1.0.tar.gz.

File metadata

  • Download URL: trublib-0.1.0.tar.gz
  • Upload date:
  • Size: 274.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for trublib-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ed469654d0c054e30ccfe5645f7aef645dee286edd552e7c1d4451e5acd3bb16
MD5 f9d0cc26ac0dc3914299ad1026b989d5
BLAKE2b-256 88b05663db164d48d13cd6e491e290b2e7fdfa5546c76d0ab12e01b402866c14

See more details on using hashes here.

File details

Details for the file trublib-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: trublib-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 259.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for trublib-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 22953ba09f5aec7ac159b85cedb828a93d4fcfd3f9b778aa97c17d4107d75b01
MD5 041758b846a62d8b614f97eb1aad8359
BLAKE2b-256 ae211bd1e14ad8aa8db7e75bb4508b7c57959afd95bd6797a21d88c12fe408cc

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