Spaces:
Running on Zero
Running on Zero
Commit History
-
Update README.md Running
Verified signature8680767 -
Update README.md
Verified signature4143dc0
-
Add hackathon submission tags
Verified signature99213d6 -
Pre-submission cleanup: remove scratch files, fix internal comments
- Delete all local .bak* files, _*.py scratch runners, lab_out/, .claude/, .pytest_cache/, demo_clip.wav, planning docs, and session artifacts - .gitignore: add .claude/, .pytest_cache/, _*.py patterns - app.py: strip internal build-instruction comments that leaked into the CSS string and JS block; remove first-person attribution ('Tony wants', 'Tony's call') from inline comments - README.md: commit the hackathon-ready version (comprehensive, accurate)9aeb323 -
Fix resubmit/state-reset bug: fresh output on first click
A finished run left its player, summary and seam ribbon mounted. On the next upload or re-click the stale result lingered and the new output often needed several clicks to appear, with visible jank in between. - analyze_on_upload now resets the result panel (player=None, summary, seam, stage) on a new clip, via 4 added trailing outputs, so a fresh upload can never show the previous run's output. - finish_song clears the player/summary/seam on its first yield, so the reveal is a clean None -> new-file transition that forces WaveSurfer to reload instead of keeping the prior take's waveform mounted (this is the 'needs multiple clicks' fix). - Hero spectrum: tear down the previous Web Audio graph (disconnect the old MediaElementSource + analyser) on each new track so nodes don't accumulate across resubmits; coalesce the MutationObserver to one sync per animation frame so WaveSurfer repaints + stage animations stop thrashing EQ.sync hundreds of times/sec (the 'glitchy' fe…3ef2e8b -
Keep the hero spectrum reactive across pause/play cycles (+ seek-safe)
The shadow-audio FFT bars reacted on the first play but went dead after a pause->play. Root cause: .coda-eq-live (which kills the .coda-eq-playing keyframe so JS inline scaleY shows) was added only once, gated behind the EQ.confirmed flag. On stop() the decay removed the class; on the next play EQ.confirmed was still latched true, so the loop never re-added it and the CSS keyframe overrode every inline transform -- frozen bars. - EQ.start: re-arm EQ.confirmed=false each play session so 1st/2nd/Nth play all re-detect energy and re-take ownership of the bars. - EQ.loop: re-assert .coda-eq-live every confirmed frame (idempotent) so a prior stop()'s removal can never strand a later play. - EQ.sync: wake the silent shadow if it stalled (ended / browser-paused after a scrub past its buffered edge) while the player is still playing, alongside the existing timestamp drift-resync -- makes seeking/scrubbing self-healing. Only app.py touched; pipeline contract untouched.d63fbaf -
Give the processing overlay room to breathe (fix cramped 'composing' stage)
The live processing stage (spinner + label + sub-line + step rail) was crushed together and the spinner itself was collapsing to ~30px. Fixes: - The overlay is position:absolute, so it can't size its own card; during processing the card now gets min-height:380px (released the instant the result lands, with a smooth transition) so there is real vertical room. - Spinner core was a flex item with default shrink and rendered ~30px tall; pin it with flex:0 0 96px so the rings draw at full size. - Replace the uniform 14px flex gap with an intentional rhythm: 42/34 padding, 30px under the spinner, label+sub kept tight as a pair (11px), 32px down to the step rail; hide an empty sub-line so it never leaves a phantom gap.c2ff332 -
Audio-reactive hero: real FFT via shadow <audio>, + in-body JS bootstrap
Two changes that together make the 48 hero bars actually dance with the finished track on the deployed Space. Engine: Gradio's WaveSurfer here plays from a decoded buffer through its own Web Audio graph - its <audio> element never loads (readyState 0, no src), so there is no media element to tap and a play()-wrap never fires. Instead we drive the bars from a SILENT shadow <audio> of the same file URL, wired MediaElementSource -> AnalyserNode but NOT connected to destination, started/stopped and position-synced in lockstep with WaveSurfer. We hold the CSS-energized look until the analyser delivers real energy, then JS owns the bars (mirrored center=lows/edges=highs, snappy attack + soft release) and glides them back to idle on stop. Web Audio unavailable / autoplay blocked / cross-origin taint all fall back to CSS cleanly. Delivery: head= injection is dropped entirely on the Space (verified live - none of the module's symbols reach the page), so the whole front-end module never ran th…7b2436e -
Make the hero spectrum dance with the actual audio (Web Audio AnalyserNode)
The 48 hero EQ bars used to freeze the moment the finished track played - the CSS only energized them off the play button's label. Now they react to the real audio: when any CODA player starts we tap its element with a MediaElementSource + AnalyserNode and paint each bar from getByteFrequencyData() every frame. - Wrap HTMLMediaElement.play/pause so we capture WaveSurfer's DETACHED <audio> element (no DOM parent, so querySelector/closest/capture listeners miss it); the wrap runs in the click stack so the AudioContext resumes under a gesture. - Mirrored mapping: center bars track the lows, edges the highs, scaled within each bar's existing height so the centered silhouette is preserved. - On pause/stop the bars glide back to idle and hand control to the CSS breathing animation; reduced-motion and wiring failures fall back to the CSS-only look. Also folds in the working-tree intro/head fixes: the 2016 story is baked on with an inline onclick close fallback, and head=HEAD_SCRIPT …474be08 -
Fix result-panel UI: accurate seam ribbon, full waveform, instant readout, intro replays
- Seam 'needle' was drifting/stuck: it measured WaveSurfer's waveform in the browser. Replace with a self-contained before/after ribbon rendered server-side (YOUR PART | CODA split + join), so the marker is always exactly at src/total. - Output waveform was clipped (~15px bleeding into the timestamps): give the waveform container real height (min 90px, centered) so it shows in full. - 'CODA heard' sat greyed until generation on slow hosts: make analyze_on_upload stream a 'listening...' state the instant a clip lands, then the key/tempo readout. - Intro only played on first load (localStorage gate): remove the gate so the 2016 intro replays on every page load. - Polish: easing/transition refinements, lighter front-end (dropped the fragile seam-overlay JS and its observers).5eef7f2 -
Add three flagship experiences: onboarding, seam reveal, live hero
- Cinematic onboarding: a short, skippable opening that tells the Track0000 story (2016 -> quit at the bridge -> finished) before the tool, gated by localStorage with a 'replay intro' link. - Before/after seam reveal: on a finished track, a gold seam marker with 'YOUR PART | CODA' split labels shows exactly where the original ends and CODA's continuation begins (positioned from source_seconds/total, which finish_song now surfaces as a hidden data carrier — no pipeline change). - Play-energized hero: the spectrum comes alive (faster, taller, brighter) whenever the player is playing. On-load JS runs via a gr.Blocks(head=...) bootstrap script: this Gradio build drops js-only app.load() handlers and does not auto-run gr.Blocks(js=...), so neither fired. NOTE: true live-FFT reactivity is not possible here — Gradio's WaveSurfer exposes no tappable media element — so the hero energizes on the player's play/pause state instead. Engine pipeline, hidden length mirror, autoplay-off,…8694d13 -
Swap demo to Track0000 — my own unfinished song from 2016
Replace the placeholder demo clip with Track0000, the song I recorded in 2016 and never finished — the exact kind of clip CODA exists to finish, and the emotional core of the project. Update the demo button + footer to tell that story; remove the old placeholder. Bundled via Git LFS.45a4784 -
Ship the bundled PUSHBACK demo clip (via Git LFS)
The demo audio matched '*.mp3' in .gitignore, so it was never committed or deployed — 'Try the demo' had no file on the Space, which surfaced as a cascade of 403 / cache-move / split errors that all traced back to a missing file. Track *.mp3 with LFS (HF rejects plain binaries) and add the clip so the demo loads. Pairs with the load_demo temp-copy + allowed_paths.491b8c9 -
Fix demo load: copy bundled clip to a temp file for Gradio cache
allowed_paths got past the 403, but Gradio 6 then refused to move the bundled examples/pushback_demo.mp3 into its cache ('not uploaded by a user'). Copy it to a per-request temp dir first so Gradio caches and serves it like a normal upload, so 'Try the demo' loads and analyzes.9a6056f -
Fix 'Try the demo' on the Space: allow serving the bundled clip
On HF Spaces, Gradio 6 returns 403 for gradio_api/file=…/examples/ pushback_demo.mp3 unless its directory is in allowed_paths, so clicking 'Try the demo' failed to load the clip (and a downstream frontend error blocked the fingerprint readout). Add the examples dir to launch(allowed_paths).418300b -
Make CODA a premium audio instrument with a 4-beat journey
Turn the UI into a milled-metal studio instrument with a cyan->violet->gold narrative arc across four emotional beats: - OPEN: faceplates rise on expo-out easing as milled panels (bevel lip + recessed body + contact drop); the spectrum powers on from flat; the Finish key sits visibly disarmed. - UPLOAD: the fingerprint readout renders as a backlit-LCD HUD that powers on (scanline sweep + per-cell settle) and the Finish key ignites. - PROCESS: a generator yields a live stage overlay at the real pipeline milestones (listening/composing/splicing) with counter-rotating rings, dancing bars, and a violet active-step stepper that holds the GPU wait. - REVEAL: the result deck escalates to a gold MASTER (gold bevel, head, play control, and mono spec-plate summary chips). Every module is custom-styled away from default Gradio: recessed upload channel, milled fader with a lit knurled thumb, carved vibe field, backlit remaster toggle, illuminated key states, integrated player decks. …f66f37b -
Redesign UI: ethereal dark-studio theme for CODA
Replace the generic Gradio look with a premium, high-end interface: - Animated aurora background, cursor-reactive glow, and drifting particles - Frosted-glass panels (backdrop-blur) with soft elevation and rise-in motion - Gradient 'CODA' wordmark in Space Grotesk with a flowing shimmer - 48-bar animated frequency spectrum under the hero - Gradient, glowing primary button with tactile hover and disabled states - Softened the result player's empty state into an on-brand panel UI-only: engine pipeline, event wiring, the hidden length-mirror field, and the no-autoplay output player are all unchanged.9c6b4bb -
Fix resubmit UI bugs: persist length across runs, drop autoplay
Two bugs made later runs look broken: - the length slider could snap back to its 30s minimum on a 2nd+ submit, so the next run generated a tiny tail that 'sounded like the original'. The length is now held in a hidden Number written only from the slider's change/release, so it survives a frontend slider reset -- and, unlike a gr.State, stays settable through the API. - the output autoplay player could fail to reload its src on the 2nd+ generation, so a finished run looked like 'nothing played'. Drop autoplay; a plain player reliably loads each new result. Verified locally end-to-end: the API still sets the length (45/90/110s produce matching output) and the output player has no autoplay.3f7cbfd -
Harden best-of-N selection: reject dropouts and squashed takes
The selection metric only scored loud-bursts and whole-tail silence, so two failure modes that sound bad to a listener slipped through as clean: - a brief mid-tail near-silent dropout (overall RMS stays high and max/median stays low, so neither existing term fires) - an audible cut-out; - dynamics/transient collapse - a perfectly tonal but squashed, attack-less wash that low-flatness and loudness checks all green-light. Add a sustained-dropout term and a crest-factor (peak/RMS) floor to the score, raise the candidate pool to 5 and tighten early-accept to 3.5 so best-of-N keeps searching past a merely-okay draw for a genuinely good one. Generation is unchanged; only which draw is selected. Adds unit tests for all four failure modes plus the natural-ending-taper false-positive guard.1cca94c -
Autoplay the finished song; remove temporary diagnostics
The finished track now autoplays the instant generation completes, so the result is unmistakable instead of a silent, ready-but-unpressed player. The ZeroGPU (H200) continuation is verified clean end-to-end - generation, splice and WAV delivery all produce a healthy 44.1 kHz stereo track - so the temporary diagnostic instrumentation has served its purpose and is removed.21ec938 -
Add temporary ZeroGPU diagnostic instrumentation
Log the @spaces.GPU fork's torch/CUDA/arch (to settle whether the GPU is H200 sm_90 or Blackwell sm_120) and the full mathematical QA signature of each generated tail (burst_ratio, n_bursts_4x, clip_frac, spectral flatness, hf_frac, crest). The 'loud random synth noise' artifact cannot be reproduced locally even on the exact Space torch (2.8.0+cu128) on Blackwell, so this captures ground truth from the live Space logs to verify the H200 fp16 fix against the clean local baseline. Logging-only, no uploads; removed once confirmed.7a93620 -
Fix H200 fp16 instability: pin MATH SDPA, fp32 autoencoder, no TF32
The continuation sounds clean on local Blackwell (sm_120) but produced sporadic loud bursts on ZeroGPU's H200 (sm_90). Root cause is fp16 numerical instability on H200, not a torch version. - Pin F.scaled_dot_product_attention to the MATH (reference) backend around generation. SA3's transformer calls SDPA with no backend pin and casts q/k/v to fp16; on H200 torch 2.8+ can route that to a cuDNN/ mem-efficient kernel with known fp16 NaN/garbage bugs (the loud-burst signature). flash-attn is absent in this image, so SDPA is the live path and the pin engages. - Run the autoencoder (Oobleck/DAC, Snake1d) in fp32 while the DiT stays fp16. Snake's x + (1/(b+1e-9))*sin(a*x)^2 can exceed fp16's 65504 ceiling -> inf/NaN -> broadband noise on decode. sampling.py casts latents to the pretransform dtype before decode, so an fp32 pretransform upcasts the whole encode+decode path with no library change. The inpaint lead is cast to the pretransform dtype to match. - Disable TF32 m…fea5b3c -
Fix ZeroGPU audio quality and stuck-processing UI
Quality: stop pinning seed=7. That seed reproduced the verified lab take on torch 2.7.1, but ZeroGPU runs torch 2.8-2.11, where the same seed is just an arbitrary (bad) draw -- the 'sporadic loud random synth noise' take. engine.continue_audio now draws best-of-N candidates and keeps the cleanest by a blind artifact score that rejects both loud random bursts and silence collapse. Early-accept + an 85s wall-clock budget keep it inside the 120s GPU window. Stay at the distilled 8-step pingpong regime (bumping steps adds artifacts, not quality). UI: collapse the finish_btn .then chain into a single event so one completion signal clears the spinner -- the chained second event could hang the 'processing' state if the SSE stream blipped (ClientDisconnect). Build the summary markdown visible (empty) instead of toggling it. Queue one job at a time and launch with show_error so a real failure surfaces in the UI instead of a silently stuck spinner.dd34fe0 -
Restore the verified-good whole-buffer normalization
The bounded-lead fix alone resolves the deployed near-silence (the model was generating actual zeros into a tiny masked window, not getting scaled down). The earlier switch to per-tail normalization was an unneeded change to the working path, so revert it to the original whole-buffer peak-normalize. Proven on the Blackwell GPU: for the verified seed=7 demo->60 case the new engine now produces BYTE-IDENTICAL output to the pre-change engine (max abs diff 0.0), while the long-source case (100s->120) still generates non-silent audio (rms 0.13, was 0.001).c9f44d7 -
Fix ZeroGPU continuation: bound the lead-in, normalize the tail, shrink the GPU window
Three deployed bugs, all reproduced on the Blackwell GPU and fixed: 1. Near-silence / "only 5s of new audio". A long source (e.g. 100s) filled SA3's buffer and left only a tiny masked window, which the 8-step distilled sampler rendered as near-silence (rms 0.001). engine now conditions on at most MAX_LEAD_SECONDS (30s) of the clip's TAIL and masks [lead, lead+new], keeping the generated region substantial. The splice still rejoins the tail onto the full pristine original, so the listener hears the whole clip. Verified: 100s->120 now yields rms 0.15 (was 0.001). 2. Length/mask. With the whole source in the buffer, "total < source" floored to source+5s. With a bounded lead, new = total - source actually extends to the requested finished length (100s->120 generates +20s). 3. Stream abort (BodyStreamBuffer was aborted). enhance/fingerprint/decode ran INSIDE @spaces.GPU, burning the ZeroGPU window before generation started. Only the diffusion call is now wra…e033515 -
Authenticate to the HF Hub with HF_TOKEN before loading gated SA3 weights
stabilityai/stable-audio-3-small-music is gated under the Stability Community License, so get_pretrained_model 401s on the Space unless the request is authenticated. Call huggingface_hub.login(token=HF_TOKEN) at startup, before preload() pulls the weights. Guarded so it is a no-op locally (where huggingface-cli login already provides credentials), and logs a clear warning on a Space when the secret is missing.5067511 -
Revert to gradio SDK with runtime --no-deps SA3 install for ZeroGPU
ZeroGPU is only available on the gradio SDK, not Docker, so the Docker approach is a dead end. Go back to sdk: gradio and keep stable-audio-tools out of requirements.txt entirely (its pyproject hard-pins torch==2.7.1, which ZeroGPU rejects). Instead app.py installs it at import time with pip --no-cache-dir --no-deps, so the ZeroGPU-managed torch is used and SA3's torch pin is never resolved. requirements.txt supplies all of SA3's non-torch dependencies up front. - README front-matter: sdk docker -> gradio (restore sdk_version/app_file) - Remove Dockerfile - app.py: add --no-cache-dir to the runtime SA3 install1881421 -
Switch Space to Docker SDK to bypass stable-audio-tools torch pin
stable-audio-tools hard-pins torch==2.7.1 in its pyproject.toml, which ZeroGPU rejects (it accepts only 2.8.0/2.9.1/2.10.0/2.11.0), so the gradio-SDK build fails resolving the dependency tree. Move to sdk: docker with a Dockerfile that installs a ZeroGPU-compatible torch (2.8.0+cu124) plus all of SA3's non-torch deps from requirements.txt, then installs stable-audio-tools with --no-deps so its torch pin is never resolved. app.py keeps a runtime --no-deps install as a fallback (a no-op once the image bakes it in). - Dockerfile: python:3.10-slim, ffmpeg/libsndfile1/git, UID 1000, port 7860 - README front-matter: sdk gradio -> docker, app_port 7860bd0ded8
-
Fix torch pin for ZeroGPU: 2.7.1+cu128 → 2.8.0+cu124
ZeroGPU only accepts torch 2.8.0, 2.9.1, 2.10.0, or 2.11.0; 2.7.1 was rejected at Space build time. Bump to 2.8.0 (lowest supported) on cu124 wheels, which cover the H200 (sm_90) and are available for this version.4ad6bf7 -
Pin the continuation seed so the app reproduces the verified take
SA3 is generative: app.py called continue_audio with the default seed (-1), drawing a fresh random seed every run, so each continuation differed and most were weaker than the lab take Tony approved. The verified lab_out/sa3 renders were produced by lab_e2e.py with seed=7; pin the same seed in the app's generation call so the deliverable reproduces that result instead of re-rolling. No audio-pipeline parameters changed.a45d149 -
Rebuild CODA on Stable Audio 3 Small Music
Replace the MusicGen multi-pass chaining with SA3's native audio inpainting: one diffusion call continues the clip into a finished 44.1kHz stereo track, deleting the windowed passes, energy guards and re-roll logic entirely. - engine.py: SA3 continuation core. preload() to CPU at boot, fp16 on GPU inside the @spaces.GPU window; inpaint mask = [source_end, total]; source clip cast to model dtype; Windows-safe seed; over-long clips rejected so the mask can't invert. - stitch.py: stereo-native splice. Loudness-match, short equal-power crossfade at the seam, cos^2 closing fade, peak guard, all at 44.1k. - verify.py: dev-only math QA — duration, silence-collapse, clipping, seam/loudness/tempo/key continuity, spectral rolloff, stereo width, with a dark diagnostic plot. - app.py: dark "DAW console" UI. Total-length slider (30-120s), optional vibe prompt, instant on-upload analysis, staged progress, output player built visible. Over-long uploads blocked with a clear message. -…e8b2f06 -
Rebuild CODA around a working continuation engine; strip the scope creep
The product had drifted into a six-stage pipeline (lyric transcription with Whisper, lyric continuation with Qwen3-8B, vinyl-sleeve posters, liner notes) wrapped in a 1685-line app, and the one thing it was supposed to do — return a listenable continuation — didn't: the generated audio decayed into near-silent "ghost noise" a few seconds in. Root cause found by probing the engine on the demo clip: MusicGen drifts toward silence when prompted with a quiet lo-fi clip (rms ~0.06). Fix is to RMS-normalize every prompt to a confident level (0.12) before the model sees it — back-half energy went from tail/head 0.28 to 0.63, the spectral centroid of the continuation snapped to the original's (3528Hz -> 2288Hz vs 2197Hz), and the generated region reads as tonal music (spectral flatness 0.0002, harmonic fraction 0.92). Verified end-to-end through the UI on a real GPU. Engine (continue_music.py): - normalize the prompt to PROMPT_TARGET_RMS in every pass; anchor the energy guard to that level…aed07b7
-
Mount the handoff player reliably: build it visible inside the hidden result group (gradio 6 drops visible=False audio components that a later update tries to show)
13580de -
Trim editor-local entries out of the tracked gitignore
bd738fb -
Tests track the window-safe planner; add energy-guard + re-roll coverage; pin transformers to the GPU-verified 4.57.6
10a5d89 -
Real music out: window-safe passes, stem-sum prompt, level anchor + session console
The continuation is now verified end-to-end on a local GPU (lab in local_lab.py / lab_spec.py, A/B results below). Root causes of the ghost-noise output, in order of damage: - musicgen-small collapses to near-silence on dense lo-fi prompts (one pass measured at 0.03x prompt level). Ship musicgen-medium: A/B rolls came back as dense or denser than large at half the latency. - prompt + new tokens overflowing the trained 30s window (20s prompt + 18s new) extrapolates the positional embeddings: clipping, tempo drift. The planner now fits every pass inside the window (20s first prompt + 10s new, then 12s ctx + 18s new) and drops sub-3s remainders. - the vocal gate prompted with mix-minus-vocals, which keeps the demucs residual (tape hiss, phasey vocal ghosts) in the prompt, and the model continues the noise. Prompt with the sum of the non-vocal stems. - unconditional generation level-drifts and chained passes compound it: every chunk is now rms-anchored to the user's clip (…03b5ec1 -
Fix: instant visual feedback when "Finish this song" is clicked
Before this change the button appeared unresponsive for 20-30s: no state change, no timeline, nothing — the first yield only fired after librosa finished loading the file and ZeroGPU allocated a slot. Changes: - Yield an immediate "warming up…" frame at the very start of run_pipeline, before librosa.load or any GPU work, so the browser reacts in milliseconds - Disable the button ("Processing…") on that first yield; re-enable it at every exit point (success, audio-gen error, poster error, no-input error) - Add continue_btn to the click outputs so Gradio can update its state - Add show_progress="minimal" to the click handler for Gradio's progress bar - Add CSS :disabled rule so the greyed-out button is visually obvious66609d5 -
Remove mp3 from git, will upload via CLI
265c133 -
Switch from LFS to Xet for mp3
71e1eaf -
Track mp3 with LFS
79f2254 -
PUSHBACK demo preset + lo-fi input enhancement (hears the song, not the noise)
- examples/pushback_demo.mp3: bundled sample clip by the band PUSHBACK (sourced from TikTok), credited in the preset label, share caption, liner notes, in-app about section, and README. Explicitly NOT presented as the user's music: the credit threads through run_pipeline -> generate_words -> write_liner_notes and share_caption so every artifact attributes the band. gitignore exception added. - enhance.py: input enhancement for lo-fi recordings (voice memos, phone recordings, mp3 rips) - 35Hz high-pass, per-band spectral noise gate learned from the quietest frames, peak normalize. Length- and shape-preserving (the sample-aligned crossfade depends on it), and it falls back to the raw input on any failure. Verified: noise floor cut 4.6x on a synthetic hiss+rumble test. - the cleaned copy now feeds analysis AND musicgen's audio prompt, so the model imitates the music instead of the compression; the user's raw original still goes into the final track. master_match re…f3537fe -
The handoff, liner notes, share caption, and the craft story
Creative-director round: make the claim falsifiable and give every track a written artifact. - "The handoff": a ten-second snippet cut around the splice (five seconds of you, five of coda) served under the finished song with the challenge "can you hear the seam?" - the product's entire claim, testable in one listen - Liner notes: qwen3 writes back-of-sleeve liner notes for EVERY track in the same GPU window (write_lyrics.write_liner_notes). Instrumental clips - including the demo-clip path every judge takes - previously ended with two skipped stages; now they leave with prose. Stage 5 relabels to "writing the liner notes" for instrumentals. - Share caption: feed-ready post text with a copy button under the poster ("I quit this song in 2018. CODA finished it today - eight years later." + stack line + #BuildSmall2026) - "how coda listens" accordion: the research story in-app (guidance amplifies text not audio, the demucs gate, the mastering splice) - "name your song"…da998cc -
UI elevation: live waveform painting, streaming lyrics, vinyl poster v2
The pipeline now performs for the user instead of making them wait: - continue_music.py: optional progress callback (default None, zero behavior change) emitting ("separating") and per-pass ("pass", i, n, audio) events - app.py: ZeroGPU generator streaming end to end. The planned song renders as cream bars + a ghost skeleton, and paints in amber pass by pass with a pulsing leading edge ("pass 2 of 3 - 36s written"). Six- stage timeline tracker (check marks, ring pulse, skip/error states, aria-live). The finished track autoplays the moment it is stitched. Lyrics render as a serif lyric sheet and the continuation types itself in as qwen3 streams (TextIteratorStreamer). Poster lands last with a dealt-card animation. Friendly error copy (no stack traces), amber- themed sliders/players (primary_hue + WaveformOptions), header equalizer, mobile breakpoints, html-escaped user content. - demo_clip.py: synthesized unfinished lofi loop (Am, 92bpm, cuts off mid-phrase) gen…359e1db -
Full pipeline overhaul: lyrics, poster, meter detection, staged UI
- analyze.py: time-signature estimation (beat-accent grid scoring, 4/4 bias), single-decode fingerprint() - stems.py: shared in-process HT-Demucs vocal isolation - transcribe.py: drop torchaudio/torchcodec path and demucs subprocess; demucs-isolated vocals -> whisper large-v3 long-form (chunked), with a hallucination filter on the output - write_lyrics.py: qwen3 thinking mode off, think/scaffold scrubbing, recommended non-thinking sampling (t=0.7, top_p=0.8, top_k=20) - poster.py: vinyl-sleeve 1080x1080 poster with two-tone waveform (original cream / continuation amber), started+finished dates, key/bpm/meter, "completed by CODA" branding; upload waveform renderer - app.py: wire the whole pipeline behind one button with a streamed 4-stage progress tracker; mastering+stitch moved off the GPU window; separate ZeroGPU calls for music (300s) and lyrics (180s); waveform panel, meter card, lyrics panels, poster output, original-date input; gradio 6 Image buttons API; flatt…ddef6a2
-
Pure audio continuation: drop text pull, add vocal gate + mastering pass
Implements the fixes from RESEARCH_music_continuation_2026-06-10.md. Root cause of the "weird funk pop" output: guidance_scale only amplifies the TEXT condition in transformers' MusicGen CFG (the audio prompt is copied into both branches and cancels out), and our meta-instruction caption was out-of-distribution noise that regressed to the stock-music prior - at 7x amplification. - guidance_scale 7.0 -> 1.0 default (CFG off); deleted the "identical instruments..." meta-instruction and the SECTION_ARC / _section_plan song-arc hints. Pure audio-conditioned continuation (no text) is the canonical mode. - Optional "describe your song" caption box in the UI replaces the inverted "style adherence" slider; a real user caption runs at Meta's trained guidance 3.0 with detected key/bpm appended. - Demucs vocal gate: MusicGen's training data had vocals stripped, so if the tail carries vocal energy (stem/mix rms > 0.1) the prompt is swapped for the HT-Demucs instrumental (mix minus v…9bf6d71
-
Max out audio context (20s prompt), equal-gain seam, generate() logging
NOTE: the previous two fixes never reached the Space — origin is the HF Space repo and the commits were intentionally unpushed, so testing kept hitting the original deployed code (hardcoded 15s generation = the persistent "14 seconds"). Deploying requires a push. - audio prompt 15s -> 20s, the maximum MusicGen's hard 30s decoder window allows while leaving 10s of generation per pass; clips shorter than 20s are used in full as the prompt - seam blend switched from equal-power to equal-gain (linear): the blended signals are time-aligned copies of the same content, and equal-power curves swell up to +3dB on correlated material — the audible volume bump/tonal shift at the splice. equal-gain keeps level dead flat (regression test: 0.999 level ratio through the blend) - default blend lengthened 3s -> 6s (UI slider 2-10s) so the handoff from original to model audio is gradual and completes before new material starts: one unified track, not original + crossfade + AI - guidance…6f68d75 -
Fix generic "8-bit" output: fp32 conditioning, 15s audio prompt, song-arc structure
Root cause of the chiptune sound: the whole model ran in fp16. MusicGen's text encoder is T5, which is numerically unstable in fp16 (garbage/NaN conditioning), and the EnCodec audio tokenizer audibly degrades in half precision -- the audio prompt codes carried almost no timbre information, so the model fell back to generic text-driven synth output. audiocraft's reference implementation keeps EnCodec in fp32 for this exact reason. - run the model in fp32 with TF32 matmuls (drop the fp16 input_values cast) - lengthen the audio prompt from 10s to 15s so the model hears enough of the clip's instrumentation and production to match it - raise guidance_scale 3 -> 6 (UI slider 3-10, "style adherence") and make the text prompt reinforce the audio condition ("identical instruments, identical timbre, same production") instead of describing a style - per-pass section hints (verse/chorus/bridge -> outro) so long extensions arc like a finished song; final pass always resolves and ends the t…f1cce7f -
Fix music continuation: chained 60s+ generation, native-rate stitching, seamless crossfade
- chain multiple MusicGen passes (each re-prompted with the last 10s of accumulated output) so extensions aren't capped at one ~15s window; default 60s, UI slider 15-120s - never downsample the original: keep it at native sample rate, channels, and bit depth (PCM_16/PCM_24 matched to input); resample the 32kHz generated audio UP with soxr_hq before stitching - crossfade inside MusicGen's re-encoded prompt region so the equal-power fade (2-5s, default 3s) completes exactly where new material begins -- the handoff into generated content happens entirely within model audio - RMS-match the generation to the original over the shared prompt region - condition the text prompt on detected key/BPM ("same instruments, same style") - add offline regression test for chaining and stitch math3fb00f7 -
Fix footer year: Build Small 2026
1877ee4 -
Fix torchcodec crash, gradio 6 launch args, and polish UI
- continue_music: load audio with librosa instead of torchaudio.load; torchaudio 2.9+ delegates decoding to torchcodec, which is not installed on the Space ("TorchCodec is required" crash on continue) - app: move theme/css from gr.Blocks() to launch() per gradio 6 - app: restyle - near-black palette with gold accent, Inter + Instrument Serif type, refined panels/cards/buttons54a9a2d