minhahwang Copilot commited on
Commit
2b743ed
Β·
1 Parent(s): 3cfcf98

fix: voice cloning playback - add status indicator, fallback, debug logging

Browse files

- Show 'PLAYING β€” Cloned Voice' or 'PLAYING β€” Stock Voice' in status bar
- Add fallback: if cloned synthesis fails, automatically use stock voice
- Add logging to stream_tts to confirm profile_id is received

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Files changed (2) hide show
  1. app.py +6 -2
  2. tts.py +22 -6
app.py CHANGED
@@ -872,10 +872,14 @@ with gr.Blocks(title="MomsVoice", css=css_code) as demo:
872
 
873
  # 5. Play button β€” streams TTS audio chunk by chunk
874
  def stream_tts(tts_chunks, paras, profile_id):
875
- _status_playing = """
 
 
 
 
876
  <div style="margin-top: 12px; display: flex; align-items: center; gap: 10px; justify-content: center;">
877
  <span style="width: 8px; height: 8px; border-radius: 50%; background: #4ade80; display: inline-block;"></span>
878
- <span style="font-size: 11px; color: #4ade80; font-family: monospace;">PLAYING</span>
879
  </div>
880
  """
881
  _status_done = """
 
872
 
873
  # 5. Play button β€” streams TTS audio chunk by chunk
874
  def stream_tts(tts_chunks, paras, profile_id):
875
+ import logging as _log
876
+ _log.getLogger(__name__).info("stream_tts called with profile_id=%s", profile_id)
877
+
878
+ voice_mode = "πŸŽ™οΈ Cloned Voice" if profile_id else "πŸ”Š Stock Voice"
879
+ _status_playing = f"""
880
  <div style="margin-top: 12px; display: flex; align-items: center; gap: 10px; justify-content: center;">
881
  <span style="width: 8px; height: 8px; border-radius: 50%; background: #4ade80; display: inline-block;"></span>
882
+ <span style="font-size: 11px; color: #4ade80; font-family: monospace;">PLAYING β€” {voice_mode}</span>
883
  </div>
884
  """
885
  _status_done = """
tts.py CHANGED
@@ -60,17 +60,33 @@ def generate_audio_stream(
60
 
61
 
62
  def _start_qwen_worker(chunks, profile_id, chunk_q):
63
- """Background thread: synthesize chunks with Qwen3-TTS voice clone (Base 1.7B)."""
 
64
  def _worker():
65
- from voice_clone import synthesize_cloned
 
66
  for i, stmt in enumerate(chunks):
67
  try:
68
- wav, _sr = synthesize_cloned(stmt, profile_id)
 
 
 
69
  chunk_q.put((i, wav, None))
70
  except Exception as exc:
71
- logger.exception("Qwen3-TTS synthesis failed on chunk %d", i)
72
- chunk_q.put((i, None, str(exc)))
73
- return
 
 
 
 
 
 
 
 
 
 
 
74
  chunk_q.put(_SENTINEL)
75
 
76
  threading.Thread(target=_worker, daemon=True).start()
 
60
 
61
 
62
  def _start_qwen_worker(chunks, profile_id, chunk_q):
63
+ """Background thread: synthesize chunks with Qwen3-TTS voice clone (Base 1.7B).
64
+ Falls back to stock voice if cloned synthesis fails."""
65
  def _worker():
66
+ from voice_clone import synthesize_cloned, synthesize_custom_voice
67
+ use_fallback = False
68
  for i, stmt in enumerate(chunks):
69
  try:
70
+ if use_fallback:
71
+ wav, _sr = synthesize_custom_voice(stmt)
72
+ else:
73
+ wav, _sr = synthesize_cloned(stmt, profile_id)
74
  chunk_q.put((i, wav, None))
75
  except Exception as exc:
76
+ if not use_fallback:
77
+ logger.warning("Cloned voice failed (chunk %d): %s β€” falling back to stock voice", i, exc)
78
+ use_fallback = True
79
+ try:
80
+ wav, _sr = synthesize_custom_voice(stmt)
81
+ chunk_q.put((i, wav, None))
82
+ except Exception as exc2:
83
+ logger.exception("Stock voice also failed on chunk %d", i)
84
+ chunk_q.put((i, None, str(exc2)))
85
+ return
86
+ else:
87
+ logger.exception("Stock voice synthesis failed on chunk %d", i)
88
+ chunk_q.put((i, None, str(exc)))
89
+ return
90
  chunk_q.put(_SENTINEL)
91
 
92
  threading.Thread(target=_worker, daemon=True).start()