bpm-analyzer 0.1.0

A simple library for calculating the BPM
Documentation
# BPM Analyzer

A real-time BPM (beats per minute) detection library and application for Rust, using wavelet decomposition and autocorrelation analysis.

Based on [Audio Analysis using the Discrete Wavelet Transform](https://soundlab.cs.princeton.edu/publications/2001_amta_aadwt.pdf) by George Tzanetakis, Georg Essl and Perry Cook.

## How It Works

The BPM analyzer uses a sophisticated multi-stage signal processing pipeline:

1. **Audio Capture**: Captures audio from system input or loopback devices
2. **Resampling**: Downsamples to 22.05 kHz for efficient processing
3. **Wavelet Decomposition**: Applies 4-level Daubechies D4 wavelet transform to separate frequency bands
4. **Onset Detection**: Extracts amplitude envelopes from each band using full-wave rectification and low-pass filtering
5. **Autocorrelation**: Computes autocorrelation on the summed envelopes to find periodic patterns
6. **Peak Detection**: Identifies BPM candidates based on autocorrelation peaks within the specified range

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
bpm-analyzer = "0.1"
```

## Usage

### As a Library

```rust
use bpm_analyzer::{AnalyzerConfig, begin};

fn main() -> Result<(), bpm_analyzer::Error> {
    // Configure the analyzer
    let config = AnalyzerConfig::builder()
        .min_bpm(60.0)
        .max_bpm(180.0)
        .build();

    // Start the analyzer
    let bpm_receiver = begin(config)?;

    // Process BPM candidates
    for peaks in bpm_receiver.iter() {
        // peaks is an array of 5 (bpm, confidence) tuples
        // sorted by confidence (highest first)
        if let Some((bpm, confidence)) = peaks.first() {
            println!("Detected BPM: {:.1} (confidence: {:.4})", bpm, confidence);
        }
    }

    Ok(())
}
```

### As a Standalone Application

Run the GUI application:

```bash
cargo run --release --features bin
```

With custom BPM range:

```bash
cargo run --release --features bin -- --min-bpm 80 --max-bpm 160
```

### Command-Line Options

- `-m, --min-bpm <MIN_BPM>`: Minimum BPM to detect (default: 40)
- `-M, --max-bpm <MAX_BPM>`: Maximum BPM to detect (default: 240)

## Configuration

### AnalyzerConfig

The analyzer behavior can be customized using `AnalyzerConfig`:

```rust
let config = AnalyzerConfig::builder()
    .min_bpm(40.0)           // Minimum BPM to detect
    .max_bpm(240.0)          // Maximum BPM to detect
    .window_size(65536)      // Analysis window size (must be power of 2)
    .queue_size(4096)        // Audio queue size
    .buffer_size(256)        // Audio capture buffer size
    .build();
```

#### Parameters

- **min_bpm** / **max_bpm**: Define the range of tempos to detect. Narrowing this range can improve accuracy for specific genres.
- **window_size**: Size of the analysis window in samples. Larger windows provide better frequency resolution but slower response. 
- **queue_size**: Size of the inter-thread audio queue. I don't think you need to change this.
- **buffer_size**: Audio capture buffer size. Smaller values reduce latency but may increase CPU usage. I'm also not convinced that this needs to be changed.

## Audio Setup

### macOS

For system audio capture, install [BlackHole](https://github.com/ExistentialAudio/BlackHole):

```bash
brew install blackhole-2ch
```

Then configure your system to route audio through BlackHole using a multi-output device.

## Dependencies

This library builds on several excellent Rust crates:

- [fundsp]https://github.com/SamiPerttu/fundsp - Audio processing framework
- [osclet]https://crates.io/crates/osclet - Wavelet transform library
- [cpal]https://github.com/RustAudio/cpal - Cross-platform audio I/O
- [resampler]https://crates.io/crates/resampler - Audio resampling

## Limitations

- **Tempo Changes**: The analyzer works best with consistent tempo. Sudden tempo changes may take time to adapt.
- **Polyrhythmic Music**: Complex polyrhythmic patterns may produce multiple strong candidates.
- **Very Slow/Fast Tempos**: Accuracy may decrease outside the 40-240 BPM range.