Skip to main content

Real-time acoustic alarm pattern detection engine

Project description

Acoustic Engine

Lightweight, Deterministic Sound Recognition for IoT

Python 3.9+ License: CC BY-NC 4.0 Embedded Ready

A high-performance, noise-resilient DSP library designed to detect specific acoustic patterns (Smoke Alarms, CO Detectors, Appliance Beeps) on lightweight hardware.

[!TIP] Why this engine? Unlike heavy Neural Networks, the Acoustic Engine uses deterministic Digital Signal Processing (DSP) to achieve high accuracy with low CPU usage. Best for battery-powered or resource-constrained IoT devices.

[!NOTE] New here? → Getting Started takes you from install to a working detector in about ten minutes, no signal-processing knowledge needed.

Features

  • Installs clean on a laptop: pip install acoustic-engine and go — PortAudio is bundled in the macOS/Windows wheels (Linux: one apt line). No compilers, no heavy ML stack.
  • Zero-config presets: ship-ready profiles for standardized smoke (T3) and CO (T4) alarms — acoustic-engine run --preset smoke_t3.
  • Learn from a recording: acoustic-engine learn alarm.wav turns a clip of your alarm into a working profile automatically — no DSP knowledge required.
  • One CLI: run, learn, test, profiles, serve, plus devices/doctor to confirm your mic works in seconds — reference.
  • Act on detections: publish MQTT, POST a webhook, or run any shell command (--on-detect) — turn a laptop into an alarm-watching agent.
  • Noise Resilient: event analysis that ignores background interference (down to ~-15 dB SNR).
  • Efficient: real-time FFT with low CPU usage — runs comfortably on a Raspberry Pi.
  • Easy config: simple YAML profiles, validated on load with clear error messages.

Quick Start

Installation

pip install acoustic-engine

# …or the very latest from git
pip install "git+https://github.com/h0tp-ftw/acoustic-engine.git"

Audio capture uses sounddevice, whose macOS and Windows wheels bundle PortAudio — so on a laptop there is nothing else to install. On Linux, add the small PortAudio runtime once:

sudo apt install libportaudio2     # Debian / Ubuntu / Raspberry Pi OS

For development, clone with the optional extras (mqtt = publish detections, tuner = browser app API, dev = tests):

git clone https://github.com/h0tp-ftw/acoustic-engine.git
cd acoustic-engine
pip install -e ".[mqtt,tuner,dev]"

Quick Start (CLI)

Everything is behind one acoustic-engine command. The common cases need no DSP knowledge and no config file:

# 0. Is my mic working? (lists inputs, then a 5s live level meter)
acoustic-engine devices
acoustic-engine doctor

# 1. What can I detect out of the box?
acoustic-engine profiles

# 2. Listen for a standard smoke alarm (ISO 8201 T3) — zero config
acoustic-engine run --preset smoke_t3

# 3. Have a recording of YOUR alarm? Turn it into a profile automatically
acoustic-engine learn my_alarm.wav --name "My Dryer"      # writes my_alarm.yaml
acoustic-engine test --profile my_alarm.yaml --audio my_alarm.wav -v   # verify it
acoustic-engine run --profile my_alarm.yaml               # deploy it

# 4. Make it an agent — do something when it fires (no broker needed)
acoustic-engine run --preset smoke_t3 --on-detect 'notify-send "Alarm: {name}"'
acoustic-engine run --preset smoke_t3 --webhook https://ntfy.sh/my-alarms

# 5. Production: run from a config file (multiple alarms, MQTT, tuning)
acoustic-engine run --config config.example.yaml

The three tiers: presets (zero config) → learn + hand-edit the YAML shape (frequencies/durations, no DSP) → advanced engine tuning (you rarely need this). You only go as deep as your sound requires.

Docker

The mic is shared into the container via /dev/snd. See deploy/README.md for systemd and Docker details.

docker compose up engine          # run detection
docker compose run --rm engine acoustic-engine run --preset smoke_t3

Documentation

Guide What's in it
Getting Started Install → detect → learn your own alarm → deploy. Start here.
CLI Reference Every command and option.
Profiles & Troubleshooting How profiles work, and fixes for "won't detect" / "false alarms".
Deployment systemd, Docker, hardware tips.
Tuning Guide The advanced engine knobs (rarely needed).
Architecture How the pipeline works inside.
Changelog What's new in each release.

Profile Tuner (Browser App)

The project includes a React-based browser tool for building alarm YAML configs from audio recordings.

cd tuner
npm install
npm run dev
# Open http://localhost:5173

Features:

  • FFT-based frequency estimation with parabolic interpolation (~10Hz accuracy)
  • Adaptive threshold (noise-floor relative) with spectral gating
  • Auto cycle detection — finds repeating patterns without manual input
  • YAML import/export matching the engine's profile schema
  • Crop, playback, spectrogram visualization

Validate Against the Real Engine

