aislice
Lock AI-generated music to a fixed BPM grid, then slice it by bar or beat.
AI music (Suno, Udio, …) rarely holds a steady tempo: it drifts across the song, so it never lines up with a DAW grid. aislice tracks every beat, builds a clean tempo map, and time-stretches the song in one variable-ratio pass, so every beat lands exactly on the target grid. Pitch is preserved. Then it cuts sample-accurate slices.
Status: v0.1.0, an early release. Feedback and issues are welcome.
Install
Requirements: Python 3.10+, ffmpeg, and the Rubber Band command-line tool.
# macOS
brew install ffmpeg rubberband
pip install aislice
# latest from GitHub
pip install git+https://github.com/VNL-Works/ai-music-slicer
# or, for development
git clone https://github.com/VNL-Works/ai-music-slicer && cd ai-music-slicer
pip install -e .
Use
aislice song.mp3 other.wav # asks for BPM and slice unit
aislice ./folder --bpm 206 --slice bar
Output (one folder per input):
aislice_output/song_206bpm/
├── song_206bpm.wav # whole song locked to the grid (24-bit, source sample rate)
├── slices/ # song_bar_001.wav, song_bar_002.wav, ...
├── stems/ # optional: vocals.wav, drums.wav, … (with --stems)
├── report.json # detected tempo map, corrections, verification
└── tempo.png # before/after plot
Slice units: 1/16, 1/8, beat, bar, 2bar, 4bar, 8bar, any Nbar / Nbeat (e.g. 16bar, 3beat), or none.
Better bar detection (optional, recommended)
pip install "aislice[beats]" # adds beat_this (MIT, CPJKU) + PyTorch
With the extra installed, aislice asks beat_this which beat is bar 1. Its own precise beat grid still does the timing. If beat_this is unsure, it falls back to the built-in harmony rule. On the test tracks, beat_this agreed with the correct bar start on all four (99–100% of its downbeats), including one the built-in rule got wrong. Use --downbeats harmony to skip it, or --downbeats beat_this to require it. pip install "aislice[all]" installs both extras.
Stems (optional)
Split the locked song into stems that share its exact grid, and slice every stem with the same cut points as the mix:
pip install "aislice[stems]" # adds PyTorch + audio-separator (large)
aislice song.mp3 --bpm 206 --slice 8bar --stems 3 # 2 = vocals/instrumental, 3 = drums/bass/melody, 4 = vocals/drums/bass/other, 6 = +guitar/piano
aislice stems "aislice_output/song_206bpm" --stems 4 # add stems to an existing result
aislice_output/song_206bpm/
├── stems/ vocals.wav drums.wav bass.wav other.wav
└── slices_8bar/ song_8bar_001.wav … (mix)
├── vocals/ song_vocals_8bar_001.wav …
├── drums/ …
Separation runs after the tempo is locked, so every stem lines up sample-exactly with the mix. aislice reslice moves the stems along with the mix. Presets use Demucs v4 (MIT licensed): htdemucs_ft by default, the fine-tuned and highest-quality Demucs, or htdemucs_6s for 6 stems. --stems-fast uses the single htdemucs model instead, about 4× faster with slightly lower quality. Because htdemucs_ft uses one specialist model per instrument, its stems add back up to slightly less than the mix (about −19 dB, roughly 1% of the energy). --stems-exact puts that leftover into the melody/other stem, so the stems recombine to the mix exactly. For other models, pass --stem-model with any audio-separator model, e.g. BS-Roformer-SW.ckpt (6 stems). Check each model's license before you use it. Models download once to ~/.cache/aislice/models. On a slow 2-core CPU, a 3-minute song takes about 19 minutes with the default model and 4 with --stems-fast. Apple Silicon and NVIDIA GPUs are much faster.
Fixing a wrong bar start
If slice 1 doesn't start on the "1", move the bar start without re-processing:
aislice reslice "aislice_output/song_206bpm" --shift 2 # bar 1 = 2 beats later
aislice reslice "aislice_output/song_206bpm" --slice 4bar,8bar
aislice prints a warning when it isn't sure where bar 1 is.
How it works
- Analyze: high-resolution onset envelope (~3 ms frames) and a local tempo curve, then a dynamic-programming beat tracker whose expected period follows the song's drift.
- Calibrate: beat markers are aligned to the actual note attacks, so slices start just before each transient.
- Clean the tempo map: fix missed and extra beats, ignore weak beats in fade-ins and fade-outs, and smooth out tracking jitter while keeping real drift. Then find the bar downbeat.
- Warp: one Rubber Band R3 pass with a time map (source beat → target grid line), with the first downbeat placed on a bar line.
- Slice at exact grid positions, then verify by re-tracking the output.
Development
pip install -e ".[dev]"
pytest
The tests build synthetic songs with a known, drifting tempo and chords that change on each bar. That gives exact ground truth for beat timing, downbeat detection, slicing and the full end-to-end run. The end-to-end test needs rubberband and ffmpeg installed and is skipped otherwise. CI runs everything on Python 3.10–3.13 and on macOS, plus a job that runs the real Demucs and beat_this models. See AGENTS.md for architecture and invariants, and CHANGELOG.md for releases.
License
MIT © VNL Works
aislice calls the Rubber Band command-line tool as a separate program. Rubber Band itself is GPL-2.0+ (commercial licenses are available from its authors) and is installed separately.
Metadata
Release files for aislice 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aislice-0.2.0.tar.gz | 33.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aislice-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.8 kB
Release files / aislice-0.2.0.tar.gz
| Download URL | aislice-0.2.0.tar.gz |
|---|---|
| Size | 33.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9dbf50981012434bf9efcdc87527e5f23fcc0356ae4b25ac5fad91c8dba137ba
|
|
BLAKE2b-256 checksum How to use checksums |
872d068c58b6da002b9d08efe3f8bf0fb30dbfb7398cf6bdd2c32f894a714f7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / aislice-0.2.0-py3-none-any.whl
| Download URL | aislice-0.2.0-py3-none-any.whl |
|---|---|
| Size | 32.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4cb10e25269b79f308077e49e00fb77adc342c26b0f104801f669b87d219be5a
|
|
BLAKE2b-256 checksum How to use checksums |
99d4337bc03dafd10af6c7268549aeb794408dc6367a61ff867623d21b2fa5ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log