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.
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, orgeneric(default: house)--meter: Time signature -4/4,3/4, or2/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, orgeneric(default: house)--meter: Time signature -4/4,3/4, or2/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 feel0.5-0.7- Natural human feel, noticeable ghost notes0.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
- mido - MIDI file handling
- numpy - Numerical computations
- requests - HTTP requests
- beautifulsoup4 - HTML parsing
Release Instructions
Automated Releases (Recommended)
The project includes GitHub Actions that automatically create releases when version tags are pushed.
To create a new release:
-
Update version in
pyproject.tomlandsrc/beatstoch/__init__.py(if exists) -
Update CHANGELOG.md with new features and fixes
-
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}"
-
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:
-
Build distributions:
uv build -
Upload to PyPI:
uv publish -
Verify installation:
pip install beatstoch beatstoch --help
PyPI Setup
- Get PyPI API token from PyPI Account Settings
- Add to GitHub Secrets: Go to repository Settings > Secrets and variables > Actions
- Add
PYPI_API_TOKENwith your PyPI API token value
Documentation
Documentation is automatically built and deployed to GitHub Pages using MkDocs.
- Live Documentation: https://james-see.github.io/beatstoch/
- Build locally:
mkdocs serve(requires MkDocs installation)
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.
Contributing
- Fork the repository at https://github.com/james-see/beatstoch
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Run the test suite:
uv run python -m pytest - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Support
Generated drum patterns are for educational and creative purposes. Always respect music copyrights and licensing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file beatstoch-1.5.1.tar.gz.
File metadata
- Download URL: beatstoch-1.5.1.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c8ad7aa551549b268c3dd2c088c3548f7bb94626748d4d195802064a9ae83f6
|
|
| MD5 |
52d0d72a432e7e73a108847d26d670c1
|
|
| BLAKE2b-256 |
65b918a9f5fe0a8d52005faee0a97b599776889c43d07968960dc03c55ef7b41
|
File details
Details for the file beatstoch-1.5.1-py3-none-any.whl.
File metadata
- Download URL: beatstoch-1.5.1-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5351ee673d258c25f6df31cbc2f440bfaaa1a66f18578a18aac3b71aafe065a7
|
|
| MD5 |
0e1f8ff8cba6572d94a8227fd34ffea1
|
|
| BLAKE2b-256 |
6c068196236e1547bb98e9c1fa2f9383a995dc4bcfb71b9763a80316e9b8b706
|