andevs commited on
Commit
b02eaf8
·
verified ·
1 Parent(s): 77bfa1d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -104
app.py CHANGED
@@ -232,7 +232,7 @@ def synthesize(text, reference_audio, language="en", speed=1.0, progress=gr.Prog
232
  if "list index out of range" in error or "index out of range" in error:
233
  raise gr.Error(
234
  "Voice extraction failed.\n\n"
235
- "✅ SOLUTION: Use microphone recording:\n"
236
  "1. Click the microphone icon\n"
237
  "2. Record 6-10 seconds clearly\n"
238
  "3. Say: 'Hello, this is my test voice'\n"
@@ -335,16 +335,16 @@ def clear_cache():
335
  _tts = None
336
  if torch.cuda.is_available():
337
  torch.cuda.empty_cache()
338
- return "✅ Cache cleared"
339
 
340
  def get_status():
341
  if _tts is not None:
342
- return "✅ Model ready (GPU)" if torch.cuda.is_available() else "✅ Model ready (CPU)"
343
  elif _model_loading:
344
- return "⏳ Loading model..."
345
  elif _model_error:
346
- return f"❌ Error"
347
- return "🔄 Ready - first use loads model"
348
 
349
  def estimate_duration(text, speed=1.0):
350
  if not text:
@@ -356,73 +356,57 @@ def estimate_duration(text, speed=1.0):
356
  return f"{mins}m {secs}s" if mins > 0 else f"{secs}s"
357
 
358
  # ============================================================
359
- # UI - COMPLETE WITH ALL FEATURES
360
  # ============================================================
361
 
362
- with gr.Blocks(title="VoxForge TTS", theme=gr.themes.Soft(), css=".gradio-container {max-width: 1200px !important; margin: auto !important;}") as demo:
363
 
364
  gr.Markdown("# 🎙️ VoxForge TTS - Professional Voice Cloning")
365
- gr.Markdown("**Upload any voice or use microphone** to record 6-10 seconds. First use downloads model (2-5 min).")
366
 
367
  with gr.Tabs():
368
 
369
- # ========================================================
370
- # TAB 1: STANDARD SYNTHESIS
371
- # ========================================================
372
- with gr.Tab("🎤 Standard Synthesis"):
373
  with gr.Row():
374
  with gr.Column(scale=1):
375
- text_input = gr.Textbox(
376
- label="Text to Synthesize",
377
- lines=6,
378
- max_length=2000,
379
- placeholder="Enter text up to 2000 characters...\n\nExample: Hello, this is my cloned voice speaking naturally."
380
- )
381
 
382
  with gr.Row():
383
  char_count = gr.Label("0/2000")
384
  duration_est = gr.Label("Est. 0s")
385
 
386
- ref_audio = gr.Audio(
387
- label="Reference Voice (6-10 seconds - Click microphone to record!)",
388
- type="filepath",
389
- sources=["upload", "microphone"]
390
- )
391
 
392
  with gr.Row():
393
  language = gr.Dropdown(choices=SUPPORTED_LANGUAGES, value="en", label="Language")
394
  speed = gr.Slider(0.5, 2.0, value=1.0, step=0.05, label="Speed")
395
 
396
  with gr.Row():
397
- gen_btn = gr.Button("🎵 Generate Speech", variant="primary", size="lg")
398
- clear_btn = gr.Button("🗑️ Clear", variant="secondary", size="lg")
399
 
400
- with gr.Accordion("⚙️ Advanced", open=False):
401
  status_text = gr.Label(get_status())
402
  clear_cache_btn = gr.Button("Clear Model Cache", size="sm")
403
- clear_output = gr.Textbox(visible=False)
404
 
405
  with gr.Column(scale=1):
406
- audio_output = gr.Audio(label="🔊 Generated Speech", type="filepath")
407
 
408
- gr.Markdown("""
409
- ### ⭐ Tips for Best Results
410
-
411
- 1. **Use microphone** (click the mic icon) - records perfectly every time!
412
- 2. **Speak clearly** for 6-10 seconds
413
- 3. **No background noise** - one speaker only
414
- 4. **Match language** to your voice
415
-
416
- ### 🚀 Speed Tips
417
- - First synthesis: 2-5 min (downloads 4GB model)
418
- - After that: 10-30 seconds
419
- - Enable GPU in Space settings for faster results
420
-
421
- ### 🌐 Supported Languages
422
- English, Spanish, French, German, Italian, Portuguese, Polish, Turkish, Russian, Dutch, Czech, Arabic, Chinese, Japanese
423
- """)
424
 
425
- # Event handlers
426
  def update_char(t):
427
  return f"{len(t)}/2000" if t else "0/2000"
428
 
@@ -435,77 +419,75 @@ with gr.Blocks(title="VoxForge TTS", theme=gr.themes.Soft(), css=".gradio-contai
435
 
436
  gen_btn.click(synthesize, [text_input, ref_audio, language, speed], [audio_output])
437
  clear_btn.click(lambda: ("", None, "en", 1.0), None, [text_input, ref_audio, language, speed])
438
- clear_cache_btn.click(clear_cache, None, [clear_output]).then(lambda: get_status(), None, [status_text])
439
 
440
- # ========================================================
441
- # TAB 2: BATCH SYNTHESIS
442
- # ========================================================
443
- with gr.Tab("📚 Batch (Long Text)"):
444
- gr.Markdown("### 🔄 For texts over 2000 characters")
445
  gr.Markdown("Automatically splits into chunks and combines audio.")
446
 
447
  with gr.Row():
448
  with gr.Column(scale=1):
449
- long_text = gr.Textbox(
450
- label="Long Text",
451
- lines=12,
452
- max_length=10000,
453
- placeholder="Paste long text here (up to 10000 characters)..."
454
- )
455
  chunk_slider = gr.Slider(300, 800, value=500, step=50, label="Chunk Size (characters)")
456
  batch_audio = gr.Audio(label="Reference Voice", type="filepath", sources=["upload", "microphone"])
457
  with gr.Row():
458
  batch_lang = gr.Dropdown(choices=SUPPORTED_LANGUAGES, value="en", label="Language")
459
  batch_speed = gr.Slider(0.5, 2.0, value=1.0, step=0.05, label="Speed")
460
- batch_btn = gr.Button("🎵 Generate Long Speech", variant="primary", size="lg")
461
  with gr.Column(scale=1):
462
  batch_output = gr.Audio(label="Generated Speech (Combined)", type="filepath")
463
 
464
- gr.Markdown("""
465
- ### ℹ️ Batch Mode Info
466
- - Splits at sentence boundaries (., !, ?)
467
- - Synthesizes each chunk separately
468
- - Combines all chunks into one file
469
- - Best for audiobooks, presentations, long narrations
470
- """)
471
 
472
  batch_btn.click(batch_synthesize, [long_text, batch_audio, batch_lang, batch_speed, chunk_slider], [batch_output])
473
 
474
- # ========================================================
475
- # TAB 3: HELP & TROUBLESHOOTING
476
- # ========================================================
477
- with gr.Tab("❓ Help"):
478
- gr.Markdown("""
479
- # 📖 Help Guide
480
-
481
- ## ✅ Quick Start
482
-
483
- 1. **Record your voice** (click microphone icon, say 6-10 seconds)
484
- 2. **Type text** you want to synthesize
485
- 3. **Click Generate** - works in 10-30 seconds
486
-
487
- ## 🔧 Troubleshooting
488
-
489
- ### "Index out of range" / Voice extraction fails
490
- - **Use microphone recording** - this works 100% of the time
491
- - Uploaded files must be short (6-10 seconds), WAV format, clean speech
492
-
493
- ### First use is slow
494
- - Normal! Downloads 4GB model (2-5 minutes)
495
- - Subsequent uses are fast (10-30 seconds)
496
- - Enable GPU in Space settings for faster performance
497
-
498
- ### Improve quality
499
- - Use 8-10 second recording
500
- - No background noise
501
- - One speaker only
502
- - Speak clearly at normal pace
503
-
504
- ## 🔄 Converting your existing audio
505
-
506
- ```bash
507
- # Extract best 10 seconds from long audio
508
- ffmpeg -i long_audio.mp3 -t 10 -ac 1 -ar 22050 short.wav
509
-
510
- # Remove silence
511
- ffmpeg -i input.wav -af silenceremove=1:0:-50dB output.wav
 
 
 
 
 
 
 
 
232
  if "list index out of range" in error or "index out of range" in error:
233
  raise gr.Error(
234
  "Voice extraction failed.\n\n"
235
+ "SOLUTION: Use microphone recording:\n"
236
  "1. Click the microphone icon\n"
237
  "2. Record 6-10 seconds clearly\n"
238
  "3. Say: 'Hello, this is my test voice'\n"
 
335
  _tts = None
336
  if torch.cuda.is_available():
337
  torch.cuda.empty_cache()
338
+ return "Cache cleared"
339
 
340
  def get_status():
341
  if _tts is not None:
342
+ return "Model ready (GPU)" if torch.cuda.is_available() else "Model ready (CPU)"
343
  elif _model_loading:
344
+ return "Loading model..."
345
  elif _model_error:
346
+ return "Error"
347
+ return "Ready - model loads on first use"
348
 
349
  def estimate_duration(text, speed=1.0):
350
  if not text:
 
356
  return f"{mins}m {secs}s" if mins > 0 else f"{secs}s"
357
 
358
  # ============================================================
359
+ # UI - NO TRIPLE QUOTES
360
  # ============================================================
361
 
362
+ with gr.Blocks(title="VoxForge TTS", theme=gr.themes.Soft()) as demo:
363
 
364
  gr.Markdown("# 🎙️ VoxForge TTS - Professional Voice Cloning")
365
+ gr.Markdown("Upload any voice or use microphone to record 6-10 seconds. First use downloads model (2-5 min).")
366
 
367
  with gr.Tabs():
368
 
369
+ # TAB 1: Standard Synthesis
370
+ with gr.Tab("Standard Synthesis"):
 
 
371
  with gr.Row():
372
  with gr.Column(scale=1):
373
+ text_input = gr.Textbox(label="Text to Synthesize", lines=6, max_length=2000, placeholder="Enter text up to 2000 characters... Example: Hello, this is my cloned voice.")
 
 
 
 
 
374
 
375
  with gr.Row():
376
  char_count = gr.Label("0/2000")
377
  duration_est = gr.Label("Est. 0s")
378
 
379
+ ref_audio = gr.Audio(label="Reference Voice (6-10 seconds - Click microphone to record!)", type="filepath", sources=["upload", "microphone"])
 
 
 
 
380
 
381
  with gr.Row():
382
  language = gr.Dropdown(choices=SUPPORTED_LANGUAGES, value="en", label="Language")
383
  speed = gr.Slider(0.5, 2.0, value=1.0, step=0.05, label="Speed")
384
 
385
  with gr.Row():
386
+ gen_btn = gr.Button("Generate Speech", variant="primary", size="lg")
387
+ clear_btn = gr.Button("Clear", variant="secondary", size="lg")
388
 
389
+ with gr.Accordion("Advanced Options", open=False):
390
  status_text = gr.Label(get_status())
391
  clear_cache_btn = gr.Button("Clear Model Cache", size="sm")
 
392
 
393
  with gr.Column(scale=1):
394
+ audio_output = gr.Audio(label="Generated Speech", type="filepath")
395
 
396
+ gr.Markdown("### Tips for Best Results")
397
+ gr.Markdown("1. Use microphone (click the mic icon) - records perfectly every time!")
398
+ gr.Markdown("2. Speak clearly for 6-10 seconds")
399
+ gr.Markdown("3. No background noise - one speaker only")
400
+ gr.Markdown("4. Match language to your voice")
401
+ gr.Markdown("")
402
+ gr.Markdown("### Performance Notes")
403
+ gr.Markdown("- First synthesis: 2-5 min (downloads 4GB model)")
404
+ gr.Markdown("- After that: 10-30 seconds")
405
+ gr.Markdown("- Enable GPU in Space settings for faster results")
406
+ gr.Markdown("")
407
+ gr.Markdown("### Supported Languages")
408
+ gr.Markdown("English, Spanish, French, German, Italian, Portuguese, Polish, Turkish, Russian, Dutch, Czech, Arabic, Chinese, Japanese")
 
 
 
409
 
 
410
  def update_char(t):
411
  return f"{len(t)}/2000" if t else "0/2000"
412
 
 
419
 
420
  gen_btn.click(synthesize, [text_input, ref_audio, language, speed], [audio_output])
421
  clear_btn.click(lambda: ("", None, "en", 1.0), None, [text_input, ref_audio, language, speed])
422
+ clear_cache_btn.click(clear_cache, None, [status_text]).then(lambda: get_status(), None, [status_text])
423
 
424
+ # TAB 2: Batch Synthesis
425
+ with gr.Tab("Batch (Long Text)"):
426
+ gr.Markdown("### For texts over 2000 characters")
 
 
427
  gr.Markdown("Automatically splits into chunks and combines audio.")
428
 
429
  with gr.Row():
430
  with gr.Column(scale=1):
431
+ long_text = gr.Textbox(label="Long Text", lines=12, max_length=10000, placeholder="Paste long text here (up to 10000 characters)...")
 
 
 
 
 
432
  chunk_slider = gr.Slider(300, 800, value=500, step=50, label="Chunk Size (characters)")
433
  batch_audio = gr.Audio(label="Reference Voice", type="filepath", sources=["upload", "microphone"])
434
  with gr.Row():
435
  batch_lang = gr.Dropdown(choices=SUPPORTED_LANGUAGES, value="en", label="Language")
436
  batch_speed = gr.Slider(0.5, 2.0, value=1.0, step=0.05, label="Speed")
437
+ batch_btn = gr.Button("Generate Long Speech", variant="primary", size="lg")
438
  with gr.Column(scale=1):
439
  batch_output = gr.Audio(label="Generated Speech (Combined)", type="filepath")
440
 
441
+ gr.Markdown("### Batch Mode Info")
442
+ gr.Markdown("- Splits at sentence boundaries (., !, ?)")
443
+ gr.Markdown("- Synthesizes each chunk separately")
444
+ gr.Markdown("- Combines all chunks into one file")
445
+ gr.Markdown("- Best for audiobooks, presentations, long narrations")
 
 
446
 
447
  batch_btn.click(batch_synthesize, [long_text, batch_audio, batch_lang, batch_speed, chunk_slider], [batch_output])
448
 
449
+ # TAB 3: Help
450
+ with gr.Tab("Help & Troubleshooting"):
451
+ gr.Markdown("# Help Guide")
452
+ gr.Markdown("")
453
+ gr.Markdown("## Quick Start")
454
+ gr.Markdown("")
455
+ gr.Markdown("1. Record your voice (click microphone icon, say 6-10 seconds)")
456
+ gr.Markdown("2. Type text you want to synthesize")
457
+ gr.Markdown("3. Click Generate - works in 10-30 seconds")
458
+ gr.Markdown("")
459
+ gr.Markdown("## Troubleshooting")
460
+ gr.Markdown("")
461
+ gr.Markdown("### Voice extraction fails")
462
+ gr.Markdown("- Use microphone recording - this works 100% of the time")
463
+ gr.Markdown("- Uploaded files must be short (6-10 seconds), WAV format, clean speech")
464
+ gr.Markdown("")
465
+ gr.Markdown("### First use is slow")
466
+ gr.Markdown("- Normal! Downloads 4GB model (2-5 minutes)")
467
+ gr.Markdown("- Subsequent uses are fast (10-30 seconds)")
468
+ gr.Markdown("- Enable GPU in Space settings for faster performance")
469
+ gr.Markdown("")
470
+ gr.Markdown("### Improve quality")
471
+ gr.Markdown("- Use 8-10 second recording")
472
+ gr.Markdown("- No background noise")
473
+ gr.Markdown("- One speaker only")
474
+ gr.Markdown("- Speak clearly at normal pace")
475
+ gr.Markdown("")
476
+ gr.Markdown("## Converting your existing audio")
477
+ gr.Markdown("")
478
+ gr.Markdown("```bash")
479
+ gr.Markdown("# Extract best 10 seconds from long audio")
480
+ gr.Markdown("ffmpeg -i long_audio.mp3 -t 10 -ac 1 -ar 22050 short.wav")
481
+ gr.Markdown("# Remove silence")
482
+ gr.Markdown("ffmpeg -i input.wav -af silenceremove=1:0:-50dB output.wav")
483
+ gr.Markdown("```")
484
+ gr.Markdown("")
485
+ gr.Markdown("## Need more help?")
486
+ gr.Markdown("Check container logs in Space Settings.")
487
+
488
+ if __name__ == "__main__":
489
+ demo.launch(
490
+ server_name="0.0.0.0",
491
+ server_port=int(os.environ.get("PORT", 7860)),
492
+ show_error=True
493
+ )