The tuner includes a validation API that runs your audio + profile through the actual detection pipeline (SpectralMonitor, FrequencyFilter, EventGenerator, WindowedMatcher) so you know with certainty whether the engine will detect your alarm.

# Terminal 1: Start the validation API
acoustic-engine serve --port 8787

# Terminal 2: Start the tuner
cd tuner && npm run dev

Click "Validate with Real Engine" in the browser. Engine tone events appear as a cyan overlay on the timeline alongside the browser's own analysis, so you can compare both.


Use Cases

  • Life Safety: Industry-standard Smoke (T3) and CO (T4) alarm detection.
  • Appliances: Detect microwave beeps, oven timers, or dishwasher completion chimes.
  • Medical: Monitor critical patient equipment alarms in noisy hospitals.
  • Industrial: Identify specific machinery fault codes or safety buzzers in high-reverb warehouses.
  • Smart Home: Trigger automation when your doorbell or dryer buzzes.

Not Suited For

  • Single / Lone Beeps: A single beep is too generic. The engine relies on repetition (rhythm) for specificity.
  • Complex Non-Tonal Sounds: Dog barks, glass breaking, or speech. Use a Neural Network for these.
  • Variable Melodies: Tunes that change notes every time.

Alarm Profiles

Define patterns in YAML. One sound = one profile.

name: "SmokeAlarm_T3"
confirmation_cycles: 2

segments:
  - type: "tone"
    frequency: { min: 3150, max: 3350 }
    duration: { min: 0.5, max: 0.7 }
  - type: "silence"
    duration: { min: 0.25, max: 0.5 }
  - type: "tone"
    frequency: { min: 3150, max: 3350 }
    duration: { min: 0.5, max: 0.7 }
  - type: "silence"
    duration: { min: 1.0, max: 3.0 }

# Optional per-profile resolution override
resolution:
  min_tone_duration: 0.05
  dropout_tolerance: 0.05

Optional Parameters

reset_timeout: 10.0      # Seconds of silence before resetting match progress
window_duration: 10.0     # Analysis window size (auto-calculated if omitted)
eval_frequency: 0.5       # How often to evaluate windows

Testing Profiles

Against Audio Files

python -m acoustic_engine.tester \
  --profile profiles/smoke_alarm.yaml \
  --audio recording.wav \
  -v

Live Microphone

python -m acoustic_engine.tester \
  --profile profiles/ \
  --live \
  --duration 60

With Noise Mixing

python -m acoustic_engine.tester \
  --profile profiles/smoke_alarm.yaml \
  --audio recording.wav \
  --noise 0.3 \
  --noise-type white

Noise types: white, pink, brown


Robustness & Benchmarks

Performance Metrics

  • Extreme Noise Resilience: Confirmed detection at -15dB SNR (White/Pink Noise).
  • Spectral Subtraction: Per-bin noise profiling learns and subtracts stationary noise (fans, HVAC, motors).
  • Dynamic Background Rejection: Identifies alarms even in "Cocktail Party" scenarios at negative SNR.
  • Echo/Reverb Rejection: Dip-disconnect logic handles reverb decays of up to 50%.
  • Frequency Drift Tracking: Follows dying piezo buzzers sweeping up to 200Hz without losing lock.
  • Alarm Collision Isolation: Detects target alarm while a louder distractor alarm sounds in a different frequency lane.
  • Absolute Specificity: Zero false positives against imposter timers with similar but incorrect rhythms.

DSP vs Neural Networks

Metric Acoustic Engine (DSP) Neural Network (Edge AI)
CPU 3-5% (Pi 4) 25-80%
Latency ~50ms 200ms+
Determinism 100% (Math) Probabilistic
Data Needed None (Zero-shot) Thousands of samples

Data is needed for configuration file generation, but not for runtime.

Use this engine for specific, repetitive patterns (alarms, beeps, machinery). Use Neural Networks for general semantic sounds (shouting, glass breaking, dog barking).


Architecture

graph TD
    subgraph "Input Layer"
        MIC[Microphone] --> AL[AudioListener]
        FILE[Audio File] --> PR[Manual Processing]
    end

    subgraph "Processing Layer"
        AL --> SM[SpectralMonitor<br/>FFT + Peak Detection]
        PR --> SM
        SM --> FF[FrequencyFilter<br/>Noise Screener]
    end

    subgraph "Analysis Layer"
        FF --> EG[EventGenerator<br/>Peaks to Tones]
        EG --> WM[WindowedMatcher<br/>Pattern Matching]
    end

    subgraph "Output Layer"
        WM --> CB[Callbacks / Detections]
    end

    subgraph "Configuration"
        YP[YAML Profiles] --> WM
        CONFIG[GlobalConfig] --> AL
        CONFIG --> SM
    end
  • Input: Hardware-agnostic. sounddevice for live capture (PyAudio fallback), or process_chunk() for any source.
  • Processing: SpectralMonitor (FFT + adaptive noise floor) then FrequencyFilter (discards irrelevant frequencies).
  • Analysis: EventGenerator (debounces peaks into tone events) then WindowedMatcher (sliding window pattern matching).

