Code-first beat making in Python — sample-driven, config-driven, no DAW required
Project description
beat-engine
Code-first beat making in Python. Bring your own samples (WAV files or SF2 soundfonts), describe a song in TOML or a Python dict, render to WAV / stems / MIDI. No DAW required.
Status
0.1.0 — alpha. The audio pipeline (numpy float32 + pedalboard direct, no pydub, no tempfile round-trips) is complete and tested. The lib already produces well-mixed beats from a config alone, but several "modern pro" features are explicitly deferred to 0.2. Expect breaking config changes between 0.x versions.
Working today
- Sample-driven rendering — WAV one-shots, multisample directories, SF2 soundfonts.
- 16 scales, 9 melody contour shapes, A-A' motif sequencer with cross-bar continuity.
- Drum patterns with energy-based switching, accents, ghost notes, fills, ratchets, stutters, drops.
- Voice-leading, chord inversions, chromatic bass approaches.
- Per-instrument Pedalboard FX (Reverb, Compressor, Chorus, Delay, Distortion, Bitcrush, Highpass, Lowpass, PeakFilter, Limiter), sends, sidechain ducking, saturation, tape wobble, auto-pan, stereo width.
- Section dynamics: fade-in / fade-out, crossfade, crescendo / decrescendo, key shift, tape stop, vinyl crackle.
- Master chain: bus compressor + brick-wall limiter, optional LUFS-target normalize.
- WAV / stems / MIDI export.
Deferred to 0.2
- Phase-vocoder pitch shift (sustained melodic notes currently shorten with the tape-trick shift).
- Automation envelopes — filter sweeps into the hook, opening reverb tails on the drop.
- Procedural generators:
noise_riser,sine_sub,impact— config-only, no samples needed. - Real 808 glide / portamento.
- Tempo curves and per-section BPM.
- Per-section per-instrument FX overrides.
A 30-second demo render lives in examples/demo_beat.py — python examples/demo_beat.py writes demo_beat.wav from synthetic samples.
Install
pip install beat-engine
# Optional extras:
pip install beat-engine[sf2] # SoundFont (.sf2) playback via FluidSynth
pip install beat-engine[loudness] # LUFS-target master normalization
Quick start
from beat_engine import quick_render
quick_render({
"song": {"bpm": 85, "title": "My Beat", "key": "C minor"},
"sections": [
{"name": "verse", "bars": 4, "energy": 0.5},
{"name": "hook", "bars": 4, "energy": 0.8},
],
"base": {
"chord_progression": [["C4", "D#4", "G4"], ["G#3", "C4", "D#4"]],
"instruments": {
"kick": {"sample": "samples/kick.wav", "pattern": "x---x---x---x---"},
"snare": {"sample": "samples/snare.wav", "pattern": "----x-------x---", "volume_db": -3},
"hat": {"sample": "samples/hihat.wav", "pattern": "x-x-x-x-x-x-x-x-", "volume_db": -10},
"bass": {"sample": "samples/bass_C2.wav", "source_note": "C2", "bass_profile": "anchor"},
},
},
}, output="my_beat.wav")
CLI
beat-engine render songs/my_song # full mix WAV
beat-engine stems songs/my_song # one WAV per instrument
beat-engine midi songs/my_song # Standard MIDI File
beat-engine validate songs/my_song # config lint
Sound sources
You bring your own samples — beat-engine ships no audio.
| Mode | Config keys | Notes |
|---|---|---|
| Single sample | sample + source_note |
One WAV pitch-shifted per note (tape-speed shift, changes duration) |
| Multisample dir | sample_dir |
Picks closest note from a directory of note_velocity_rr.wav files |
| SF2 soundfont | sf2 + sf2_preset + sf2_bank |
FluidSynth rendering, requires [sf2] extra |
Features
Sequencing: 16-step drum patterns, energy-based pattern switching, accent patterns (H/M/m/l), ghost notes, fills, ratchets, stutters, drops, swing, per-instrument groove templates (mpc/lazy/push/funk), velocity curves (linear/exponential/logarithmic/soft/hard), humanize, laid-back timing, hit probability.
Harmony: 16 scales (major, minor, modes, blues, pentatonics, exotic), voice-leading, chord inversions, chromatic bass approaches, key shifts per section, harmony layer (counter-melody from a source instrument).
Melody: auto-generation from scale + contour (arch/ascending/descending/wave/flat/valley/zigzag/random_walk/stairs) + density buckets, with chord-tone snapping on strong beats, A-A' motif sequencing, cross-bar continuity, manual step-list melodies.
Mixing: per-instrument FX (Pedalboard) — Reverb / Compressor / Chorus / Delay / Distortion / Bitcrush / Highpass / Lowpass / PeakFilter / Limiter — plus reverb/chorus/delay sends, tempo-synced delay, sidechain ducking, saturation (tanh), tape wobble, auto-pan LFO, stereo width (mid/side), per-instrument pan and gain.
Song-level: intro fade-in, outro fade-out, section crossfades, crescendo / decrescendo, key shifts, tape-stop outro, vinyl crackle.
Master chain: bus compressor + brick-wall Limiter. Optional LUFS-target normalization (target_lufs in config) when pyloudnorm is installed.
Export: 24-bit WAV (full mix), per-instrument stems, Standard MIDI File (Type 1).
Design
beat-engine is a pure-Python lib that delegates DSP to native code:
- Audio buffers:
numpy.ndarrayshape(num_samples, 2),float32, 44.1 kHz throughout. - Effects:
pedalboard(JUCE C++) called directly on the in-memory buffers. - I/O:
soundfile(libsndfile). - SF2:
pyfluidsynth(FluidSynth C library).
There is no pydub and no tempfile round-tripping for FX. The musical logic (sequencing, melody generation, MIDI export) is pure Python and stateless where it can be.
Project
- Contributing: see CONTRIBUTING.md — uses gitmoji commits and pre-commit hooks.
- Changelog: CHANGELOG.md — Keep a Changelog format.
- Code of conduct: CODE_OF_CONDUCT.md — Contributor Covenant 2.1.
- Security: SECURITY.md — private vulnerability reporting via GitHub Security Advisories.
License
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 beat_engine-0.1.2.tar.gz.
File metadata
- Download URL: beat_engine-0.1.2.tar.gz
- Upload date:
- Size: 49.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e974afa8278c21074d57a170a0d3e71d069fba377f408c767e65c9b8a7eda10c
|
|
| MD5 |
ef8e95bbe61794a33cebc673711f7924
|
|
| BLAKE2b-256 |
53279fa7c382382d9a39299325a1517f3bb6d8ed954007d7dab0d7b11b5684e9
|
Provenance
The following attestation bundles were made for beat_engine-0.1.2.tar.gz:
Publisher:
release.yml on hugocharels/beat-engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
beat_engine-0.1.2.tar.gz -
Subject digest:
e974afa8278c21074d57a170a0d3e71d069fba377f408c767e65c9b8a7eda10c - Sigstore transparency entry: 1476021420
- Sigstore integration time:
-
Permalink:
hugocharels/beat-engine@ceef1d1fe7d40a2fd35405a89e6b7d7aa86f173d -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/hugocharels
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ceef1d1fe7d40a2fd35405a89e6b7d7aa86f173d -
Trigger Event:
push
-
Statement type:
File details
Details for the file beat_engine-0.1.2-py3-none-any.whl.
File metadata
- Download URL: beat_engine-0.1.2-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3275dee31c940ef5a4fa82c25cc9ea4180eead3bd27112b858cb30ba9c5e638d
|
|
| MD5 |
ff4aac0a39702a0c191bc33e176c6591
|
|
| BLAKE2b-256 |
586a1db94386f3d43bb95a2c153b42ee8405128268b01466b269f2831ac1de0f
|
Provenance
The following attestation bundles were made for beat_engine-0.1.2-py3-none-any.whl:
Publisher:
release.yml on hugocharels/beat-engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
beat_engine-0.1.2-py3-none-any.whl -
Subject digest:
3275dee31c940ef5a4fa82c25cc9ea4180eead3bd27112b858cb30ba9c5e638d - Sigstore transparency entry: 1476021638
- Sigstore integration time:
-
Permalink:
hugocharels/beat-engine@ceef1d1fe7d40a2fd35405a89e6b7d7aa86f173d -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/hugocharels
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ceef1d1fe7d40a2fd35405a89e6b7d7aa86f173d -
Trigger Event:
push
-
Statement type: