danceflow-stemlab 1.2.0__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/MANIFEST.in +8 -0
- {danceflow_stemlab-1.2.0/src/danceflow_stemlab.egg-info → danceflow_stemlab-1.3.1}/PKG-INFO +193 -5
- danceflow_stemlab-1.2.0/PKG-INFO → danceflow_stemlab-1.3.1/README.md +152 -89
- danceflow_stemlab-1.3.1/docs/branding/README.md +11 -0
- danceflow_stemlab-1.3.1/docs/branding/logo-monochrome.svg +6 -0
- danceflow_stemlab-1.3.1/docs/branding/logo.png +0 -0
- danceflow_stemlab-1.3.1/docs/branding/logo.svg +6 -0
- danceflow_stemlab-1.3.1/docs/cue-alignment.md +201 -0
- danceflow_stemlab-1.3.1/docs/evidence-models.md +109 -0
- danceflow_stemlab-1.3.1/docs/midi.md +353 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/mcp-registry/server.json +4 -4
- danceflow_stemlab-1.3.1/plugins/stemlab/.codex-plugin/plugin.json +24 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/README.md +4 -0
- danceflow_stemlab-1.3.1/plugins/stemlab/branding/logo-monochrome.svg +6 -0
- danceflow_stemlab-1.3.1/plugins/stemlab/branding/logo.png +0 -0
- danceflow_stemlab-1.3.1/plugins/stemlab/branding/logo.svg +6 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/plugin.json +4 -4
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/skills/stemlab/SKILL.md +29 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/skills/stemlab/references/tools.md +3 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/pyproject.toml +30 -5
- danceflow_stemlab-1.3.1/scripts/benchmark_evidence_corpus.py +46 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/build_codex_plugin.py +2 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/prepare_codex_marketplace.py +2 -1
- danceflow_stemlab-1.3.1/scripts/smoke_midi.py +44 -0
- danceflow_stemlab-1.2.0/README.md → danceflow_stemlab-1.3.1/src/danceflow_stemlab.egg-info/PKG-INFO +277 -3
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/danceflow_stemlab.egg-info/SOURCES.txt +43 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/danceflow_stemlab.egg-info/requires.txt +51 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/__init__.py +1 -1
- danceflow_stemlab-1.3.1/src/stemlab/analysis/evidence/__init__.py +4 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/evidence/adapters.py +230 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/evidence/registry.py +146 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/evidence/runner.py +216 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/evidence/worker.py +35 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/__init__.py +8 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/adapters.py +254 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/artifacts.py +109 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/registry.py +119 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/runner.py +238 -0
- danceflow_stemlab-1.3.1/src/stemlab/analysis/midi/worker.py +39 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/registry.py +25 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/runner.py +63 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/beats/beatnet.py +16 -3
- danceflow_stemlab-1.3.1/src/stemlab/beats/beatthis.py +41 -0
- danceflow_stemlab-1.3.1/src/stemlab/bootstrap.py +249 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/branding.py +4 -3
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/canonical.py +5 -12
- danceflow_stemlab-1.3.1/src/stemlab/cli.py +452 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/bridge.py +55 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/jobs.py +1 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/server.py +40 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/tasks.py +125 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/worker.py +5 -1
- danceflow_stemlab-1.3.1/src/stemlab/cue_cli.py +86 -0
- danceflow_stemlab-1.3.1/src/stemlab/cues.py +645 -0
- danceflow_stemlab-1.3.1/src/stemlab/lyric_lrc.py +105 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/pipeline.py +79 -2
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/bsroformer.py +27 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/spectrogram.py +57 -27
- danceflow_stemlab-1.3.1/src/stemlab/spectrogram_repair.py +86 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/types.py +24 -0
- danceflow_stemlab-1.3.1/src/stemlab/word_alignment.py +114 -0
- danceflow_stemlab-1.3.1/tests/test_beat_this_bootstrap.py +62 -0
- danceflow_stemlab-1.3.1/tests/test_beatnet_bootstrap.py +66 -0
- danceflow_stemlab-1.3.1/tests/test_bsroformer_adapter.py +30 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_package.py +3 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_protocol.py +1 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_release.py +1 -1
- danceflow_stemlab-1.3.1/tests/test_cue_integration.py +200 -0
- danceflow_stemlab-1.3.1/tests/test_cues.py +370 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_distribution_identity.py +7 -1
- danceflow_stemlab-1.3.1/tests/test_docker_contract.py +78 -0
- danceflow_stemlab-1.3.1/tests/test_evidence_models.py +126 -0
- danceflow_stemlab-1.3.1/tests/test_lyric_lrc.py +75 -0
- danceflow_stemlab-1.3.1/tests/test_midi_adapters.py +245 -0
- danceflow_stemlab-1.3.1/tests/test_midi_extraction.py +207 -0
- danceflow_stemlab-1.3.1/tests/test_midi_integration.py +151 -0
- danceflow_stemlab-1.3.1/tests/test_midi_registry.py +52 -0
- danceflow_stemlab-1.3.1/tests/test_spectrogram.py +55 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_web_frontend.py +5 -4
- danceflow_stemlab-1.3.1/tests/test_word_alignment.py +27 -0
- danceflow_stemlab-1.2.0/plugins/stemlab/.codex-plugin/plugin.json +0 -24
- danceflow_stemlab-1.2.0/src/stemlab/beats/beatthis.py +0 -25
- danceflow_stemlab-1.2.0/src/stemlab/bootstrap.py +0 -133
- danceflow_stemlab-1.2.0/src/stemlab/cli.py +0 -230
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/.agents/plugins/marketplace.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/.github/workflows/codex-plugin.yml +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/.github/workflows/release.yml +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/LICENSE +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/docs/codex-plugin.md +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/docs/codex-publishing.md +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/.mcp.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/plugins/stemlab/mcp.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/capture_loop_workflow.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/check_codex_timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/loop_demo.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/scripts/publish_mcp_registry.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/setup.cfg +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/danceflow_stemlab.egg-info/dependency_links.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/danceflow_stemlab.egg-info/entry_points.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/danceflow_stemlab.egg-info/top_level.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/__main__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/harmony.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/loops.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/lyrics.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/rhythm.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/semantic_audio.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/semantic_text.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/song_map.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/sonic.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/structure.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/tempo_regimes.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/analysis/transcription.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/audio.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/beats/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/beats/base.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/beats/beattransformer.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/beats/common.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/__main__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/paths.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/codex/timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/manifest.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/models.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/base.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/common.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/demucs.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/openunmix.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/separators/scnet.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/server.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/speech.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/util.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/vamp.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/vamp_runtime.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/app.js +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/arcadians-cover.jpg +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/arcadians-reference.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/index.html +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/style.css +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/web/timeline.css +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/src/stemlab/webui.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_analysis_registry.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_arcadians_fixture.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_audio_normalization.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_beat_consensus.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_beatnet_compat.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_branding.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_canonical.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_canonical_extended.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_bridge.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_jobs.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_codex_timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_deep_harmony.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_deep_lyrics.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_deep_sonic_rhythm.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_loop_integration.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_loops.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_manifest.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_models.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_repository_hygiene.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_server.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_song_map.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_sonic_visualiser_workspace.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_speech_repetition.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_vamp.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.1}/tests/test_vamp_runtime.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
include .agents/plugins/marketplace.json
|
|
2
2
|
recursive-include plugins/stemlab *.json *.md
|
|
3
|
+
recursive-include plugins/stemlab/branding *.svg *.png
|
|
3
4
|
include plugins/stemlab/.mcp.json
|
|
4
5
|
include plugins/stemlab/.codex-plugin/plugin.json
|
|
5
6
|
include scripts/build_codex_plugin.py
|
|
@@ -13,3 +14,10 @@ include .github/workflows/release.yml
|
|
|
13
14
|
include scripts/check_codex_timeline.py
|
|
14
15
|
include scripts/loop_demo.py
|
|
15
16
|
include scripts/capture_loop_workflow.py
|
|
17
|
+
include docs/midi.md
|
|
18
|
+
include scripts/smoke_midi.py
|
|
19
|
+
include docs/cue-alignment.md
|
|
20
|
+
include docs/evidence-models.md
|
|
21
|
+
include scripts/benchmark_evidence_corpus.py
|
|
22
|
+
|
|
23
|
+
recursive-include docs/branding *.svg *.png *.md
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: danceflow-stemlab
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.3.1
|
|
4
|
+
Summary: Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
|
|
5
5
|
Author: Kieran Simkin
|
|
6
6
|
Maintainer: Kieran Simkin
|
|
7
7
|
License-Expression: MIT
|
|
8
|
+
Project-URL: DanceFlow ecosystem, https://kieransimkin.co.uk/danceflow/
|
|
8
9
|
Project-URL: Homepage, https://kieransimkin.co.uk/
|
|
9
10
|
Project-URL: My Songs portfolio, https://kieransimkin.co.uk/my-songs/
|
|
10
11
|
Project-URL: Arcadians showcase, https://kieransimkin.co.uk/arcadians/
|
|
@@ -49,6 +50,8 @@ Provides-Extra: speech
|
|
|
49
50
|
Requires-Dist: faster-whisper; extra == "speech"
|
|
50
51
|
Provides-Extra: beats
|
|
51
52
|
Requires-Dist: beat-this>=1.1.0; extra == "beats"
|
|
53
|
+
Requires-Dist: madmom-prebuilt==0.17.post1; python_version >= "3.11" and extra == "beats"
|
|
54
|
+
Requires-Dist: mido>=1.2.6; extra == "beats"
|
|
52
55
|
Provides-Extra: deep
|
|
53
56
|
Requires-Dist: sentence-transformers<7,>=6.1; extra == "deep"
|
|
54
57
|
Requires-Dist: all-in-one-infer>=3.1; extra == "deep"
|
|
@@ -56,6 +59,40 @@ Provides-Extra: semantic-nc
|
|
|
56
59
|
Requires-Dist: muq; extra == "semantic-nc"
|
|
57
60
|
Provides-Extra: amt
|
|
58
61
|
Requires-Dist: basic-pitch<0.5,>=0.4; python_version < "3.12" and extra == "amt"
|
|
62
|
+
Provides-Extra: midi
|
|
63
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi"
|
|
64
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi"
|
|
65
|
+
Requires-Dist: psutil>=5.9; extra == "midi"
|
|
66
|
+
Provides-Extra: midi-piano
|
|
67
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-piano"
|
|
68
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-piano"
|
|
69
|
+
Requires-Dist: psutil>=5.9; extra == "midi-piano"
|
|
70
|
+
Requires-Dist: piano-transcription-inference==0.0.6; extra == "midi-piano"
|
|
71
|
+
Provides-Extra: midi-transkun
|
|
72
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-transkun"
|
|
73
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-transkun"
|
|
74
|
+
Requires-Dist: psutil>=5.9; extra == "midi-transkun"
|
|
75
|
+
Requires-Dist: transkun==2.0.1; extra == "midi-transkun"
|
|
76
|
+
Requires-Dist: setuptools<81; extra == "midi-transkun"
|
|
77
|
+
Provides-Extra: midi-mt3
|
|
78
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-mt3"
|
|
79
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-mt3"
|
|
80
|
+
Requires-Dist: psutil>=5.9; extra == "midi-mt3"
|
|
81
|
+
Requires-Dist: mt3-infer[torch]==0.2.0; extra == "midi-mt3"
|
|
82
|
+
Provides-Extra: evidence
|
|
83
|
+
Requires-Dist: psutil>=5.9; extra == "evidence"
|
|
84
|
+
Provides-Extra: evidence-vocals
|
|
85
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-vocals"
|
|
86
|
+
Requires-Dist: fireredvad<0.1,>=0.0.2; extra == "evidence-vocals"
|
|
87
|
+
Provides-Extra: evidence-pitch
|
|
88
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-pitch"
|
|
89
|
+
Requires-Dist: swift-f0[audio]<0.4,>=0.3; extra == "evidence-pitch"
|
|
90
|
+
Provides-Extra: evidence-align
|
|
91
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-align"
|
|
92
|
+
Requires-Dist: qwen-asr; extra == "evidence-align"
|
|
93
|
+
Provides-Extra: evidence-chords
|
|
94
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-chords"
|
|
95
|
+
Requires-Dist: lv-chordia; extra == "evidence-chords"
|
|
59
96
|
Provides-Extra: server
|
|
60
97
|
Requires-Dist: fastapi<1,>=0.115; extra == "server"
|
|
61
98
|
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "server"
|
|
@@ -77,6 +114,8 @@ Requires-Dist: openunmix>=1.3.0; extra == "all"
|
|
|
77
114
|
Requires-Dist: bs-roformer-infer>=0.1.5; extra == "all"
|
|
78
115
|
Requires-Dist: faster-whisper; extra == "all"
|
|
79
116
|
Requires-Dist: beat-this>=1.1.0; extra == "all"
|
|
117
|
+
Requires-Dist: madmom-prebuilt==0.17.post1; python_version >= "3.11" and extra == "all"
|
|
118
|
+
Requires-Dist: mido>=1.2.6; extra == "all"
|
|
80
119
|
Requires-Dist: sentence-transformers<7,>=6.1; extra == "all"
|
|
81
120
|
Requires-Dist: all-in-one-infer>=3.1; extra == "all"
|
|
82
121
|
Requires-Dist: fastapi<1,>=0.115; extra == "all"
|
|
@@ -86,13 +125,24 @@ Dynamic: license-file
|
|
|
86
125
|
|
|
87
126
|
# StemLab
|
|
88
127
|
|
|
128
|
+
[](https://kieransimkin.co.uk/danceflow/)
|
|
129
|
+
|
|
130
|
+
By **[Kieran Simkin](https://kieransimkin.co.uk/)** · [DanceFlow ecosystem](https://kieransimkin.co.uk/danceflow/) · [Vector logo and usage guide](docs/branding/README.md).
|
|
131
|
+
|
|
132
|
+
Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
|
|
133
|
+
|
|
134
|
+
|
|
89
135
|
<!-- mcp-name: io.github.kieransimkin/stemlab -->
|
|
90
136
|
|
|
91
137
|
> **StemLab by [Kieran Simkin](https://kieransimkin.co.uk/)** · [My Songs portfolio](https://kieransimkin.co.uk/my-songs/) · [Arcadians EPK](https://kieransimkin.co.uk/arcadians/) · [Source](https://github.com/kieransimkin/stemlab)
|
|
92
138
|
|
|
93
139
|
> **Packaging identity:** the canonical project name is **StemLab**. StemLab is part of the **Dance Flow** project. The PyPI distribution is named `danceflow-stemlab` solely because Python package-registry names are globally unique. The Python import, CLI, GitHub repository and container image remain `stemlab`.
|
|
94
140
|
|
|
95
|
-
|
|
141
|
+
## Synopsis
|
|
142
|
+
|
|
143
|
+
**StemLab is a local, evidence-led music analysis toolkit that turns a master recording into inspectable stems, timing, structure, harmony, lyric and sonic evidence, then finds complete-bar loopable sections for Shorts and other short-form videos.**
|
|
144
|
+
|
|
145
|
+
It combines independent separation and music-information-retrieval routes rather than treating any single model as the answer. Results remain traceable through source hashes, manifests, JSON/TSV/NPZ artefacts, portable Sonic Visualiser sessions and a shared React timeline for playback and comparison. StemLab can run as a CLI, Python library, web service, container or local Codex MCP plugin. It is the music-understanding layer of Kieran Simkin's **DanceFlow** workflow and can supply downstream motion systems such as the WordPress **DanceMoves** plugin, while remaining useful on its own.
|
|
96
146
|
|
|
97
147
|
> **Model weights are not redistributed by this project.** They are fetched from their upstream registries/releases on first use. This avoids silently republishing checkpoints whose licensing may differ from the source code license, and lets upstream integrity metadata be used where available.
|
|
98
148
|
|
|
@@ -134,13 +184,19 @@ Relevant upstreams:
|
|
|
134
184
|
|
|
135
185
|
For every successful separator, **every WAV it emits** is retained. Stem names are discovered from files rather than truncated to a hard-coded four-stem schema, which is important for MVSep Mega 53. For the master and every stem, StemLab writes both a PNG spectrogram and compressed `.npz` spectrogram data (time axis, frequency axis, dB matrix, FFT metadata).
|
|
136
186
|
|
|
187
|
+
Full-resolution spectrogram evidence stays in the `.npz`; the PNG renderer is bounded to 8,192 time frames so long tracks cannot expand into multi-gigabyte Matplotlib RGBA buffers. If an older run retained the NPZ but failed while drawing the PNG, repair it in place without rerunning models:
|
|
188
|
+
|
|
189
|
+
```powershell
|
|
190
|
+
stemlab repair-spectrograms "path\to\analysis-results"
|
|
191
|
+
```
|
|
192
|
+
|
|
137
193
|
The preferred vocal stem is passed through the Silero VAD implementation bundled with `faster-whisper`. Speech regions are used to create a timeline-preserving `spoken_word.wav` (non-speech is zeroed rather than concatenated), then Whisper is run with word timestamps. Outputs include `whisper.json`, `speech_regions.json`, `transcript.txt`, `transcript.srt`, and `words.tsv`.
|
|
138
194
|
|
|
139
195
|
Whisper runs in repetition-safe mode by default (`condition_on_previous_text=False`) to prevent a repeated syllable in one window contaminating later windows. `whisper.json` records that setting and includes repeated-token diagnostics. Use `--whisper-condition-on-previous-text` only for an explicit comparison run; a flagged transcript remains evidence requiring section-wise recovery or listening QA, not a trustworthy lyric source.
|
|
140
196
|
|
|
141
197
|
Beat analysis runs:
|
|
142
198
|
|
|
143
|
-
- **BeatNet** in offline/DBN mode
|
|
199
|
+
- **BeatNet** in offline/DBN mode through StemLab's checksum-verified runtime bootstrap. StemLab uses the maintained `madmom-prebuilt` wheel and bypasses only BeatNet 1.1.3's obsolete NumPy/Numba package metadata.
|
|
144
200
|
- **Beat This!** using the `final0` checkpoint and its minimal postprocessor.
|
|
145
201
|
- **Beat Transformer**, using the original released model code/checkpoints. The model was trained on five demixed mel streams, so StemLab maps BS-RoFormer-SW to vocals, drums, bass, piano, and `other + guitar`, makes 128-bin mel-power spectrograms at the original 44.1 kHz / 4096 FFT / 1024-hop settings, and averages all eight released fold checkpoints by default. It uses the original madmom DBN decoder if madmom is importable, otherwise a documented SciPy peak-picking fallback.
|
|
146
202
|
|
|
@@ -305,9 +361,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
305
361
|
|
|
306
362
|

|
|
307
363
|
|
|
364
|
+
## Audio-to-MIDI model comparison
|
|
365
|
+
|
|
366
|
+
MIDI extraction is an **optional, independent model pass**. It adds Transkun V2
|
|
367
|
+
and high-resolution note/pedal piano transcription, plus MR-MT3 and YourMT3
|
|
368
|
+
multi-instrument transcription, alongside Spotify Basic Pitch. Automatic source
|
|
369
|
+
selection uses piano/keyboard stems for the piano specialists, pitched stems for
|
|
370
|
+
Basic Pitch and the mix for MT3-family models. Missing stems are reported, never
|
|
371
|
+
silently substituted. The legacy `--basic-pitch` command remains supported.
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# Install the chosen runtime; the standard profiles do not install MIDI models.
|
|
375
|
+
python -m pip install -e ".[midi-transkun]"
|
|
376
|
+
stemlab midi-models
|
|
377
|
+
|
|
378
|
+
# Use an existing separated piano, without rerunning any earlier analysis.
|
|
379
|
+
stemlab midi analysis-master --model transkun
|
|
380
|
+
|
|
381
|
+
# Or transcribe a directly supplied piano recording to a new folder.
|
|
382
|
+
stemlab midi piano.wav -o midi-piano --model transkun
|
|
383
|
+
|
|
384
|
+
# Full mix comparison requires the separately installed midi-mt3 extra.
|
|
385
|
+
# Both requested checkpoints need explicit first-use download consent.
|
|
386
|
+
stemlab midi mix.wav -o midi-comparison --model mr_mt3 --model yourmt3 --allow-model-downloads
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Each model/source gets its original `.mid`, tempo-aware `notes.json` and
|
|
390
|
+
`notes.csv`, an optional real note `piano-roll.png`, source/checkpoint hashes,
|
|
391
|
+
package versions and a worker log. Native MIDI controllers, pitch bends, tempo
|
|
392
|
+
changes and drums are preserved. Note sample numbers are original-rate
|
|
393
|
+
**estimates**, not a claim that the transcription is sample-accurate ground truth.
|
|
394
|
+
The MIDI clock is not used to overwrite StemLab's measured beat grid.
|
|
395
|
+
|
|
396
|
+
New analyses can opt in with repeated `--midi-model` switches and
|
|
397
|
+
`--midi-allow-downloads`. Existing Codex installations gain a workspace-scoped
|
|
398
|
+
`stemlab_start_midi_scan` job tool after updating the Python installation and
|
|
399
|
+
restarting the session. Models remain optional and no Python dependencies are
|
|
400
|
+
automatically installed. Incompatible research runtimes can use separate
|
|
401
|
+
`--backend-python MODEL=PATH` interpreters.
|
|
402
|
+
|
|
403
|
+
See [the MIDI guide](docs/midi.md) for all models, installation choices, checkpoint
|
|
404
|
+
and licensing caveats, saved-stem targeting, Codex usage, exact output semantics,
|
|
405
|
+
real-inference smoke commands and test limitations. The React timeline remains
|
|
406
|
+
the analysis inspector; this patch adds no MIDI synthesizer or new interactive
|
|
407
|
+
piano-roll lane. Static note plots are not frontend screenshots.
|
|
408
|
+
|
|
409
|
+
## Align timed musical cues to detected beats
|
|
410
|
+
|
|
411
|
+
Use saved analysis to snap an LRC cue file without rerunning models or editing audio:
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review
|
|
415
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review-100ms --tolerance-ms 100
|
|
416
|
+
stemlab generate-cues analysis-master -o generated-cues --title "Song title"
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Only timestamps change: bracketed labels such as `[DROP: CHORUS 1]`, metadata,
|
|
420
|
+
encoding and line layout are preserved. A cue with **no detected beat within
|
|
421
|
+
±150 ms** is highlighted as **REVIEW**, with its nearest-beat gap, and kept unchanged
|
|
422
|
+
by default. `--force-snap` moves distant cues too but retains their warnings.
|
|
423
|
+
`--downbeats` restricts targets to reported bar starts; `--beat-model` selects a
|
|
424
|
+
specific detector. No constant-tempo beats are invented to fill detection gaps.
|
|
425
|
+
|
|
426
|
+
Each new output folder contains the rewritten `.beat-snapped.lrc`, `report.json`,
|
|
427
|
+
a colour-coded `review.html`, and `review.txt`. Exact mode preserves the stored
|
|
428
|
+
beat timestamp; explicit millisecond/centisecond compatibility modes report
|
|
429
|
+
rounding. Source-rate sample-frame estimates are included when the rate is known.
|
|
430
|
+
Use `--fail-on-review` to write results and exit 2 when review is needed.
|
|
431
|
+
Generated section-cue files use a title-specific, WordPress-safe filename so
|
|
432
|
+
multiple releases can be uploaded and mapped without ambiguous duplicate names.
|
|
433
|
+
For the retained 3 October 2026 future-release batch,
|
|
434
|
+
`scripts/run-upcoming-full-cues.ps1` resumes full analyses without overwriting an
|
|
435
|
+
incomplete directory, and `scripts/summarize-upcoming-cues.ps1` reads each closed
|
|
436
|
+
manifest/report to produce one reproducible hash, cue-action and error-count row
|
|
437
|
+
per release. The summary script refuses missing or ambiguous generated LRCs.
|
|
438
|
+
|
|
439
|
+
For a new analysis, add `--snap-cues "musical cues.lrc"` and optionally
|
|
440
|
+
`--cue-tolerance-ms 100`. Cue alignment uses that run's detected events and appears
|
|
441
|
+
in `analysis.json`. See [the cue alignment guide](docs/cue-alignment.md) for exact
|
|
442
|
+
precision, offsets, all switches, safety rules and interpretation of warnings.
|
|
443
|
+
|
|
444
|
+
## Complementary evidence models
|
|
445
|
+
|
|
446
|
+
StemLab now has an optional **evidence-model layer** for models that add a different
|
|
447
|
+
kind of musical evidence instead of duplicating the normal separation or MIDI
|
|
448
|
+
backends. Nothing in this layer is enabled by a normal profile.
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
stemlab evidence-models
|
|
452
|
+
|
|
453
|
+
# Singing/speech/music activity + continuous pitch on saved vocals.
|
|
454
|
+
stemlab evidence analysis-master -o evidence-vocals \
|
|
455
|
+
--model firered_aed --model swift_f0 \
|
|
456
|
+
--model-path firered_aed=/models/FireRedVAD/AED
|
|
457
|
+
|
|
458
|
+
# Align approved lyrics without replacing them.
|
|
459
|
+
stemlab evidence analysis-master -o evidence-align \
|
|
460
|
+
--model qwen_forced_aligner --canonical-text lyrics.txt --allow-model-downloads
|
|
461
|
+
|
|
462
|
+
# Independent harmony evidence.
|
|
463
|
+
stemlab evidence analysis-master -o evidence-chords --model lv_chordia
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
The built-in registry covers **FireRed AED**, **HeartTranscriptor**, **Qwen3
|
|
467
|
+
ForcedAligner**, **SwiftF0**, **SongFormer**, **lv-chordia** and **ADTOF PyTorch**.
|
|
468
|
+
It also exposes explicit external-runtime bridges for **GAME**, **SheetSage2**,
|
|
469
|
+
**MOSS-Music** and **AudioSep** so large or restricted research dependencies never
|
|
470
|
+
get silently bundled into StemLab. Outputs stay independent: singing activity,
|
|
471
|
+
forced alignment, pitch, structure, chords and drum hits are review evidence, not
|
|
472
|
+
a hidden combined ground-truth score.
|
|
473
|
+
|
|
474
|
+
Saved analyses automatically route vocal models to a preferred full vocal stem,
|
|
475
|
+
drum transcription to a drum stem, continuous pitch to pitched stems, and
|
|
476
|
+
structure/harmony models to the master. Missing specialist stems are reported.
|
|
477
|
+
Use `--backend-python MODEL=/path/to/python` for conflicting research environments.
|
|
478
|
+
|
|
479
|
+
See [the evidence-model guide](docs/evidence-models.md) for model terms, routing,
|
|
480
|
+
external bridges and interpretation rules. `scripts/benchmark_evidence_corpus.py`
|
|
481
|
+
probes an authorised evaluation collection without copying audio into the repo.
|
|
482
|
+
|
|
308
483
|
## Install
|
|
309
484
|
|
|
310
|
-
Python 3.
|
|
485
|
+
Python 3.11 is recommended for the broad optional-model ecosystem. The `beats` and `all` extras install Beat This! plus the compatible `madmom-prebuilt` decoder. BeatNet 1.1.3 itself still publishes obsolete NumPy/Numba dependency pins, so StemLab downloads its official pure-Python wheel separately, verifies the published SHA-256, and exposes only the BeatNet code and bundled model weights from its cache. This route is supported on Python 3.11-3.13; a missing BeatNet result must not be mistaken for a successful detector run.
|
|
311
486
|
|
|
312
487
|
From PyPI, install the released StemLab distribution with:
|
|
313
488
|
|
|
@@ -330,6 +505,18 @@ SCNet and Beat Transformer are research repositories rather than stable pip infe
|
|
|
330
505
|
stemlab bootstrap all
|
|
331
506
|
```
|
|
332
507
|
|
|
508
|
+
For BeatNet alone:
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
pip install "danceflow-stemlab[beats]"
|
|
512
|
+
stemlab bootstrap beatnet
|
|
513
|
+
stemlab doctor
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
`stemlab doctor` reports BeatNet as ready only when the normal package or the
|
|
517
|
+
verified StemLab cache can actually be found. `analyze --no-bootstrap` never
|
|
518
|
+
downloads BeatNet and records the unavailable backend instead.
|
|
519
|
+
|
|
333
520
|
For only the Vamp analysis stack:
|
|
334
521
|
|
|
335
522
|
```bash
|
|
@@ -439,6 +626,7 @@ endpoints, events and the Arcadians reference workflow.
|
|
|
439
626
|
- [Web service](docs/web.md)
|
|
440
627
|
- [Containers](docs/containers.md)
|
|
441
628
|
- [Publishing and releases](docs/publishing.md)
|
|
629
|
+
- [BeatNet compatibility](docs/beatnet.md)
|
|
442
630
|
- [Changelog](CHANGELOG.md)
|
|
443
631
|
|
|
444
632
|
## Codex plugin and MCP server
|
|
@@ -1,98 +1,23 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: danceflow-stemlab
|
|
3
|
-
Version: 1.2.0
|
|
4
|
-
Summary: StemLab audio timing analysis and loopable sections for creating Shorts videos; DanceFlow and WordPress DanceMoves
|
|
5
|
-
Author: Kieran Simkin
|
|
6
|
-
Maintainer: Kieran Simkin
|
|
7
|
-
License-Expression: MIT
|
|
8
|
-
Project-URL: Homepage, https://kieransimkin.co.uk/
|
|
9
|
-
Project-URL: My Songs portfolio, https://kieransimkin.co.uk/my-songs/
|
|
10
|
-
Project-URL: Arcadians showcase, https://kieransimkin.co.uk/arcadians/
|
|
11
|
-
Project-URL: Repository, https://github.com/kieransimkin/stemlab
|
|
12
|
-
Project-URL: Issues, https://github.com/kieransimkin/stemlab/issues
|
|
13
|
-
Project-URL: Documentation, https://github.com/kieransimkin/stemlab/tree/main/docs
|
|
14
|
-
Project-URL: Changelog, https://github.com/kieransimkin/stemlab/blob/main/CHANGELOG.md
|
|
15
|
-
Project-URL: About Kieran, https://kieransimkin.co.uk/about-me/
|
|
16
|
-
Project-URL: Contact, https://kieransimkin.co.uk/contact/
|
|
17
|
-
Keywords: music,audio,MIR,source separation,BPM,rhythm,harmony,DanceFlow,DanceMoves,motion response,WordPress
|
|
18
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
19
|
-
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
-
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
25
|
-
Requires-Python: >=3.10
|
|
26
|
-
Description-Content-Type: text/markdown
|
|
27
|
-
License-File: LICENSE
|
|
28
|
-
Requires-Dist: numpy
|
|
29
|
-
Requires-Dist: scipy
|
|
30
|
-
Requires-Dist: torch>=2.4
|
|
31
|
-
Requires-Dist: torchaudio>=2.4
|
|
32
|
-
Requires-Dist: soundfile>=0.12
|
|
33
|
-
Requires-Dist: matplotlib
|
|
34
|
-
Requires-Dist: typer>=0.12
|
|
35
|
-
Requires-Dist: rich>=13.7
|
|
36
|
-
Requires-Dist: platformdirs>=4.2
|
|
37
|
-
Requires-Dist: librosa>=0.11
|
|
38
|
-
Requires-Dist: pyloudnorm>=0.2
|
|
39
|
-
Requires-Dist: cmudict>=1.1.3
|
|
40
|
-
Provides-Extra: codex
|
|
41
|
-
Requires-Dist: mcp<3,>=2.2; extra == "codex"
|
|
42
|
-
Requires-Dist: fastapi<1,>=0.115; extra == "codex"
|
|
43
|
-
Requires-Dist: uvicorn<1,>=0.34; extra == "codex"
|
|
44
|
-
Provides-Extra: separation
|
|
45
|
-
Requires-Dist: demucs>=4.0.1; extra == "separation"
|
|
46
|
-
Requires-Dist: openunmix>=1.3.0; extra == "separation"
|
|
47
|
-
Requires-Dist: bs-roformer-infer>=0.1.5; extra == "separation"
|
|
48
|
-
Provides-Extra: speech
|
|
49
|
-
Requires-Dist: faster-whisper; extra == "speech"
|
|
50
|
-
Provides-Extra: beats
|
|
51
|
-
Requires-Dist: beat-this>=1.1.0; extra == "beats"
|
|
52
|
-
Provides-Extra: deep
|
|
53
|
-
Requires-Dist: sentence-transformers<7,>=6.1; extra == "deep"
|
|
54
|
-
Requires-Dist: all-in-one-infer>=3.1; extra == "deep"
|
|
55
|
-
Provides-Extra: semantic-nc
|
|
56
|
-
Requires-Dist: muq; extra == "semantic-nc"
|
|
57
|
-
Provides-Extra: amt
|
|
58
|
-
Requires-Dist: basic-pitch<0.5,>=0.4; python_version < "3.12" and extra == "amt"
|
|
59
|
-
Provides-Extra: server
|
|
60
|
-
Requires-Dist: fastapi<1,>=0.115; extra == "server"
|
|
61
|
-
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "server"
|
|
62
|
-
Requires-Dist: python-socketio<6,>=5.12; extra == "server"
|
|
63
|
-
Provides-Extra: dev
|
|
64
|
-
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
65
|
-
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
66
|
-
Requires-Dist: build>=1.2; extra == "dev"
|
|
67
|
-
Requires-Dist: tomli>=2; python_version < "3.11" and extra == "dev"
|
|
68
|
-
Requires-Dist: httpx2; extra == "dev"
|
|
69
|
-
Provides-Extra: binary
|
|
70
|
-
Requires-Dist: nuitka>=2.7; extra == "binary"
|
|
71
|
-
Requires-Dist: ordered-set>=4.1; extra == "binary"
|
|
72
|
-
Requires-Dist: zstandard>=0.23; extra == "binary"
|
|
73
|
-
Requires-Dist: lazy-loader==0.4; extra == "binary"
|
|
74
|
-
Provides-Extra: all
|
|
75
|
-
Requires-Dist: demucs>=4.0.1; extra == "all"
|
|
76
|
-
Requires-Dist: openunmix>=1.3.0; extra == "all"
|
|
77
|
-
Requires-Dist: bs-roformer-infer>=0.1.5; extra == "all"
|
|
78
|
-
Requires-Dist: faster-whisper; extra == "all"
|
|
79
|
-
Requires-Dist: beat-this>=1.1.0; extra == "all"
|
|
80
|
-
Requires-Dist: sentence-transformers<7,>=6.1; extra == "all"
|
|
81
|
-
Requires-Dist: all-in-one-infer>=3.1; extra == "all"
|
|
82
|
-
Requires-Dist: fastapi<1,>=0.115; extra == "all"
|
|
83
|
-
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "all"
|
|
84
|
-
Requires-Dist: python-socketio<6,>=5.12; extra == "all"
|
|
85
|
-
Dynamic: license-file
|
|
86
|
-
|
|
87
1
|
# StemLab
|
|
88
2
|
|
|
3
|
+
[](https://kieransimkin.co.uk/danceflow/)
|
|
4
|
+
|
|
5
|
+
By **[Kieran Simkin](https://kieransimkin.co.uk/)** · [DanceFlow ecosystem](https://kieransimkin.co.uk/danceflow/) · [Vector logo and usage guide](docs/branding/README.md).
|
|
6
|
+
|
|
7
|
+
Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
|
|
8
|
+
|
|
9
|
+
|
|
89
10
|
<!-- mcp-name: io.github.kieransimkin/stemlab -->
|
|
90
11
|
|
|
91
12
|
> **StemLab by [Kieran Simkin](https://kieransimkin.co.uk/)** · [My Songs portfolio](https://kieransimkin.co.uk/my-songs/) · [Arcadians EPK](https://kieransimkin.co.uk/arcadians/) · [Source](https://github.com/kieransimkin/stemlab)
|
|
92
13
|
|
|
93
14
|
> **Packaging identity:** the canonical project name is **StemLab**. StemLab is part of the **Dance Flow** project. The PyPI distribution is named `danceflow-stemlab` solely because Python package-registry names are globally unique. The Python import, CLI, GitHub repository and container image remain `stemlab`.
|
|
94
15
|
|
|
95
|
-
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
**StemLab is a local, evidence-led music analysis toolkit that turns a master recording into inspectable stems, timing, structure, harmony, lyric and sonic evidence, then finds complete-bar loopable sections for Shorts and other short-form videos.**
|
|
19
|
+
|
|
20
|
+
It combines independent separation and music-information-retrieval routes rather than treating any single model as the answer. Results remain traceable through source hashes, manifests, JSON/TSV/NPZ artefacts, portable Sonic Visualiser sessions and a shared React timeline for playback and comparison. StemLab can run as a CLI, Python library, web service, container or local Codex MCP plugin. It is the music-understanding layer of Kieran Simkin's **DanceFlow** workflow and can supply downstream motion systems such as the WordPress **DanceMoves** plugin, while remaining useful on its own.
|
|
96
21
|
|
|
97
22
|
> **Model weights are not redistributed by this project.** They are fetched from their upstream registries/releases on first use. This avoids silently republishing checkpoints whose licensing may differ from the source code license, and lets upstream integrity metadata be used where available.
|
|
98
23
|
|
|
@@ -134,13 +59,19 @@ Relevant upstreams:
|
|
|
134
59
|
|
|
135
60
|
For every successful separator, **every WAV it emits** is retained. Stem names are discovered from files rather than truncated to a hard-coded four-stem schema, which is important for MVSep Mega 53. For the master and every stem, StemLab writes both a PNG spectrogram and compressed `.npz` spectrogram data (time axis, frequency axis, dB matrix, FFT metadata).
|
|
136
61
|
|
|
62
|
+
Full-resolution spectrogram evidence stays in the `.npz`; the PNG renderer is bounded to 8,192 time frames so long tracks cannot expand into multi-gigabyte Matplotlib RGBA buffers. If an older run retained the NPZ but failed while drawing the PNG, repair it in place without rerunning models:
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
stemlab repair-spectrograms "path\to\analysis-results"
|
|
66
|
+
```
|
|
67
|
+
|
|
137
68
|
The preferred vocal stem is passed through the Silero VAD implementation bundled with `faster-whisper`. Speech regions are used to create a timeline-preserving `spoken_word.wav` (non-speech is zeroed rather than concatenated), then Whisper is run with word timestamps. Outputs include `whisper.json`, `speech_regions.json`, `transcript.txt`, `transcript.srt`, and `words.tsv`.
|
|
138
69
|
|
|
139
70
|
Whisper runs in repetition-safe mode by default (`condition_on_previous_text=False`) to prevent a repeated syllable in one window contaminating later windows. `whisper.json` records that setting and includes repeated-token diagnostics. Use `--whisper-condition-on-previous-text` only for an explicit comparison run; a flagged transcript remains evidence requiring section-wise recovery or listening QA, not a trustworthy lyric source.
|
|
140
71
|
|
|
141
72
|
Beat analysis runs:
|
|
142
73
|
|
|
143
|
-
- **BeatNet** in offline/DBN mode
|
|
74
|
+
- **BeatNet** in offline/DBN mode through StemLab's checksum-verified runtime bootstrap. StemLab uses the maintained `madmom-prebuilt` wheel and bypasses only BeatNet 1.1.3's obsolete NumPy/Numba package metadata.
|
|
144
75
|
- **Beat This!** using the `final0` checkpoint and its minimal postprocessor.
|
|
145
76
|
- **Beat Transformer**, using the original released model code/checkpoints. The model was trained on five demixed mel streams, so StemLab maps BS-RoFormer-SW to vocals, drums, bass, piano, and `other + guitar`, makes 128-bin mel-power spectrograms at the original 44.1 kHz / 4096 FFT / 1024-hop settings, and averages all eight released fold checkpoints by default. It uses the original madmom DBN decoder if madmom is importable, otherwise a documented SciPy peak-picking fallback.
|
|
146
77
|
|
|
@@ -305,9 +236,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
305
236
|
|
|
306
237
|

|
|
307
238
|
|
|
239
|
+
## Audio-to-MIDI model comparison
|
|
240
|
+
|
|
241
|
+
MIDI extraction is an **optional, independent model pass**. It adds Transkun V2
|
|
242
|
+
and high-resolution note/pedal piano transcription, plus MR-MT3 and YourMT3
|
|
243
|
+
multi-instrument transcription, alongside Spotify Basic Pitch. Automatic source
|
|
244
|
+
selection uses piano/keyboard stems for the piano specialists, pitched stems for
|
|
245
|
+
Basic Pitch and the mix for MT3-family models. Missing stems are reported, never
|
|
246
|
+
silently substituted. The legacy `--basic-pitch` command remains supported.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Install the chosen runtime; the standard profiles do not install MIDI models.
|
|
250
|
+
python -m pip install -e ".[midi-transkun]"
|
|
251
|
+
stemlab midi-models
|
|
252
|
+
|
|
253
|
+
# Use an existing separated piano, without rerunning any earlier analysis.
|
|
254
|
+
stemlab midi analysis-master --model transkun
|
|
255
|
+
|
|
256
|
+
# Or transcribe a directly supplied piano recording to a new folder.
|
|
257
|
+
stemlab midi piano.wav -o midi-piano --model transkun
|
|
258
|
+
|
|
259
|
+
# Full mix comparison requires the separately installed midi-mt3 extra.
|
|
260
|
+
# Both requested checkpoints need explicit first-use download consent.
|
|
261
|
+
stemlab midi mix.wav -o midi-comparison --model mr_mt3 --model yourmt3 --allow-model-downloads
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Each model/source gets its original `.mid`, tempo-aware `notes.json` and
|
|
265
|
+
`notes.csv`, an optional real note `piano-roll.png`, source/checkpoint hashes,
|
|
266
|
+
package versions and a worker log. Native MIDI controllers, pitch bends, tempo
|
|
267
|
+
changes and drums are preserved. Note sample numbers are original-rate
|
|
268
|
+
**estimates**, not a claim that the transcription is sample-accurate ground truth.
|
|
269
|
+
The MIDI clock is not used to overwrite StemLab's measured beat grid.
|
|
270
|
+
|
|
271
|
+
New analyses can opt in with repeated `--midi-model` switches and
|
|
272
|
+
`--midi-allow-downloads`. Existing Codex installations gain a workspace-scoped
|
|
273
|
+
`stemlab_start_midi_scan` job tool after updating the Python installation and
|
|
274
|
+
restarting the session. Models remain optional and no Python dependencies are
|
|
275
|
+
automatically installed. Incompatible research runtimes can use separate
|
|
276
|
+
`--backend-python MODEL=PATH` interpreters.
|
|
277
|
+
|
|
278
|
+
See [the MIDI guide](docs/midi.md) for all models, installation choices, checkpoint
|
|
279
|
+
and licensing caveats, saved-stem targeting, Codex usage, exact output semantics,
|
|
280
|
+
real-inference smoke commands and test limitations. The React timeline remains
|
|
281
|
+
the analysis inspector; this patch adds no MIDI synthesizer or new interactive
|
|
282
|
+
piano-roll lane. Static note plots are not frontend screenshots.
|
|
283
|
+
|
|
284
|
+
## Align timed musical cues to detected beats
|
|
285
|
+
|
|
286
|
+
Use saved analysis to snap an LRC cue file without rerunning models or editing audio:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review
|
|
290
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review-100ms --tolerance-ms 100
|
|
291
|
+
stemlab generate-cues analysis-master -o generated-cues --title "Song title"
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Only timestamps change: bracketed labels such as `[DROP: CHORUS 1]`, metadata,
|
|
295
|
+
encoding and line layout are preserved. A cue with **no detected beat within
|
|
296
|
+
±150 ms** is highlighted as **REVIEW**, with its nearest-beat gap, and kept unchanged
|
|
297
|
+
by default. `--force-snap` moves distant cues too but retains their warnings.
|
|
298
|
+
`--downbeats` restricts targets to reported bar starts; `--beat-model` selects a
|
|
299
|
+
specific detector. No constant-tempo beats are invented to fill detection gaps.
|
|
300
|
+
|
|
301
|
+
Each new output folder contains the rewritten `.beat-snapped.lrc`, `report.json`,
|
|
302
|
+
a colour-coded `review.html`, and `review.txt`. Exact mode preserves the stored
|
|
303
|
+
beat timestamp; explicit millisecond/centisecond compatibility modes report
|
|
304
|
+
rounding. Source-rate sample-frame estimates are included when the rate is known.
|
|
305
|
+
Use `--fail-on-review` to write results and exit 2 when review is needed.
|
|
306
|
+
Generated section-cue files use a title-specific, WordPress-safe filename so
|
|
307
|
+
multiple releases can be uploaded and mapped without ambiguous duplicate names.
|
|
308
|
+
For the retained 3 October 2026 future-release batch,
|
|
309
|
+
`scripts/run-upcoming-full-cues.ps1` resumes full analyses without overwriting an
|
|
310
|
+
incomplete directory, and `scripts/summarize-upcoming-cues.ps1` reads each closed
|
|
311
|
+
manifest/report to produce one reproducible hash, cue-action and error-count row
|
|
312
|
+
per release. The summary script refuses missing or ambiguous generated LRCs.
|
|
313
|
+
|
|
314
|
+
For a new analysis, add `--snap-cues "musical cues.lrc"` and optionally
|
|
315
|
+
`--cue-tolerance-ms 100`. Cue alignment uses that run's detected events and appears
|
|
316
|
+
in `analysis.json`. See [the cue alignment guide](docs/cue-alignment.md) for exact
|
|
317
|
+
precision, offsets, all switches, safety rules and interpretation of warnings.
|
|
318
|
+
|
|
319
|
+
## Complementary evidence models
|
|
320
|
+
|
|
321
|
+
StemLab now has an optional **evidence-model layer** for models that add a different
|
|
322
|
+
kind of musical evidence instead of duplicating the normal separation or MIDI
|
|
323
|
+
backends. Nothing in this layer is enabled by a normal profile.
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
stemlab evidence-models
|
|
327
|
+
|
|
328
|
+
# Singing/speech/music activity + continuous pitch on saved vocals.
|
|
329
|
+
stemlab evidence analysis-master -o evidence-vocals \
|
|
330
|
+
--model firered_aed --model swift_f0 \
|
|
331
|
+
--model-path firered_aed=/models/FireRedVAD/AED
|
|
332
|
+
|
|
333
|
+
# Align approved lyrics without replacing them.
|
|
334
|
+
stemlab evidence analysis-master -o evidence-align \
|
|
335
|
+
--model qwen_forced_aligner --canonical-text lyrics.txt --allow-model-downloads
|
|
336
|
+
|
|
337
|
+
# Independent harmony evidence.
|
|
338
|
+
stemlab evidence analysis-master -o evidence-chords --model lv_chordia
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The built-in registry covers **FireRed AED**, **HeartTranscriptor**, **Qwen3
|
|
342
|
+
ForcedAligner**, **SwiftF0**, **SongFormer**, **lv-chordia** and **ADTOF PyTorch**.
|
|
343
|
+
It also exposes explicit external-runtime bridges for **GAME**, **SheetSage2**,
|
|
344
|
+
**MOSS-Music** and **AudioSep** so large or restricted research dependencies never
|
|
345
|
+
get silently bundled into StemLab. Outputs stay independent: singing activity,
|
|
346
|
+
forced alignment, pitch, structure, chords and drum hits are review evidence, not
|
|
347
|
+
a hidden combined ground-truth score.
|
|
348
|
+
|
|
349
|
+
Saved analyses automatically route vocal models to a preferred full vocal stem,
|
|
350
|
+
drum transcription to a drum stem, continuous pitch to pitched stems, and
|
|
351
|
+
structure/harmony models to the master. Missing specialist stems are reported.
|
|
352
|
+
Use `--backend-python MODEL=/path/to/python` for conflicting research environments.
|
|
353
|
+
|
|
354
|
+
See [the evidence-model guide](docs/evidence-models.md) for model terms, routing,
|
|
355
|
+
external bridges and interpretation rules. `scripts/benchmark_evidence_corpus.py`
|
|
356
|
+
probes an authorised evaluation collection without copying audio into the repo.
|
|
357
|
+
|
|
308
358
|
## Install
|
|
309
359
|
|
|
310
|
-
Python 3.
|
|
360
|
+
Python 3.11 is recommended for the broad optional-model ecosystem. The `beats` and `all` extras install Beat This! plus the compatible `madmom-prebuilt` decoder. BeatNet 1.1.3 itself still publishes obsolete NumPy/Numba dependency pins, so StemLab downloads its official pure-Python wheel separately, verifies the published SHA-256, and exposes only the BeatNet code and bundled model weights from its cache. This route is supported on Python 3.11-3.13; a missing BeatNet result must not be mistaken for a successful detector run.
|
|
311
361
|
|
|
312
362
|
From PyPI, install the released StemLab distribution with:
|
|
313
363
|
|
|
@@ -330,6 +380,18 @@ SCNet and Beat Transformer are research repositories rather than stable pip infe
|
|
|
330
380
|
stemlab bootstrap all
|
|
331
381
|
```
|
|
332
382
|
|
|
383
|
+
For BeatNet alone:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
pip install "danceflow-stemlab[beats]"
|
|
387
|
+
stemlab bootstrap beatnet
|
|
388
|
+
stemlab doctor
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
`stemlab doctor` reports BeatNet as ready only when the normal package or the
|
|
392
|
+
verified StemLab cache can actually be found. `analyze --no-bootstrap` never
|
|
393
|
+
downloads BeatNet and records the unavailable backend instead.
|
|
394
|
+
|
|
333
395
|
For only the Vamp analysis stack:
|
|
334
396
|
|
|
335
397
|
```bash
|
|
@@ -439,6 +501,7 @@ endpoints, events and the Arcadians reference workflow.
|
|
|
439
501
|
- [Web service](docs/web.md)
|
|
440
502
|
- [Containers](docs/containers.md)
|
|
441
503
|
- [Publishing and releases](docs/publishing.md)
|
|
504
|
+
- [BeatNet compatibility](docs/beatnet.md)
|
|
442
505
|
- [Changelog](CHANGELOG.md)
|
|
443
506
|
|
|
444
507
|
## Codex plugin and MCP server
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# StemLab visual identity
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
By [Kieran Simkin](https://kieransimkin.co.uk/), part of [DanceFlow](https://kieransimkin.co.uk/danceflow/).
|
|
6
|
+
|
|
7
|
+
Split waveforms: inspectable music and stem analysis.
|
|
8
|
+
|
|
9
|
+
Original vector artwork, created 8 October 2026. Shared family: 128-unit square, rounded 30-unit frame, 5.5-unit rounded strokes, plum `#171124`, mint `#bff7df`, gold `#f5ce85`. The symbol remains unique without colour. `logo.svg` is the self-contained dark badge; `logo-monochrome.svg` is a transparent dark mark for light surfaces; `logo.png` is the 256px registry/export companion. Prefer SVG for scaling and label tiny marks with the tool name. No external fonts, scripts, remote references, animation or model-generated assets.
|
|
10
|
+
|
|
11
|
+
Use the files unchanged at a square aspect ratio, with at least 8/128 of their width as clear space. The monochrome mark needs a light background. Do not imply an official association with model providers, React, WordPress or operating-system vendors. Source artwork follows this repository's licence; dependency and third-party notices retain their own terms.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">StemLab logo</title>
|
|
3
|
+
<desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
|
|
4
|
+
|
|
5
|
+
<g fill="none" stroke="#171124" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#171124"/><circle cx="94" cy="64" r="5" fill="#171124" stroke="none"/></g>
|
|
6
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">StemLab logo</title>
|
|
3
|
+
<desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
|
|
4
|
+
<rect x="3" y="3" width="122" height="122" rx="30" fill="#171124"/><rect x="8" y="8" width="112" height="112" rx="25" fill="none" stroke="#f5ce85" stroke-opacity=".35" stroke-width="1.5"/>
|
|
5
|
+
<g fill="none" stroke="#bff7df" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#f5ce85"/><circle cx="94" cy="64" r="5" fill="#f5ce85" stroke="none"/></g>
|
|
6
|
+
</svg>
|