See ARCHITECTURE.md for implementation details.


Configuration

system:
  log_level: "INFO"

audio:
  sample_rate: 44100
  chunk_size: 1024

engine:
  min_magnitude: 10.0
  min_sharpness: 1.5
  noise_floor_factor: 3.0
  frequency_tolerance: 50.0
  dip_threshold: 0.6

profiles:
  - include: "profiles/smoke_alarm.yaml"

Parameter Reference

Category Parameter Default Description
DSP min_sharpness 1.5 Ratio a peak must be above its neighbors to be considered a tone.
DSP noise_floor_factor 3.0 Multiplier for the adaptive noise floor threshold.
Gen dip_threshold 0.6 Detects sudden magnitude drops to disconnect reverb tails.
Gen freq_smoothing 0.3 Alpha for EMA frequency tracking (higher = faster tracking).
Match noise_skip_limit 2 Non-matching events to ignore before breaking a cycle.
Match duration_relax_low 0.8 Multiplier for minimum segment duration during matching.

See docs/tuning_guide.md for scenario-based tuning recipes.


Python API

from acoustic_engine import Engine
from acoustic_engine.config import AudioSettings, EngineConfig
from acoustic_engine.profiles import load_profiles_from_yaml

profiles = load_profiles_from_yaml("profiles/smoke_alarm.yaml")

engine = Engine(
    profiles=profiles,
    audio_config=AudioSettings(sample_rate=44100, chunk_size=1024),
    on_detection=lambda name: print(f"ALARM: {name}")
)

engine.start()

Key Classes

  • Engine — Main orchestrator. start() for blocking mic capture, process_chunk() for manual feeding.
  • ParallelEngine — Runs multiple isolated Engine instances sharing one audio input.
  • AlarmProfile — Pattern definition: name, segments, confirmation_cycles, optional resolution.
  • AudioSettings — Audio capture config: sample_rate, chunk_size, device_index, channels.
  • EngineConfig — Pipeline tuning: magnitudes, tolerances, thresholds. Auto-computed from profiles via EngineConfig.from_profiles().

CLI Tools

Command Purpose
python -m acoustic_engine.runner --config <yaml> Production runner (multi-config, parallel pipelines)
python -m acoustic_engine.tester --profile <yaml> --audio <file> Test profiles against audio files
python -m acoustic_engine.tester --profile <yaml> --live Live microphone testing
python -m acoustic_engine.tuner.validate --port 8787 Validation API for the browser tuner

Resource Consumption

Measured on a standard Linux workstation (x86_64):

Resource Idle Active (Listening) Active (Detection)
RAM ~37 MB ~40 MB ~43 MB
CPU (1 Core) < 1% < 1% < 1%

Requirements

  • Python 3.9+
  • System Dependencies: none on macOS/Windows; on Linux, libportaudio2 (sudo apt install libportaudio2) for microphone access.
  • Python Libraries: numpy, sounddevice, PyYAML (installed automatically).

Development

pip install -e ".[dev]"
pytest tests/ -v

License

This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0).

  • Attribution: You must give appropriate credit to @h0tp-ftw on github.com.
  • Non-Commercial: You may not use the material for commercial purposes.

See LICENSE for the full text.

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

acoustic_engine-1.2.0.tar.gz (88.4 kB view details)

Uploaded Source

Built Distribution

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

acoustic_engine-1.2.0-py3-none-any.whl (81.6 kB view details)

Uploaded Python 3

File details

Details for the file acoustic_engine-1.2.0.tar.gz.

File metadata

  • Download URL: acoustic_engine-1.2.0.tar.gz
  • Upload date:
  • Size: 88.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for acoustic_engine-1.2.0.tar.gz
Algorithm Hash digest
SHA256 1c3f3912b75dbc7c048016592dfec8a170f63c833e2ccadb6491c28ad590bd62
MD5 a8d211c146e69fef9ff32ab3915c91a8
BLAKE2b-256 d0476335c88181a63ab2fb783555ca4934c3e0130b15c9e01ca75c0004b6a2b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for acoustic_engine-1.2.0.tar.gz:

Publisher: release.yml on h0tp-ftw/acoustic-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file acoustic_engine-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: acoustic_engine-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 81.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for acoustic_engine-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3940e16c0ddf1e9fbc1e5875b362a41fe7f2a68ee1998c01df1bb48aa6ffec19
MD5 e06a66032b87086a8bc780cb3c70082f
BLAKE2b-256 fec69503eab62f61476afa6b9b444ec378e3cbeada1b498db547d70f183ec698

See more details on using hashes here.

Provenance

The following attestation bundles were made for acoustic_engine-1.2.0-py3-none-any.whl:

Publisher: release.yml on h0tp-ftw/acoustic-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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