Real-time environmental audio monitoring and analysis system with decisecond resolution storage in TimescaleDB.
Soundscape analyzer is a Python-based system that captures audio from microphones, processes it to extract acoustic features (decibel levels and frequency bands), and stores the data in TimescaleDB for advanced time-series analysis. T
- 📊 High-resolution audio monitoring - Capture audio metrics at 0.1-second (decisecond) resolution
- 🔊 Complete frequency analysis - Extract and analyze 7 frequency bands (sub-bass to brilliance)
- 📈 Efficient time-series storage - Leverage TimescaleDB's hypertables and continuous aggregates
- 🔍 Real-time visualization - Monitor acoustic environments through Grafana dashboards
- 🏙️ Spatial noise mapping - Track and compare noise levels across different locations
- Python 3.8+
- PostgreSQL 12+ with TimescaleDB extension
- Grafana 9+ (for visualization)
pip install numpy sounddevice psycopg2-binary scipy
-
Install TimescaleDB following the official instructions
-
Create database and enable TimescaleDB extension:
CREATE DATABASE soundscape;
\c soundscape
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
- The first run of the script will automatically create the necessary tables.
Start the audio monitor with:
python audio_monitor.py \
--db-host localhost \
--db-port 5432 \
--db-name soundscape \
--db-user postgres \
--db-password yourpassword \
--location-id downtown-01
To run as a background service using systemd (Linux):
- Create a service file at
/etc/systemd/system/audio-monitor.service
:
[Unit]
Description=Soundscape Audio Monitor
After=network.target postgresql.service
[Service]
Type=simple
User=youruser
ExecStart=/usr/bin/python3 /path/to/audio_monitor.py \
--db-host localhost \
--db-port 5432 \
--db-name soundscape \
--db-user postgres \
--db-password yourpassword \
--location-id downtown-01
Restart=on-failure
RestartSec=10s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
- Enable and start the service:
sudo systemctl enable audio-monitor
sudo systemctl start audio-monitor
The main script that:
- Captures audio data from the microphone
- Processes it to extract acoustic features
- Stores data in TimescaleDB
# Key functions:
calculate_decibel(audio_chunk, reference=1.0) # Converts audio data to decibel scale
analyze_frequency(audio_data) # Extracts frequency bands from audio data
-- Sensor metadata table
CREATE TABLE sound_sensors (
sensor_id TEXT PRIMARY KEY,
location_id TEXT NOT NULL,
description TEXT,
installation_date TIMESTAMPTZ DEFAULT NOW()
);
-- Raw metrics table as a hypertable
CREATE TABLE sound_metrics (
time TIMESTAMPTZ NOT NULL,
sensor_id TEXT NOT NULL,
location_id TEXT NOT NULL,
decibel_level FLOAT NOT NULL,
frequency_bands JSONB NOT NULL,
FOREIGN KEY (sensor_id) REFERENCES sound_sensors(sensor_id)
);
-- Convert to TimescaleDB hypertable
SELECT create_hypertable('sound_metrics', 'time');
For efficient querying of historical data:
-- Create minute-level aggregates
CREATE MATERIALIZED VIEW sound_metrics_minute
WITH (timescaledb.continuous) AS
SELECT
time_bucket('1 minute', time) AS bucket,
sensor_id,
location_id,
AVG(decibel_level) AS avg_decibel,
MAX(decibel_level) AS max_decibel,
MIN(decibel_level) AS min_decibel,
jsonb_build_object(
'sub_bass', AVG((frequency_bands->>'sub_bass')::float),
'bass', AVG((frequency_bands->>'bass')::float),
'low_mid', AVG((frequency_bands->>'low_mid')::float),
'mid', AVG((frequency_bands->>'mid')::float),
'upper_mid', AVG((frequency_bands->>'upper_mid')::float),
'presence', AVG((frequency_bands->>'presence')::float),
'brilliance', AVG((frequency_bands->>'brilliance')::float)
) AS avg_frequency_bands
FROM sound_metrics
GROUP BY bucket, sensor_id, location_id;