danceflow-stemlab 1.2.0__tar.gz → 1.3.0__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.0}/MANIFEST.in +5 -0
- {danceflow_stemlab-1.2.0/src/danceflow_stemlab.egg-info → danceflow_stemlab-1.3.0}/PKG-INFO +185 -5
- danceflow_stemlab-1.2.0/PKG-INFO → danceflow_stemlab-1.3.0/README.md +145 -89
- danceflow_stemlab-1.3.0/docs/cue-alignment.md +201 -0
- danceflow_stemlab-1.3.0/docs/evidence-models.md +109 -0
- danceflow_stemlab-1.3.0/docs/midi.md +353 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/mcp-registry/server.json +4 -4
- danceflow_stemlab-1.3.0/plugins/stemlab/.codex-plugin/plugin.json +24 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/plugin.json +4 -4
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/skills/stemlab/SKILL.md +29 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/skills/stemlab/references/tools.md +3 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/pyproject.toml +26 -5
- danceflow_stemlab-1.3.0/scripts/benchmark_evidence_corpus.py +46 -0
- danceflow_stemlab-1.3.0/scripts/smoke_midi.py +44 -0
- danceflow_stemlab-1.2.0/README.md → danceflow_stemlab-1.3.0/src/danceflow_stemlab.egg-info/PKG-INFO +269 -3
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/SOURCES.txt +36 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/requires.txt +51 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/__init__.py +1 -1
- danceflow_stemlab-1.3.0/src/stemlab/analysis/evidence/__init__.py +4 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/evidence/adapters.py +230 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/evidence/registry.py +146 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/evidence/runner.py +216 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/evidence/worker.py +35 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/__init__.py +8 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/adapters.py +254 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/artifacts.py +109 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/registry.py +119 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/runner.py +238 -0
- danceflow_stemlab-1.3.0/src/stemlab/analysis/midi/worker.py +39 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/registry.py +25 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/runner.py +63 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/beats/beatnet.py +16 -3
- danceflow_stemlab-1.3.0/src/stemlab/beats/beatthis.py +41 -0
- danceflow_stemlab-1.3.0/src/stemlab/bootstrap.py +249 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/branding.py +4 -3
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/canonical.py +5 -12
- danceflow_stemlab-1.3.0/src/stemlab/cli.py +452 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/bridge.py +55 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/jobs.py +1 -1
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/server.py +40 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/tasks.py +125 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/worker.py +5 -1
- danceflow_stemlab-1.3.0/src/stemlab/cue_cli.py +86 -0
- danceflow_stemlab-1.3.0/src/stemlab/cues.py +645 -0
- danceflow_stemlab-1.3.0/src/stemlab/lyric_lrc.py +105 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/pipeline.py +79 -2
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/bsroformer.py +27 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/spectrogram.py +57 -27
- danceflow_stemlab-1.3.0/src/stemlab/spectrogram_repair.py +86 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/types.py +24 -0
- danceflow_stemlab-1.3.0/src/stemlab/word_alignment.py +114 -0
- danceflow_stemlab-1.3.0/tests/test_beat_this_bootstrap.py +62 -0
- danceflow_stemlab-1.3.0/tests/test_beatnet_bootstrap.py +66 -0
- danceflow_stemlab-1.3.0/tests/test_bsroformer_adapter.py +30 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_protocol.py +1 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_release.py +1 -1
- danceflow_stemlab-1.3.0/tests/test_cue_integration.py +200 -0
- danceflow_stemlab-1.3.0/tests/test_cues.py +370 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_distribution_identity.py +7 -1
- danceflow_stemlab-1.3.0/tests/test_docker_contract.py +78 -0
- danceflow_stemlab-1.3.0/tests/test_evidence_models.py +126 -0
- danceflow_stemlab-1.3.0/tests/test_lyric_lrc.py +75 -0
- danceflow_stemlab-1.3.0/tests/test_midi_adapters.py +245 -0
- danceflow_stemlab-1.3.0/tests/test_midi_extraction.py +207 -0
- danceflow_stemlab-1.3.0/tests/test_midi_integration.py +151 -0
- danceflow_stemlab-1.3.0/tests/test_midi_registry.py +52 -0
- danceflow_stemlab-1.3.0/tests/test_spectrogram.py +55 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_web_frontend.py +5 -4
- danceflow_stemlab-1.3.0/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.0}/.agents/plugins/marketplace.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/.github/workflows/codex-plugin.yml +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/.github/workflows/release.yml +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/LICENSE +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/docs/codex-plugin.md +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/docs/codex-publishing.md +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/.mcp.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/README.md +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/plugins/stemlab/mcp.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/build_codex_plugin.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/capture_loop_workflow.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/check_codex_timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/loop_demo.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/prepare_codex_marketplace.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/scripts/publish_mcp_registry.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/setup.cfg +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/dependency_links.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/entry_points.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/top_level.txt +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/__main__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/harmony.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/loops.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/lyrics.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/rhythm.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/semantic_audio.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/semantic_text.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/song_map.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/sonic.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/structure.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/tempo_regimes.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/transcription.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/audio.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/beats/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/beats/base.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/beats/beattransformer.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/beats/common.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/__main__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/paths.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/codex/timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/manifest.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/models.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/__init__.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/base.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/common.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/demucs.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/openunmix.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/separators/scnet.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/server.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/speech.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/util.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/vamp.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/vamp_runtime.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/app.js +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/arcadians-cover.jpg +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/arcadians-reference.json +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/index.html +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/style.css +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/web/timeline.css +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/src/stemlab/webui.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_analysis_registry.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_arcadians_fixture.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_audio_normalization.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_beat_consensus.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_beatnet_compat.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_branding.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_canonical.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_canonical_extended.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_bridge.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_jobs.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_package.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_codex_timeline.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_deep_harmony.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_deep_lyrics.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_deep_sonic_rhythm.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_loop_integration.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_loops.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_manifest.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_models.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_repository_hygiene.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_server.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_song_map.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_sonic_visualiser_workspace.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_speech_repetition.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_vamp.py +0 -0
- {danceflow_stemlab-1.2.0 → danceflow_stemlab-1.3.0}/tests/test_vamp_runtime.py +0 -0
|
@@ -13,3 +13,8 @@ include .github/workflows/release.yml
|
|
|
13
13
|
include scripts/check_codex_timeline.py
|
|
14
14
|
include scripts/loop_demo.py
|
|
15
15
|
include scripts/capture_loop_workflow.py
|
|
16
|
+
include docs/midi.md
|
|
17
|
+
include scripts/smoke_midi.py
|
|
18
|
+
include docs/cue-alignment.md
|
|
19
|
+
include docs/evidence-models.md
|
|
20
|
+
include scripts/benchmark_evidence_corpus.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: danceflow-stemlab
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Local, evidence-led music analysis for stems, timing, structure, harmony, lyrics, and loopable sections for Shorts
|
|
5
5
|
Author: Kieran Simkin
|
|
6
6
|
Maintainer: Kieran Simkin
|
|
7
7
|
License-Expression: MIT
|
|
@@ -49,6 +49,8 @@ Provides-Extra: speech
|
|
|
49
49
|
Requires-Dist: faster-whisper; extra == "speech"
|
|
50
50
|
Provides-Extra: beats
|
|
51
51
|
Requires-Dist: beat-this>=1.1.0; extra == "beats"
|
|
52
|
+
Requires-Dist: madmom-prebuilt==0.17.post1; python_version >= "3.11" and extra == "beats"
|
|
53
|
+
Requires-Dist: mido>=1.2.6; extra == "beats"
|
|
52
54
|
Provides-Extra: deep
|
|
53
55
|
Requires-Dist: sentence-transformers<7,>=6.1; extra == "deep"
|
|
54
56
|
Requires-Dist: all-in-one-infer>=3.1; extra == "deep"
|
|
@@ -56,6 +58,40 @@ Provides-Extra: semantic-nc
|
|
|
56
58
|
Requires-Dist: muq; extra == "semantic-nc"
|
|
57
59
|
Provides-Extra: amt
|
|
58
60
|
Requires-Dist: basic-pitch<0.5,>=0.4; python_version < "3.12" and extra == "amt"
|
|
61
|
+
Provides-Extra: midi
|
|
62
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi"
|
|
63
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi"
|
|
64
|
+
Requires-Dist: psutil>=5.9; extra == "midi"
|
|
65
|
+
Provides-Extra: midi-piano
|
|
66
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-piano"
|
|
67
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-piano"
|
|
68
|
+
Requires-Dist: psutil>=5.9; extra == "midi-piano"
|
|
69
|
+
Requires-Dist: piano-transcription-inference==0.0.6; extra == "midi-piano"
|
|
70
|
+
Provides-Extra: midi-transkun
|
|
71
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-transkun"
|
|
72
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-transkun"
|
|
73
|
+
Requires-Dist: psutil>=5.9; extra == "midi-transkun"
|
|
74
|
+
Requires-Dist: transkun==2.0.1; extra == "midi-transkun"
|
|
75
|
+
Requires-Dist: setuptools<81; extra == "midi-transkun"
|
|
76
|
+
Provides-Extra: midi-mt3
|
|
77
|
+
Requires-Dist: pretty-midi<0.3,>=0.2.10; extra == "midi-mt3"
|
|
78
|
+
Requires-Dist: mido<2,>=1.3; extra == "midi-mt3"
|
|
79
|
+
Requires-Dist: psutil>=5.9; extra == "midi-mt3"
|
|
80
|
+
Requires-Dist: mt3-infer[torch]==0.2.0; extra == "midi-mt3"
|
|
81
|
+
Provides-Extra: evidence
|
|
82
|
+
Requires-Dist: psutil>=5.9; extra == "evidence"
|
|
83
|
+
Provides-Extra: evidence-vocals
|
|
84
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-vocals"
|
|
85
|
+
Requires-Dist: fireredvad<0.1,>=0.0.2; extra == "evidence-vocals"
|
|
86
|
+
Provides-Extra: evidence-pitch
|
|
87
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-pitch"
|
|
88
|
+
Requires-Dist: swift-f0[audio]<0.4,>=0.3; extra == "evidence-pitch"
|
|
89
|
+
Provides-Extra: evidence-align
|
|
90
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-align"
|
|
91
|
+
Requires-Dist: qwen-asr; extra == "evidence-align"
|
|
92
|
+
Provides-Extra: evidence-chords
|
|
93
|
+
Requires-Dist: psutil>=5.9; extra == "evidence-chords"
|
|
94
|
+
Requires-Dist: lv-chordia; extra == "evidence-chords"
|
|
59
95
|
Provides-Extra: server
|
|
60
96
|
Requires-Dist: fastapi<1,>=0.115; extra == "server"
|
|
61
97
|
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "server"
|
|
@@ -77,6 +113,8 @@ Requires-Dist: openunmix>=1.3.0; extra == "all"
|
|
|
77
113
|
Requires-Dist: bs-roformer-infer>=0.1.5; extra == "all"
|
|
78
114
|
Requires-Dist: faster-whisper; extra == "all"
|
|
79
115
|
Requires-Dist: beat-this>=1.1.0; extra == "all"
|
|
116
|
+
Requires-Dist: madmom-prebuilt==0.17.post1; python_version >= "3.11" and extra == "all"
|
|
117
|
+
Requires-Dist: mido>=1.2.6; extra == "all"
|
|
80
118
|
Requires-Dist: sentence-transformers<7,>=6.1; extra == "all"
|
|
81
119
|
Requires-Dist: all-in-one-infer>=3.1; extra == "all"
|
|
82
120
|
Requires-Dist: fastapi<1,>=0.115; extra == "all"
|
|
@@ -92,7 +130,11 @@ Dynamic: license-file
|
|
|
92
130
|
|
|
93
131
|
> **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
132
|
|
|
95
|
-
|
|
133
|
+
## Synopsis
|
|
134
|
+
|
|
135
|
+
**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.**
|
|
136
|
+
|
|
137
|
+
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
138
|
|
|
97
139
|
> **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
140
|
|
|
@@ -134,13 +176,19 @@ Relevant upstreams:
|
|
|
134
176
|
|
|
135
177
|
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
178
|
|
|
179
|
+
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:
|
|
180
|
+
|
|
181
|
+
```powershell
|
|
182
|
+
stemlab repair-spectrograms "path\to\analysis-results"
|
|
183
|
+
```
|
|
184
|
+
|
|
137
185
|
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
186
|
|
|
139
187
|
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
188
|
|
|
141
189
|
Beat analysis runs:
|
|
142
190
|
|
|
143
|
-
- **BeatNet** in offline/DBN mode
|
|
191
|
+
- **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
192
|
- **Beat This!** using the `final0` checkpoint and its minimal postprocessor.
|
|
145
193
|
- **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
194
|
|
|
@@ -305,9 +353,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
305
353
|
|
|
306
354
|

