diff --git a/app/play/page.tsx b/app/play/page.tsx index acc9d20..bbcf259 100644 --- a/app/play/page.tsx +++ b/app/play/page.tsx @@ -879,14 +879,17 @@ function PlayInner() { // - BYO (xiaomi): baked voice OR voiceDescription to provision locally. // - Server stepfun: stepfunVoiceId or voiceDescription — no Xiaomi // `voice` needed (saves the ~220KB reference-audio FOT). - // - Server xiaomi / unknown: rely on speaker.voice (the server will - // normalize if provider mismatch — but we still need *something*). + // - Server xiaomi / unknown (probe pending): accept ANY synthesizable + // source. The null case covers the race where getTtsProvider hasn't + // resolved before the first beat fetch fires — without this widening + // a stepfun-only speaker (no Xiaomi voice) would be silently dropped. + // The server resolves + normalizes regardless of which fields arrive. if (byo) { if (!speaker.voice && !speaker.voiceDescription) return; } else if (serverProvider === "stepfun") { if (!speaker.stepfunVoiceId && !speaker.voiceDescription) return; } else { - if (!speaker.voice) return; + if (!speaker.voice && !speaker.stepfunVoiceId && !speaker.voiceDescription) return; } if (beatAudioAbortRef.current.has(beat.id)) return; diff --git a/lib/engine/director.ts b/lib/engine/director.ts index ab997f3..b2a89a1 100644 --- a/lib/engine/director.ts +++ b/lib/engine/director.ts @@ -308,6 +308,9 @@ export async function directScene( // On the StepFun path, thread the LLM-selected stepfunVoiceId from the card // into provision — it lets stepfunProvision honor the catalog pick instead // of falling back to the keyword scorer (same network cost: still zero). + // ALSO persist it onto the Character so the client can echo it back on a + // StepFun server (where it skips the ~220KB voice payload) and the server + // resolveVoice honors the LLM pick at synth time instead of re-scoring. const voicePromises = cards.map((card) => provisionCharacterVoice(config, card.voiceDescription, card.name, { stepfunVoiceId: card.stepfunVoiceId, @@ -316,6 +319,7 @@ export async function directScene( name: card.name, voiceDescription: card.voiceDescription, voice, + stepfunVoiceId: card.stepfunVoiceId, }), ), );