Skip to content

rv-online/hacksmu

Repository files navigation

ElephantComm - Bioacoustic Research Toolkit

CI Python Tests Status License

Noise in, research evidence out.

A bioacoustic ML pipeline built for the HackSMU VII iMasons "AI & Machine Learning for Nature" challenge. ElephantComm takes noisy field recordings of elephant vocalizations, strips out mechanical interference, isolates individual calls, and classifies them into meaningful categories — giving wildlife researchers clean, structured data from messy real-world audio.


The Problem

Wildlife researchers deploy recording devices in the field to capture elephant vocalizations. But those recordings are full of noise — airplane engines, electrical hum, wind, and other mechanical interference. Manually sifting through hours of corrupted audio to find usable elephant calls is slow, tedious, and error-prone.

ElephantComm automates this entire workflow. Drop in a noisy recording, get back clean segments, classified calls, and exportable research data.


See It In Action

Waveform: Before & After Noise Removal

Waveform comparison showing clean, noisy, and denoised audio

Top: original elephant audio. Middle: same audio with mechanical noise mixed in. Bottom: recovered signal after spectral subtraction.

Spectrogram Analysis

The spectrograms below show frequency content over time (0-500 Hz range). Elephant rumbles appear as horizontal bands in the low-frequency region.

Clean Input Noisy Input Denoised Output
Clean Noisy Denoised
Original 23s African forest elephant recording Same recording with simulated mechanical interference Signal recovered by the preprocessing pipeline

Trumpeting Call (Short Demo)

Noisy Input Denoised Output
Noisy trumpeting Denoised trumpeting
5-second elephant trumpeting with noise overlay Clean signal extracted — 6 segments detected

Classification Results

From a single 23-second recording, the pipeline detected 73 audio segments and classified each one:

Classification distribution

Segments are classified into vocalization types based on acoustic features like fundamental frequency, spectral centroid, and duration.


Architecture

The pipeline processes elephant audio through six stages:

flowchart LR
    A["Raw Recording"] --> B["Ingestion"]
    B --> C["Preprocessing"]
    C --> D["Feature Extraction"]
    D --> E["Classification"]
    E --> F["Semantic Analysis"]
    F --> G["Research Queries"]

    style A fill:#e74c3c,color:#fff
    style G fill:#2ecc71,color:#fff
Loading

Stage 1: Ingestion

Accepts audio in multiple formats with rich metadata.

Feature Details
Formats WAV, FLAC, MP3, PCM
Metadata GPS coordinates, device type, capture timestamp
Storage In-memory byte store with UUID-based recording IDs
Annotations Researcher notes, environment descriptions
service = IngestionService()
recording_id = service.ingest(
    source=audio_bytes,
    metadata=RecordingMetadata(
        gps_latitude=2.3,
        gps_longitude=18.6,
        device_type="field_recorder",
    ),
    audio_format=AudioFormat.WAV,
    sample_rate=16000,
)

Stage 2: Preprocessing & Noise Removal

Uses spectral subtraction to remove mechanical noise while preserving the frequencies that matter most for elephant communication.

Technique Purpose
Spectral subtraction Estimates and removes the noise frequency profile from the signal
Infrasonic preservation Protects frequencies below 20 Hz — critical for elephant rumbles humans can't hear
Amplitude normalization Standardizes volume levels across recordings
Energy-based segmentation Splits continuous audio into individual candidate calls

How spectral subtraction works:

  1. Compute the Short-Time Fourier Transform (STFT) of both the noisy audio and the noise profile
  2. Subtract the noise magnitude spectrum from the signal magnitude spectrum
  3. Reconstruct the cleaned audio via inverse STFT
  4. Preserve phase information from the original signal

Stage 3: Feature Extraction

Computes a rich set of acoustic features from each detected segment. Built entirely on numpy/scipy with no heavy dependencies.