|
|
307
355
|
|
|
356
|
+
## Audio-to-MIDI model comparison
|
|
357
|
+
|
|
358
|
+
MIDI extraction is an **optional, independent model pass**. It adds Transkun V2
|
|
359
|
+
and high-resolution note/pedal piano transcription, plus MR-MT3 and YourMT3
|
|
360
|
+
multi-instrument transcription, alongside Spotify Basic Pitch. Automatic source
|
|
361
|
+
selection uses piano/keyboard stems for the piano specialists, pitched stems for
|
|
362
|
+
Basic Pitch and the mix for MT3-family models. Missing stems are reported, never
|
|
363
|
+
silently substituted. The legacy `--basic-pitch` command remains supported.
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# Install the chosen runtime; the standard profiles do not install MIDI models.
|
|
367
|
+
python -m pip install -e ".[midi-transkun]"
|
|
368
|
+
stemlab midi-models
|
|
369
|
+
|
|
370
|
+
# Use an existing separated piano, without rerunning any earlier analysis.
|
|
371
|
+
stemlab midi analysis-master --model transkun
|
|
372
|
+
|
|
373
|
+
# Or transcribe a directly supplied piano recording to a new folder.
|
|
374
|
+
stemlab midi piano.wav -o midi-piano --model transkun
|
|
375
|
+
|
|
376
|
+
# Full mix comparison requires the separately installed midi-mt3 extra.
|
|
377
|
+
# Both requested checkpoints need explicit first-use download consent.
|
|
378
|
+
stemlab midi mix.wav -o midi-comparison --model mr_mt3 --model yourmt3 --allow-model-downloads
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Each model/source gets its original `.mid`, tempo-aware `notes.json` and
|
|
382
|
+
`notes.csv`, an optional real note `piano-roll.png`, source/checkpoint hashes,
|
|
383
|
+
package versions and a worker log. Native MIDI controllers, pitch bends, tempo
|
|
384
|
+
changes and drums are preserved. Note sample numbers are original-rate
|
|
385
|
+
**estimates**, not a claim that the transcription is sample-accurate ground truth.
|
|
386
|
+
The MIDI clock is not used to overwrite StemLab's measured beat grid.
|
|
387
|
+
|
|
388
|
+
New analyses can opt in with repeated `--midi-model` switches and
|
|
389
|
+
`--midi-allow-downloads`. Existing Codex installations gain a workspace-scoped
|
|
390
|
+
`stemlab_start_midi_scan` job tool after updating the Python installation and
|
|
391
|
+
restarting the session. Models remain optional and no Python dependencies are
|
|
392
|
+
automatically installed. Incompatible research runtimes can use separate
|
|
393
|
+
`--backend-python MODEL=PATH` interpreters.
|
|
394
|
+
|
|
395
|
+
See [the MIDI guide](docs/midi.md) for all models, installation choices, checkpoint
|
|
396
|
+
and licensing caveats, saved-stem targeting, Codex usage, exact output semantics,
|
|
397
|
+
real-inference smoke commands and test limitations. The React timeline remains
|
|
398
|
+
the analysis inspector; this patch adds no MIDI synthesizer or new interactive
|
|
399
|
+
piano-roll lane. Static note plots are not frontend screenshots.
|
|
400
|
+
|
|
401
|
+
## Align timed musical cues to detected beats
|
|
402
|
+
|
|
403
|
+
Use saved analysis to snap an LRC cue file without rerunning models or editing audio:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review
|
|
407
|
+
stemlab snap-cues analysis-master "musical cues.lrc" -o cue-review-100ms --tolerance-ms 100
|
|
408
|
+
stemlab generate-cues analysis-master -o generated-cues --title "Song title"
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Only timestamps change: bracketed labels such as `[DROP: CHORUS 1]`, metadata,
|
|
412
|
+
encoding and line layout are preserved. A cue with **no detected beat within
|
|
413
|
+
±150 ms** is highlighted as **REVIEW**, with its nearest-beat gap, and kept unchanged
|
|
414
|
+
by default. `--force-snap` moves distant cues too but retains their warnings.
|
|
415
|
+
`--downbeats` restricts targets to reported bar starts; `--beat-model` selects a
|
|
416
|
+
specific detector. No constant-tempo beats are invented to fill detection gaps.
|
|
417
|
+
|
|
418
|
+
Each new output folder contains the rewritten `.beat-snapped.lrc`, `report.json`,
|
|
419
|
+
a colour-coded `review.html`, and `review.txt`. Exact mode preserves the stored
|
|
420
|
+
beat timestamp; explicit millisecond/centisecond compatibility modes report
|
|
421
|
+
rounding. Source-rate sample-frame estimates are included when the rate is known.
|
|
422
|
+
Use `--fail-on-review` to write results and exit 2 when review is needed.
|
|
423
|
+
Generated section-cue files use a title-specific, WordPress-safe filename so
|
|
424
|
+
multiple releases can be uploaded and mapped without ambiguous duplicate names.
|
|
425
|
+
For the retained 3 October 2026 future-release batch,
|
|
426
|
+
`scripts/run-upcoming-full-cues.ps1` resumes full analyses without overwriting an
|
|
427
|
+
incomplete directory, and `scripts/summarize-upcoming-cues.ps1` reads each closed
|
|
428
|
+
manifest/report to produce one reproducible hash, cue-action and error-count row
|
|
429
|
+
per release. The summary script refuses missing or ambiguous generated LRCs.
|
|
430
|
+
|
|
431
|
+
For a new analysis, add `--snap-cues "musical cues.lrc"` and optionally
|
|
432
|
+
`--cue-tolerance-ms 100`. Cue alignment uses that run's detected events and appears
|
|
433
|
+
in `analysis.json`. See [the cue alignment guide](docs/cue-alignment.md) for exact
|
|
434
|
+
precision, offsets, all switches, safety rules and interpretation of warnings.
|
|
435
|
+
|
|
436
|
+
## Complementary evidence models
|
|
437
|
+
|
|
438
|
+
StemLab now has an optional **evidence-model layer** for models that add a different
|
|
439
|
+
kind of musical evidence instead of duplicating the normal separation or MIDI
|
|
440
|
+
backends. Nothing in this layer is enabled by a normal profile.
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
stemlab evidence-models
|
|
444
|
+
|
|
445
|
+
# Singing/speech/music activity + continuous pitch on saved vocals.
|
|
446
|
+
stemlab evidence analysis-master -o evidence-vocals \
|
|
447
|
+
--model firered_aed --model swift_f0 \
|
|
448
|
+
--model-path firered_aed=/models/FireRedVAD/AED
|
|
449
|
+
|
|
450
|
+
# Align approved lyrics without replacing them.
|
|
451
|
+
stemlab evidence analysis-master -o evidence-align \
|
|
452
|
+
--model qwen_forced_aligner --canonical-text lyrics.txt --allow-model-downloads
|
|
453
|
+
|
|
454
|
+
# Independent harmony evidence.
|
|
455
|
+
stemlab evidence analysis-master -o evidence-chords --model lv_chordia
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
The built-in registry covers **FireRed AED**, **HeartTranscriptor**, **Qwen3
|
|
459
|
+
ForcedAligner**, **SwiftF0**, **SongFormer**, **lv-chordia** and **ADTOF PyTorch**.
|
|
460
|
+
It also exposes explicit external-runtime bridges for **GAME**, **SheetSage2**,
|
|
461
|
+
**MOSS-Music** and **AudioSep** so large or restricted research dependencies never
|
|
462
|
+
get silently bundled into StemLab. Outputs stay independent: singing activity,
|
|
463
|
+
forced alignment, pitch, structure, chords and drum hits are review evidence, not
|
|
464
|
+
a hidden combined ground-truth score.
|
|
465
|
+
|
|
466
|
+
Saved analyses automatically route vocal models to a preferred full vocal stem,
|
|
467
|
+
drum transcription to a drum stem, continuous pitch to pitched stems, and
|
|
468
|
+
structure/harmony models to the master. Missing specialist stems are reported.
|
|
469
|
+
Use `--backend-python MODEL=/path/to/python` for conflicting research environments.
|
|
470
|
+
|
|
471
|
+
See [the evidence-model guide](docs/evidence-models.md) for model terms, routing,
|
|
472
|
+
external bridges and interpretation rules. `scripts/benchmark_evidence_corpus.py`
|
|
473
|
+
probes an authorised evaluation collection without copying audio into the repo.
|
|
474
|
+
|
|
308
475
|
## Install
|
|
309
476
|
|
|
310
|
-
Python 3.
|
|
477
|
+
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
478
|
|
|
312
479
|
From PyPI, install the released StemLab distribution with:
|
|
313
480
|
|
|
@@ -330,6 +497,18 @@ SCNet and Beat Transformer are research repositories rather than stable pip infe
|
|
|
330
497
|
stemlab bootstrap all
|
|
331
498
|
```
|
|
332
499
|
|
|
500
|
+
For BeatNet alone:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
pip install "danceflow-stemlab[beats]"
|
|
504
|
+
stemlab bootstrap beatnet
|
|
505
|
+
stemlab doctor
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
`stemlab doctor` reports BeatNet as ready only when the normal package or the
|
|
509
|
+
verified StemLab cache can actually be found. `analyze --no-bootstrap` never
|
|
510
|
+
downloads BeatNet and records the unavailable backend instead.
|
|
511
|
+
|
|
333
512
|
For only the Vamp analysis stack:
|
|
334
513
|
|
|
335
514
|
```bash
|
|
@@ -439,6 +618,7 @@ endpoints, events and the Arcadians reference workflow.
|
|
|
439
618
|
- [Web service](docs/web.md)
|
|
440
619
|
- [Containers](docs/containers.md)
|
|
441
620
|
- [Publishing and releases](docs/publishing.md)
|
|
621
|
+
- [BeatNet compatibility](docs/beatnet.md)
|
|
442
622
|
- [Changelog](CHANGELOG.md)
|
|
443
623
|
|
|
444
624
|
## Codex plugin and MCP server
|
|
@@ -1,89 +1,3 @@
|
|
|
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
|
|
|
89
3
|
<!-- mcp-name: io.github.kieransimkin/stemlab -->
|
|
@@ -92,7 +6,11 @@ Dynamic: license-file
|
|
|
92
6
|
|
|
93
7
|
> **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
8
|
|
|
95
|
-
|
|
9
|
+
## Synopsis
|
|
10
|
+
|
|
11
|
+
**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.**
|
|
12
|
+
|
|
13
|
+
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
14
|
|
|
97
15
|
> **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
16
|
|
|
@@ -134,13 +52,19 @@ Relevant upstreams:
|
|
|
134
52
|
|
|
135
53
|
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
54
|
|
|
55
|
+
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:
|
|
56
|
+
|
|
57
|
+
```powershell
|
|
58
|
+
stemlab repair-spectrograms "path\to\analysis-results"
|
|
59
|
+
```
|
|
60
|
+
|
|
137
61
|
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
62
|
|
|
139
63
|
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
64
|
|
|
141
65
|
Beat analysis runs:
|
|
142
66
|
|
|
143
|
-
- **BeatNet** in offline/DBN mode
|
|
67
|
+
- **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
68
|
- **Beat This!** using the `final0` checkpoint and its minimal postprocessor.
|
|
145
69
|
- **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
70
|
|
|
@@ -305,9 +229,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
305
229
|
|
|
306
230
|

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