Skip to main content

BPM-aware stochastic drum generator: library + CLI.

Project description

beatstoch

BPM-aware stochastic drum MIDI generator - Create dynamic, probabilistic drum patterns that adapt to any song's BPM.

Python 3.9+ CI uv GitHub stars

Features

  • BPM Database Integration: Automatically looks up song BPM from BPM Database
  • Psychoacoustic Algorithm: Research-based rhythms using golden ratio, Fibonacci sequences, and fractal complexity
  • Multiple Styles: House, breaks, and generic drum patterns with natural human feel
  • Time Signatures: Support for 4/4, 3/4, and 2/4 meters with natural accent patterns
  • Humanize Mode: Ghost notes and timing variation for authentic human feel
  • Stochastic Generation: Creates varied, probabilistic drum patterns with optimal predictability vs surprise balance
  • Golden Ratio Microtiming: Microtiming variations (20-30ms) for authentic groove perception
  • Natural Velocity Curves: Sine wave-based dynamics for expressive, human-like drum hits
  • Fractal Pattern Complexity: Multi-level fractal generation for organic rhythmic complexity
  • MIDI Export: Generates standard MIDI files compatible with any DAW
  • CLI & Library: Use as a command-line tool or Python library

Installation

Using pip

pip install beatstoch

Using pipx (recommended for CLI usage)

pipx install beatstoch

Using uv

uv tool install beatstoch

Development Installation

git clone https://github.com/james-see/beatstoch.git
cd beatstoch
uv sync

Quick Start

Command Line Interface

Generate drum patterns from song titles:

# Generate 8 bars of house-style drums for "1979" by Smashing Pumpkins
beatstoch generate "1979" --artist "Smashing Pumpkins" --bars 8

# Generate breaks-style pattern at 127 BPM
beatstoch generate-bpm 127 --bars 4 --style breaks

# Enable verbose logging to see BPM lookup process
beatstoch generate "Billie Jean" --artist "Michael Jackson" --verbose

Humanize Examples

Add ghost notes and timing variation for a more human feel:

# Subtle humanization (0.3) - light ghost notes
beatstoch generate-bpm 120 --humanize 0.3 --style house

# Medium humanization (0.6) - noticeable ghost notes and timing variation
beatstoch generate-bpm 128 --humanize 0.6 --style breaks

# Full humanization (1.0) - maximum ghost notes and timing drift
beatstoch generate "Take Five" --artist "Dave Brubeck" --humanize 1.0

Time Signature Examples

Generate patterns in different meters:

# 3/4 waltz time (strong-weak-weak accent pattern)
beatstoch generate-bpm 90 --meter 3/4 --style generic --bars 8

# 2/4 march feel (strong-weak accent pattern)
beatstoch generate-bpm 110 --meter 2/4 --humanize 0.5

# 4/4 with humanization (default meter)
beatstoch generate-bpm 128 --meter 4/4 --humanize 0.7 --style house

# Combine all features: 3/4 jazz waltz with full humanization
beatstoch generate "Take Five" --artist "Dave Brubeck" --meter 3/4 --humanize 0.8 --fallback-bpm 174

Python Library

from beatstoch import generate_from_song, generate_stochastic_pattern

# Generate from song lookup
mid, bpm = generate_from_song(
    "1979",
    artist="Smashing Pumpkins",
    bars=8,
    style="house",
    swing=0.1,
    intensity=0.9,
    groove_intensity=0.8
)
mid.save(f"stoch_1979_{int(bpm)}bpm.mid")
print(f"Generated pattern at {bpm} BPM")

# Generate with explicit BPM
mid2 = generate_stochastic_pattern(
    bpm=127,
    bars=4,
    style="breaks",
    seed=123,
    steps_per_beat=4,
    swing=0.12,
    groove_intensity=0.7
)
mid2.save("stoch_127_breaks.mid")

# Generate humanized 3/4 waltz pattern
mid3 = generate_stochastic_pattern(
    bpm=90,
    bars=8,
    meter=(3, 4),  # 3/4 time signature
    style="generic",
    humanize=0.7,  # Add ghost notes and timing variation
    groove_intensity=0.6
)
mid3.save("waltz_90bpm_humanized.mid")