Feature What It Measures
MFCCs (13 coefficients) Timbral texture — the "color" of the sound
Formant tracks Resonant frequencies and bandwidths — vocal tract shape
Spectrogram Full time-frequency energy distribution
Fundamental frequency The base pitch of the vocalization
Spectral centroid The "center of mass" of the frequency spectrum
Spectral bandwidth How spread out the frequencies are
Zero-crossing rate How often the signal changes sign — correlates with noisiness
Energy contour How loudness changes over the duration of the call

Stage 4: Classification

Categorizes each detected segment into one of 10 elephant vocalization types:

Category Frequency Range Typical Duration Description
Contact Rumble ~18 Hz ~4.5s Long-distance "I'm here" calls between separated groups
Greeting Rumble ~24 Hz ~3.0s Close-range social greetings when elephants reunite
Distress Call ~120 Hz ~0.8s High-frequency alarm signals indicating danger
Warning Call ~95 Hz ~0.9s Threat alerts broadcast to the group
Name Call ~42 Hz ~1.8s Individual-specific vocalizations (elephants call each other by name)
Location Reference ~36 Hz ~2.2s Calls associated with specific places
Social Bonding ~28 Hz ~2.6s Affiliative interactions that reinforce group cohesion
Musth Rumble ~12 Hz ~6.0s Very low-frequency male reproductive calls
Maternal Call ~55 Hz ~1.6s Mother-calf communication
Unknown varies varies Vocalizations that don't match known patterns

Two classification modes:

Mode How It Works When To Use
Heuristic Compares features against hand-crafted prototypes using scaled Euclidean distance + softmax No training data available (default)
Trained Nearest-centroid classifier learned from labeled (FeatureVector, CallCategory) pairs When you have labeled examples

Stage 5: Semantic Analysis

