Feat/library stems midi first class#29
Merged
Merged
Conversation
Stems and MIDI in the library can now be played, favorited, deleted, and
routed anywhere audio goes, instead of only offering a right-click send menu.
- DB schema v5: favorite column on stems + midis; get/set-favorite/delete
methods for both.
- Endpoints: PATCH/DELETE /api/library/stems/{id} and
PATCH/DELETE /api/midi/file/{id} (delete removes the file + row, leaves
the parent track and siblings intact).
- Library STEMS/MIDI rows get inline play/pause, favorite star, and delete;
MIDI right-click now routes to editor/init/inpaint/chimera.
- Shared lib/midiSynth.ts extracts the offline synth voice + WAV encoder
(renderNotesToBlob / renderStepNotesToBlob / renderMidiBufferToBlob);
PianoRoll delegates to it so previews, the editor bounce, and library MIDI
all sound identical. midiIdToSendable() makes any library MIDI a lazy
SendableAudio.
Settings 'Backend Modules' could show a false 'No modules found' when opened during a backend (re)start, because the modal fetched on open and silently blanked on any error. Now the catalog loads once on backend-ready into a shared moduleStore (retry-until-success, cached) and Settings just reads it, so there is nothing to fail on open; a real error shows an error + Retry. Also: - MIDI (Windows): basic-pitch's emoji status output no longer crashes MIDI conversion on cp1252 consoles — its stdout/stderr is captured into a text buffer (engine.py), so transcription failures report the real cause. - Stems sidecar: probe now checks all critical packages (demucs/torch/ torchaudio/torchcrepe), and ensure_running installs deps BEFORE spawning when any are missing instead of letting run_backend.py self-install and burn the 300s readiness window; the timeout error now names the dep state. - Suno API key field is wrapped in a <form> with an associated label and autoComplete=off (silences the 'password field not in a form' warning). - docs: record Phase I (stems/MIDI), G15 (device errors + Quest video-in), and H1/H2 status in the plan.
…ry (G1)
After a generation completes the backend writes artifacts synchronously, but
the library list index can lag that write by a beat — when it did, the entry
wasn't in the just-refreshed list and the track silently failed to appear
('manual reload'). Now the post-generation reconciliation retries the refresh
a few times until the expected <job_id>_<index> id shows up, and on genuine
failure surfaces a visible status message instead of only logging.
Verified the rest of the add-to-library chain end-to-end: the /api/library/
import endpoint (200 + full entry), the frontend contract, importEntry's
in-place store update, and the backend's <job_id>_<index> id scheme all match.
docs: record G15 research findings (Quest video-in without MQDH — scrcpy+OBS
virtual cam Tier 1 needs only a VJ device picker; raw passthrough is Tier 2
via the Unity Passthrough Camera API).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(library): make stems & MIDI first-class]
Stems and MIDI in the library can now be played, favorited, deleted, and
routed anywhere audio goes, instead of only offering a right-click send menu.
methods for both.
PATCH/DELETE /api/midi/file/{id} (delete removes the file + row, leaves
the parent track and siblings intact).
MIDI right-click now routes to editor/init/inpaint/chimera.
(renderNotesToBlob / renderStepNotesToBlob / renderMidiBufferToBlob);
PianoRoll delegates to it so previews, the editor bounce, and library MIDI
all sound identical. midiIdToSendable() makes any library MIDI a lazy
SendableAudio.
fix: module-list reliability, Windows MIDI/stems incidents, Suno a11y
Settings 'Backend Modules' could show a false 'No modules found' when opened
during a backend (re)start, because the modal fetched on open and silently
blanked on any error. Now the catalog loads once on backend-ready into a
shared moduleStore (retry-until-success, cached) and Settings just reads it,
so there is nothing to fail on open; a real error shows an error + Retry.
Also:
conversion on cp1252 consoles — its stdout/stderr is captured into a text
buffer (engine.py), so transcription failures report the real cause.
torchaudio/torchcrepe), and ensure_running installs deps BEFORE spawning
when any are missing instead of letting run_backend.py self-install and burn
the 300s readiness window; the timeout error now names the dep state.
autoComplete=off (silences the 'password field not in a form' warning).
and H1/H2 status in the plan.
fix(generate): reliably surface freshly-generated tracks in the library (G1)
After a generation completes the backend writes artifacts synchronously, but
the library list index can lag that write by a beat — when it did, the entry
wasn't in the just-refreshed list and the track silently failed to appear
('manual reload'). Now the post-generation reconciliation retries the refresh
a few times until the expected <job_id>_ id shows up, and on genuine
failure surfaces a visible status message instead of only logging.
Verified the rest of the add-to-library chain end-to-end: the /api/library/
import endpoint (200 + full entry), the frontend contract, importEntry's
in-place store update, and the backend's <job_id>_ id scheme all match.
docs: record G15 research findings (Quest video-in without MQDH — scrcpy+OBS
virtual cam Tier 1 needs only a VJ device picker; raw passthrough is Tier 2
via the Unity Passthrough Camera API).