# Generate humanized pattern from song lookup
mid4, bpm = generate_from_song(
    "Blue Monday",
    artist="New Order",
    bars=16,
    style="house",
    meter=(4, 4),
    humanize=0.5,  # Medium humanization
    groove_intensity=0.8
)
mid4.save(f"blue_monday_{int(bpm)}bpm_humanized.mid")

Command Line Options

generate command (song lookup)

  • title: Song title (required)
  • --artist: Artist name (optional, improves BPM lookup accuracy)
  • --bars: Number of bars to generate (default: 8)
  • --style: Drum style - house, breaks, or generic (default: house)
  • --meter: Time signature - 4/4, 3/4, or 2/4 (default: 4/4)
  • --humanize: Humanization amount 0.0-1.0 - adds ghost notes and timing variation (default: 0.0)
  • --steps-per-beat: Resolution (default: 4)
  • --swing: Swing amount 0.0-1.0 (default: 0.10)
  • --intensity: Pattern density 0.0-1.0 (default: 0.9)
  • --groove-intensity: Psychoacoustic groove strength 0.0-1.0 (default: 0.7)
  • --seed: Random seed for reproducible patterns
  • --fallback-bpm: BPM to use if lookup fails
  • --verbose: Show BPM lookup details

generate-bpm command (explicit BPM)

  • bpm: Target BPM (required)
  • --bars: Number of bars (default: 8)
  • --style: Drum style - house, breaks, or generic (default: house)
  • --meter: Time signature - 4/4, 3/4, or 2/4 (default: 4/4)
  • --humanize: Humanization amount 0.0-1.0 - adds ghost notes and timing variation (default: 0.0)
  • --steps-per-beat: Resolution (default: 4)
  • --swing: Swing amount (default: 0.10)
  • --intensity: Pattern density (default: 0.9)
  • --groove-intensity: Psychoacoustic groove strength 0.0-1.0 (default: 0.7)
  • --seed: Random seed

Drum Styles

House

Classic four-on-the-floor kick pattern enhanced with golden ratio timing and fractal hi-hat complexity. Features natural velocity curves and microtiming groove for authentic dance music feel.

Breaks

Syncopated breakbeat patterns using fractal complexity and Fibonacci probability distributions. Golden ratio microtiming creates the authentic "human feel" groove prized by breakbeat producers.

Generic

Balanced backbeat pattern with psychoacoustic optimization. Combines predictable structure (85% predictability) with controlled surprise elements for engaging, natural-sounding rhythms suitable for any genre.

Time Signatures (Meter)

The --meter option controls the time signature and affects accent patterns:

Meter Feel Accent Pattern
4/4 Standard Strong - weak - medium - weak
3/4 Waltz Strong - weak - weak
2/4 March Strong - weak

Each meter automatically adjusts velocity accents to create natural phrasing. Beat 1 is always strongest, with subsequent beats following the traditional accent patterns for each time signature.

Humanize Mode

The --humanize option (0.0-1.0) adds two key elements that make patterns sound less mechanical:

Ghost Notes

Subtle snare hits (velocity 25-50) placed on weak subdivisions:

  • "e" and "a" positions (in "1 e & a" counting) get higher probability
  • "&" positions get lower probability
  • Ghost notes vary bar-to-bar (70% chance each bar) to avoid repetition

Timing Variation

Random timing offsets (±15ms) applied to all notes, scaled by the humanize amount. This mimics the natural timing inconsistencies of human drummers.

Recommended values:

  • 0.0 - Machine-perfect timing (default)
  • 0.2-0.4 - Subtle humanization, tight feel
  • 0.5-0.7 - Natural human feel, noticeable ghost notes
  • 0.8-1.0 - Loose, expressive feel with prominent ghost notes

Output

Generated MIDI files are saved with descriptive names:

  • stoch_[artist]_[title]_[bpm]bpm_[meter].mid (from song lookup)
  • stoch_[artist]_[title]_[bpm]bpm_[meter]_humanized.mid (with humanize > 0)
  • stoch_[bpm]bpm_[meter].mid (from explicit BPM)
  • stoch_[bpm]bpm_[meter]_humanized.mid (with humanize > 0)