Goes beyond individual call classification to detect higher-order communication patterns across sequences of calls:

  • Naming events — detects when elephants use individual-specific vocalizations to address or refer to another elephant
  • Third-person references — identifies calls about absent individuals (elephants discussing others who aren't present)
  • Place references — links vocalizations to geographic locations
  • Vowel-like patterns — finds formant structures resembling vowel sounds in the call acoustics

Builds a semantic graph connecting elephants, calls, locations, and events:

graph TD
    E1["Elephant A"] -->|CALLER| C1["Call #1 (Name Call)"]
    C1 -->|ADDRESSEE| E2["Elephant B"]
    C1 -->|LOCATED_AT| L1["Waterhole"]
    E2 -->|CALLER| C2["Call #2 (Contact Rumble)"]
    C2 -->|RESPONDS_TO| C1
    C2 -->|REFERENCES| E3["Elephant C"]

    style E1 fill:#3498db,color:#fff
    style E2 fill:#3498db,color:#fff
    style E3 fill:#3498db,color:#fff
    style C1 fill:#e67e22,color:#fff
    style C2 fill:#e67e22,color:#fff
    style L1 fill:#2ecc71,color:#fff
Loading

Stage 6: Research Query Layer

Provides researchers with tools to explore, filter, and export results:

Capability Description
Filter by category Find all distress calls, contact rumbles, etc.
Filter by confidence Only return high-confidence classifications
Filter by time range Focus on specific windows of the recording
Communication profiles Summarize an individual elephant's vocal activity
CSV/JSON export Export results for use in R, Python, Excel, etc.
Spectrogram annotation Overlay classification labels on visual spectrograms

Quick Start

Prerequisites

  • Python 3.10+
  • pip

Installation

# Clone the repository
git clone https://github.com/rv-online/hacksmu.git
cd hacksmu

# Install dependencies
pip install -r requirements.txt

# Optional: install matplotlib for spectrogram visualizations
pip install matplotlib

Run the Demo

# Step 1: Download real elephant audio samples
python scripts/fetch_demo_audio.py

# Step 2: Run the full pipeline
python scripts/run_hacksmu_demo.py

Demo Options

# Short 5-second demo (recommended for quick runs)
python scripts/run_hacksmu_demo.py \
  --input demo_assets/audio/elephant_trumpeting.wav \
  --output-dir demo_outputs/trumpeting_demo

# Full 23-second African forest elephant clip
python scripts/run_hacksmu_demo.py

# Sponsor challenge dataset
python scripts/run_sponsor_challenge_demo.py \
  --sound-file 061220-24_airplane_01.wav \
  --output-dir demo_outputs/sponsor_demo

What the Demo Produces

File Description
clean_input.wav Original elephant audio
noisy_input.wav Audio with synthetic mechanical noise (60 Hz hum, engine rumble, broadband noise)
denoised_output.wav Cleaned audio after spectral subtraction
summary.json Full classification results — segment boundaries, confidence scores, SNR
clean_spectrogram.png Spectrogram of original audio (requires matplotlib)
noisy_spectrogram.png Spectrogram showing noise contamination
denoised_spectrogram.png Spectrogram after pipeline processing

Sample Output

Here's a snippet from summary.json showing a detected segment:

{
  "segment_id": "2af463da-c273-44a6-becc-96246861892b",
  "start_time": 20.096,
  "end_time": 22.272,
  "duration": 2.176,
  "fundamental_frequency": 380.95,
  "predicted_category": "DISTRESS_CALL",
  "confidence": 0.992,
  "signal_to_noise_ratio": 15.61
}

Tech Stack

Component Technology
Language Python 3.10+
Audio I/O scipy.io.wavfile
Signal Processing numpy, scipy (STFT, spectral subtraction, resampling)
Feature Extraction numpy, scipy (MFCCs, formants, spectrograms)
Data Models Pydantic v2
Testing pytest + Hypothesis (property-based testing)
Visualization matplotlib (optional)
CI GitHub Actions

Project Structure

hacksmu/
  elephant_comm/
    ingestion/           # Audio intake and metadata storage
    preprocessing/       # Spectral subtraction, normalization, segmentation
    feature_extraction/  # MFCCs, formants, spectrograms, acoustic features
    classification/      # Heuristic and nearest-centroid classifiers
    semantic/            # Communication pattern analysis and graph building
    query/               # Research filtering, profiling, and export interface
    models/              # Pydantic schemas, enums, and shared type definitions
    stores/              # Byte-safe serialization and in-memory persistence
  scripts/               # Demo runners and data-fetching utilities
  tests/                 # Unit tests and property-based tests (Hypothesis)
  docs/                  # Runbooks, pitch materials, submission checklist
  demo_assets/           # Downloaded audio samples (gitignored)
  demo_outputs/          # Generated results and spectrograms (gitignored)

Testing

# Run the full test suite
python -m pytest -q

# Run with verbose output
python -m pytest -v

# Run a specific module
python -m pytest elephant_comm/classification/test_engine.py

226 passing tests including property-based tests via Hypothesis that verify serialization round-trips, classification invariants, and model schema validation.


Audio Sources

Demo audio clips are downloaded from the public EarthToolsMaker forest-elephant repository, which describes itself as a collaboration with the Elephant Listening Project and Cornell University. The samples include:

File Duration Description
AfricanForestElephants.wav ~23s Forest elephant vocalizations with natural background
elephant_trumpeting.wav ~5s Short trumpeting call — ideal for quick demos

For Judges

Document Description
Demo Runbook Step-by-step guide for running the live demo
Demo Results Pre-computed results snapshot with key metrics
Sponsor Data Notes How we handled the challenge dataset
Hacker Toolkit Filled-out hackathon template pack
Pitch Guide Presentation framing and talking points
Submission Checklist Final submission verification

Notes

  • Sponsor assets stay local-only under sponsor_assets/
  • Generated demo outputs stay local-only under demo_outputs/
  • AI tooling was used during development and is disclosed in the submission

Contributing

Contributions are welcome. See CONTRIBUTING.md.

About

HackSMU elephant-call denoising and bioacoustic ML toolkit for the iMasons AI & ML for Nature challenge

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages