danceflow-stemlab 1.1.2__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.1.2 → danceflow_stemlab-1.3.0}/MANIFEST.in +5 -0
- {danceflow_stemlab-1.1.2/src/danceflow_stemlab.egg-info → danceflow_stemlab-1.3.0}/PKG-INFO +193 -5
- danceflow_stemlab-1.1.2/PKG-INFO → danceflow_stemlab-1.3.0/README.md +153 -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.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/plugin.json +4 -4
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/skills/stemlab/SKILL.md +29 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/skills/stemlab/references/tools.md +3 -1
- {danceflow_stemlab-1.1.2 → 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.1.2/README.md → danceflow_stemlab-1.3.0/src/danceflow_stemlab.egg-info/PKG-INFO +277 -3
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/SOURCES.txt +36 -1
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/requires.txt +51 -0
- {danceflow_stemlab-1.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/loops.py +172 -29
- 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/registry.py +25 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/runner.py +66 -3
- {danceflow_stemlab-1.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/branding.py +4 -3
- {danceflow_stemlab-1.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/bridge.py +66 -5
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/jobs.py +1 -1
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/server.py +55 -5
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/tasks.py +135 -3
- {danceflow_stemlab-1.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/pipeline.py +82 -2
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/bsroformer.py +27 -0
- {danceflow_stemlab-1.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/types.py +25 -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.1.2 → danceflow_stemlab-1.3.0}/tests/test_codex_bridge.py +40 -2
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_codex_protocol.py +1 -0
- {danceflow_stemlab-1.1.2 → 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.1.2 → 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.1.2 → danceflow_stemlab-1.3.0}/tests/test_loop_integration.py +7 -2
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_loops.py +63 -1
- 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.1.2 → 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.1.2/plugins/stemlab/.codex-plugin/plugin.json +0 -24
- danceflow_stemlab-1.1.2/src/stemlab/beats/beatthis.py +0 -25
- danceflow_stemlab-1.1.2/src/stemlab/bootstrap.py +0 -133
- danceflow_stemlab-1.1.2/src/stemlab/cli.py +0 -221
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/.agents/plugins/marketplace.json +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/.github/workflows/codex-plugin.yml +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/.github/workflows/release.yml +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/LICENSE +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/docs/codex-plugin.md +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/docs/codex-publishing.md +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/.mcp.json +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/README.md +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/plugins/stemlab/mcp.json +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/build_codex_plugin.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/capture_loop_workflow.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/check_codex_timeline.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/loop_demo.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/prepare_codex_marketplace.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/scripts/publish_mcp_registry.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/setup.cfg +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/dependency_links.txt +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/entry_points.txt +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/danceflow_stemlab.egg-info/top_level.txt +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/__main__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/__init__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/harmony.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/lyrics.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/rhythm.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/semantic_audio.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/semantic_text.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/song_map.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/sonic.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/structure.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/tempo_regimes.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/analysis/transcription.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/audio.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/beats/__init__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/beats/base.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/beats/beattransformer.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/beats/common.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/__init__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/__main__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/paths.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/codex/timeline.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/manifest.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/models.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/__init__.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/base.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/common.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/demucs.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/openunmix.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/separators/scnet.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/server.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/speech.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/util.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/vamp.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/vamp_runtime.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/app.js +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/arcadians-cover.jpg +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/arcadians-reference.json +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/index.html +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/style.css +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/web/timeline.css +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/src/stemlab/webui.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_analysis_registry.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_arcadians_fixture.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_audio_normalization.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_beat_consensus.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_beatnet_compat.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_branding.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_canonical.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_canonical_extended.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_codex_jobs.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_codex_package.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_codex_timeline.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_deep_harmony.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_deep_lyrics.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_deep_sonic_rhythm.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_manifest.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_models.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_repository_hygiene.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_server.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_song_map.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_sonic_visualiser.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_sonic_visualiser_workspace.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_speech_repetition.py +0 -0
- {danceflow_stemlab-1.1.2 → danceflow_stemlab-1.3.0}/tests/test_vamp.py +0 -0
- {danceflow_stemlab-1.1.2 → 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
|
|
|
@@ -285,6 +333,14 @@ stemlab analyze master.wav -o analysis-master --profile practical --export-loops
|
|
|
285
333
|
|
|
286
334
|
# Reuse existing separation, structure and beat results; no models rerun.
|
|
287
335
|
stemlab loops analysis-master --export-loops
|
|
336
|
+
|
|
337
|
+
# Keep all candidates within a chosen short-video edit budget, in seconds.
|
|
338
|
+
stemlab loops analysis-master --max-seconds 30 --per-section 3
|
|
339
|
+
|
|
340
|
+
# Audition possible new cut pairs anywhere in the song, even where the passage
|
|
341
|
+
# does not already repeat. These near-misses are NOT accepted seamless loops.
|
|
342
|
+
stemlab loops analysis-master --mode exploratory --search-scope whole_song \
|
|
343
|
+
--max-seconds 30 --per-section 20 --exploratory-algorithm spectral_context
|
|
288
344
|
```
|
|
289
345
|
|
|
290
346
|
In the existing analysis frontend, choose a highlighted loop region or the Loop
|
|
@@ -297,9 +353,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
297
353
|
|
|
298
354
|

|
|
299
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
|
+
|
|
300
475
|
## Install
|
|
301
476
|
|
|
302
|
-
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.
|
|
303
478
|
|
|
304
479
|
From PyPI, install the released StemLab distribution with:
|
|
305
480
|
|
|
@@ -322,6 +497,18 @@ SCNet and Beat Transformer are research repositories rather than stable pip infe
|
|
|
322
497
|
stemlab bootstrap all
|
|
323
498
|
```
|
|
324
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
|
+
|
|
325
512
|
For only the Vamp analysis stack:
|
|
326
513
|
|
|
327
514
|
```bash
|
|
@@ -431,6 +618,7 @@ endpoints, events and the Arcadians reference workflow.
|
|
|
431
618
|
- [Web service](docs/web.md)
|
|
432
619
|
- [Containers](docs/containers.md)
|
|
433
620
|
- [Publishing and releases](docs/publishing.md)
|
|
621
|
+
- [BeatNet compatibility](docs/beatnet.md)
|
|
434
622
|
- [Changelog](CHANGELOG.md)
|
|
435
623
|
|
|
436
624
|
## Codex plugin and MCP server
|
|
@@ -1,89 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: danceflow-stemlab
|
|
3
|
-
Version: 1.1.2
|
|
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
|
|
|
@@ -285,6 +209,14 @@ stemlab analyze master.wav -o analysis-master --profile practical --export-loops
|
|
|
285
209
|
|
|
286
210
|
# Reuse existing separation, structure and beat results; no models rerun.
|
|
287
211
|
stemlab loops analysis-master --export-loops
|
|
212
|
+
|
|
213
|
+
# Keep all candidates within a chosen short-video edit budget, in seconds.
|
|
214
|
+
stemlab loops analysis-master --max-seconds 30 --per-section 3
|
|
215
|
+
|
|
216
|
+
# Audition possible new cut pairs anywhere in the song, even where the passage
|
|
217
|
+
# does not already repeat. These near-misses are NOT accepted seamless loops.
|
|
218
|
+
stemlab loops analysis-master --mode exploratory --search-scope whole_song \
|
|
219
|
+
--max-seconds 30 --per-section 20 --exploratory-algorithm spectral_context
|
|
288
220
|
```
|
|
289
221
|
|
|
290
222
|
In the existing analysis frontend, choose a highlighted loop region or the Loop
|
|
@@ -297,9 +229,128 @@ sample indexing, thresholds, limitations and reproducible screenshot examples.
|
|
|
297
229
|
|
|
298
230
|

|
|
299
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
|
+
|
|
300
351
|
## Install
|
|
301
352
|
|
|
302
|
-
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.
|
|
303
354
|
|
|
304
355
|
From PyPI, install the released StemLab distribution with:
|
|
305
356
|
|
|
@@ -322,6 +373,18 @@ SCNet and Beat Transformer are research repositories rather than stable pip infe
|
|
|
322
373
|
stemlab bootstrap all
|
|
323
374
|
```
|
|
324
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
|
+
|
|
325
388
|
For only the Vamp analysis stack:
|
|
326
389
|
|
|
327
390
|
```bash
|
|
@@ -431,6 +494,7 @@ endpoints, events and the Arcadians reference workflow.
|
|
|
431
494
|
- [Web service](docs/web.md)
|
|
432
495
|
- [Containers](docs/containers.md)
|
|
433
496
|
- [Publishing and releases](docs/publishing.md)
|
|
497
|
+
- [BeatNet compatibility](docs/beatnet.md)
|
|
434
498
|
- [Changelog](CHANGELOG.md)
|
|
435
499
|
|
|
436
500
|
## Codex plugin and MCP server
|