Use real public-domain music loops for the sound bedsβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
d07d1a1
Add four FreePD (Kevin MacLeod, CC0/public-domain) loops as the background
beds β Ambient Drift (Ambient C Motion), Lo-fi Pulse (Chill Beat),
Cinematic Rise (Wonder Flow), Newsroom Bed (Action Investigation) β fetched
via scripts/build_music_loops.py and stored as compact mono FLAC (LFS).
tts/music.py now loads/loops the real track (crossfaded to episode length)
when present and falls back to the procedural numpy bed otherwise. Credits
added to the README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mix procedural background music under the podcastβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
60cefb1
The sound bed was only a label. Add tts/music.py, which synthesizes four
mood beds with numpy (Ambient Drift, Lo-fi Pulse, Cinematic Rise, Newsroom
Bed) β soft sine-pad chords, tremolo, and kick pulses β with no licensing
or asset files. run_tts now mixes the selected bed under the generated
speech at a low level (peak-guarded), and "No music" stays a clean no-op.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add playable voice samples + cap episode length at 2 minβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
310ca13
Voices: source permissively-licensed clips from CMU ARCTIC (fish-speech
ships none), assembled by scripts/build_voice_samples.py into ~20s clips.
The Voices page now renders a gr.Audio player per voice so samples are
audible while browsing. Three clips also back the narrator_warm /
host_energetic / guest_calm presets, so podcast hosts finally sound
distinct instead of all rendering as the default speaker.
UI: cap the Create LENGTH selector at 2 min (default 2) so generation
stays well under the ZeroGPU 300s cap.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve fish-speech root via __path__ (namespace package)β
jayaspjacob+1: Claude Opus 4.8 (1M context)
f3cc6d3
fish_speech is a PEP 420 namespace package on the Space, so __file__ is
None and the previous fallback raised TypeError. Locate the package dir
via __path__[0] (or by walking up setup_root's caller path) and use its
parent as the project root.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix fish-speech project-root crash by wrapping setup_rootβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
57f0925
The earlier find_root patch missed: setup_root lives in the
pyrootutils.pyrootutils submodule and resolves find_root from that
submodule's globals, not the package-level re-export. Wrap the exact
attribute fish_speech calls (pyrootutils.setup_root) so the
FileNotFoundError fallback to the installed package's parent dir is
guaranteed to apply.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add producing/loading screen and fix fish-speech project-root crashβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
310b223
UI: show a full-panel animated loader (orbital spinner + step checklist)
while the script is written and the podcast is produced, swapped in before
the work runs and out when it completes β matches the studio mockup.
TTS: patch pyrootutils.find_root before importing fish_speech inference
modules. A pip-installed fish-speech has no .project-root marker, so its
setup_root() call raised FileNotFoundError; the fallback uses the installed
package's parent dir, which we can't create as a file in root-owned
site-packages at runtime.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add Podify AI podcast generator appβ
jayaspjacob+1: Claude Opus 4.8 (1M context)
623fe6a
Two-phase Gradio app:
- Phase 1: LangGraph research agents (HF Inference LLM + DuckDuckGo) write a script
- Phase 2: Fish Audio OpenAudio S1-mini TTS on ZeroGPU with presets + voice cloning
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>