Example filenames:

stoch_new_order_blue_monday_130bpm_44.mid
stoch_dave_brubeck_take_five_174bpm_34_humanized.mid
stoch_120bpm_44_humanized.mid

Files are compatible with all major DAWs and MIDI software.

Requirements

  • Python 3.9+ (tested on 3.9-3.14)
  • Internet connection (for BPM database lookup)
  • MIDI-compatible software (for playback/editing)

Dependencies

Release Instructions

Automated Releases (Recommended)

The project includes GitHub Actions that automatically create releases when version tags are pushed.

To create a new release:

  1. Update version in pyproject.toml and src/beatstoch/__init__.py (if exists)

  2. Update CHANGELOG.md with new features and fixes

  3. Create and push a version tag:

    # Ensure you're on main branch and up to date
    git checkout main
    git pull origin main
    
    # Create annotated tag
    VERSION="1.0.0"
    git tag -a "v${VERSION}" -m "Release version ${VERSION}"
    
    # Push tag to trigger automated release
    git push origin "v${VERSION}"
    
  4. Automated workflow will:

    • Run tests
    • Build the package
    • Create a GitHub release with distribution files
    • Deploy documentation to GitHub Pages
    • Publish to PyPI (if PYPI_API_TOKEN is configured)

Manual PyPI Publishing

If automation isn't set up or fails:

  1. Build distributions:

    uv build
    
  2. Upload to PyPI:

    uv publish
    
  3. Verify installation:

    pip install beatstoch
    beatstoch --help
    

PyPI Setup

  1. Get PyPI API token from PyPI Account Settings
  2. Add to GitHub Secrets: Go to repository Settings > Secrets and variables > Actions
  3. Add PYPI_API_TOKEN with your PyPI API token value

Documentation

Documentation is automatically built and deployed to GitHub Pages using MkDocs.

Development

Setup

git clone https://github.com/james-see/beatstoch.git
cd beatstoch
uv sync

Testing

# Run all tests
uv run python -m pytest

# Test with coverage
uv run python -m pytest --cov=src/beatstoch

# Test CLI functionality
uv run beatstoch generate-bpm 120 --bars 2

Building Documentation

# Install MkDocs
pip install mkdocs mkdocs-material

# Preview locally
mkdocs serve

# Deploy to GitHub Pages
mkdocs gh-deploy

License

This project is released into the public domain under the Unlicense.

License: Unlicense

Contributing

  1. Fork the repository at https://github.com/james-see/beatstoch
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Run the test suite: uv run python -m pytest
  5. Commit your changes: git commit -m 'Add amazing feature'
  6. Push to the branch: git push origin feature/amazing-feature
  7. Open a Pull Request

Support


Generated drum patterns are for educational and creative purposes. Always respect music copyrights and licensing.

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

beatstoch-1.5.0.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

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

beatstoch-1.5.0-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file beatstoch-1.5.0.tar.gz.

File metadata

  • Download URL: beatstoch-1.5.0.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for beatstoch-1.5.0.tar.gz
Algorithm Hash digest
SHA256 14444db4b84bf3d914c7e1b0248185647a90096a238b1e1b9a69625ea482c879
MD5 555ebb1feb85bc7d4581b84b8eee4566
BLAKE2b-256 b268987bf9737230a400ed96c5ea9371e807de6b3e2bcf77e5c77473a940ccb6

See more details on using hashes here.

File details

Details for the file beatstoch-1.5.0-py3-none-any.whl.

File metadata

  • Download URL: beatstoch-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 18.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for beatstoch-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d9bd0aecc4ecd4dcec08f99ec3b9f8dd8c90b814f3c49a817b92f9198678dd6f
MD5 81de83241ac0963a2630aa3a0ad41f8b
BLAKE2b-256 5f76246a06630e54e5b51dba9ed0260e74cfc030516755c84bf94d8b581aaa0f

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