🎙️ हिंदी Text-to-Speech Studio
Premium Hindi speech synthesis powered by AI
import gradio as gr import torch import numpy as np import scipy.io.wavfile import tempfile import os from transformers import VitsModel, AutoTokenizer from gtts import gTTS # ============================================================ # 🎙️ Hindi Text-to-Speech Studio # Two Models: Meta MMS-TTS + Google TTS # ============================================================ # --- Global Model Loading (loaded once at startup) --- print("🔮 Loading Meta MMS-TTS Hindi model...") mms_model = VitsModel.from_pretrained("facebook/mms-tts-hin") mms_tokenizer = AutoTokenizer.from_pretrained("facebook/mms-tts-hin") print("✅ Meta MMS-TTS Hindi loaded successfully!") def generate_mms_tts(text, speed=1.0): """Generate speech using Facebook MMS-TTS Hindi (VITS model)""" if not text or not text.strip(): raise gr.Error("⚠️ कृपया कुछ हिंदी टेक्स्ट दर्ज करें! (Please enter some Hindi text!)") try: inputs = mms_tokenizer(text.strip(), return_tensors="pt") with torch.no_grad(): # Set speaking rate mms_model.speaking_rate = speed output = mms_model(**inputs) waveform = output.waveform.float().numpy().squeeze() sample_rate = mms_model.config.sampling_rate # Normalize audio if np.max(np.abs(waveform)) > 0: waveform = waveform / np.max(np.abs(waveform)) * 0.95 # Save to temp file tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False) scipy.io.wavfile.write(tmp.name, rate=sample_rate, data=waveform) return tmp.name except Exception as e: raise gr.Error(f"❌ MMS-TTS Error: {str(e)}") def generate_google_tts(text, slow=False): """Generate speech using Google TTS Hindi""" if not text or not text.strip(): raise gr.Error("⚠️ कृपया कुछ हिंदी टेक्स्ट दर्ज करें! (Please enter some Hindi text!)") try: tts = gTTS(text=text.strip(), lang='hi', slow=slow) tmp = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) tts.save(tmp.name) return tmp.name except Exception as e: raise gr.Error(f"❌ Google TTS Error: {str(e)}") def generate_both(text, mms_speed, google_slow): """Generate speech from both models for comparison""" if not text or not text.strip(): raise gr.Error("⚠️ कृपया कुछ हिंदी टेक्स्ट दर्ज करें! (Please enter some Hindi text!)") mms_audio = generate_mms_tts(text, mms_speed) google_audio = generate_google_tts(text, google_slow) return mms_audio, google_audio # ============================================================ # 🎨 Custom CSS for Premium UI # ============================================================ custom_css = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Noto+Sans+Devanagari:wght@300;400;500;600;700&display=swap'); * { font-family: 'Inter', 'Noto Sans Devanagari', sans-serif !important; } .gradio-container { max-width: 1100px !important; margin: 0 auto !important; background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%) !important; min-height: 100vh; } .main-header { text-align: center; padding: 2rem 1rem; background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(59, 130, 246, 0.1)); border-radius: 20px; border: 1px solid rgba(139, 92, 246, 0.2); margin-bottom: 1.5rem; backdrop-filter: blur(10px); } .main-header h1 { font-size: 2.5rem !important; font-weight: 800 !important; background: linear-gradient(135deg, #a78bfa, #818cf8, #60a5fa) !important; -webkit-background-clip: text !important; -webkit-text-fill-color: transparent !important; background-clip: text !important; margin-bottom: 0.5rem !important; letter-spacing: -0.02em; } .main-header p { color: #a5b4fc !important; font-size: 1.1rem !important; font-weight: 400; opacity: 0.9; } .model-badge { display: inline-block; padding: 0.3rem 0.8rem; border-radius: 20px; font-size: 0.8rem; font-weight: 600; margin: 0.2rem; } .badge-meta { background: linear-gradient(135deg, #7c3aed, #6d28d9); color: white; } .badge-google { background: linear-gradient(135deg, #2563eb, #1d4ed8); color: white; } /* Tab Styling */ .tab-nav { background: rgba(30, 27, 75, 0.6) !important; border-radius: 16px !important; padding: 0.4rem !important; border: 1px solid rgba(139, 92, 246, 0.2) !important; } .tab-nav button { border-radius: 12px !important; font-weight: 600 !important; padding: 0.8rem 1.5rem !important; transition: all 0.3s ease !important; color: #a5b4fc !important; font-size: 0.95rem !important; } .tab-nav button.selected { background: linear-gradient(135deg, #7c3aed, #6d28d9) !important; color: white !important; box-shadow: 0 4px 15px rgba(124, 58, 237, 0.4) !important; } /* Input/Output Containers */ .gr-block, .gr-box, .gr-panel { background: rgba(30, 27, 75, 0.5) !important; border: 1px solid rgba(139, 92, 246, 0.15) !important; border-radius: 16px !important; backdrop-filter: blur(10px) !important; } /* Textbox */ textarea, input[type="text"] { background: rgba(15, 12, 41, 0.7) !important; border: 1px solid rgba(139, 92, 246, 0.3) !important; border-radius: 12px !important; color: #e0e7ff !important; font-size: 1.05rem !important; padding: 1rem !important; transition: all 0.3s ease !important; } textarea:focus, input[type="text"]:focus { border-color: #8b5cf6 !important; box-shadow: 0 0 20px rgba(139, 92, 246, 0.2) !important; } /* Buttons */ .gr-button-primary { background: linear-gradient(135deg, #7c3aed, #6d28d9, #5b21b6) !important; border: none !important; border-radius: 12px !important; padding: 0.8rem 2rem !important; font-weight: 700 !important; font-size: 1rem !important; color: white !important; box-shadow: 0 4px 15px rgba(124, 58, 237, 0.4) !important; transition: all 0.3s ease !important; text-transform: uppercase; letter-spacing: 0.05em; } .gr-button-primary:hover { transform: translateY(-2px) !important; box-shadow: 0 8px 25px rgba(124, 58, 237, 0.5) !important; } /* Slider */ input[type="range"] { accent-color: #8b5cf6 !important; } /* Labels */ label { color: #c4b5fd !important; font-weight: 600 !important; font-size: 0.9rem !important; } /* Audio Players */ audio { border-radius: 12px !important; width: 100% !important; } /* Checkbox */ input[type="checkbox"] { accent-color: #8b5cf6 !important; } /* Examples */ .gr-examples { background: rgba(30, 27, 75, 0.3) !important; border-radius: 16px !important; padding: 1rem !important; } /* Footer */ .footer-info { text-align: center; padding: 1.5rem; color: #6366f1; font-size: 0.85rem; opacity: 0.7; } /* Scrollbar */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: rgba(15, 12, 41, 0.3); } ::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.4); border-radius: 3px; } /* Animations */ @keyframes pulse-glow { 0%, 100% { box-shadow: 0 0 20px rgba(139, 92, 246, 0.2); } 50% { box-shadow: 0 0 40px rgba(139, 92, 246, 0.4); } } .generating { animation: pulse-glow 2s ease-in-out infinite; } """ # ============================================================ # 🏗️ Build the Gradio App # ============================================================ # Example Hindi texts example_texts = [ "नमस्ते! आज का मौसम बहुत सुहावना है। चलिए बाहर घूमने चलते हैं।", "भारत एक विविधताओं से भरा देश है। यहाँ अनेक भाषाएँ, संस्कृतियाँ और परंपराएँ हैं।", "कृत्रिम बुद्धिमत्ता का क्षेत्र तेजी से विकसित हो रहा है और यह हमारे जीवन को बदल रहा है।", "हिमालय की ऊँची चोटियों से लेकर कन्याकुमारी के समुद्र तट तक, भारत अपनी प्राकृतिक सुंदरता के लिए प्रसिद्ध है।", "शिक्षा सबसे शक्तिशाली हथियार है जिसका उपयोग आप दुनिया को बदलने के लिए कर सकते हैं।", "प्रौद्योगिकी ने संचार को आसान बना दिया है। अब हम दुनिया के किसी भी कोने से जुड़ सकते हैं।", ] with gr.Blocks(css=custom_css, title="🎙️ Hindi Text-to-Speech Studio", theme=gr.themes.Base()) as demo: # Header gr.HTML("""
Premium Hindi speech synthesis powered by AI
Facebook's Massively Multilingual Speech — Neural TTS using VITS architecture. Fast, lightweight, and produces natural-sounding Hindi speech.
Google Text-to-Speech — Production-grade TTS engine. Delivers clear, natural Hindi speech with professional voice quality.
Side-by-Side Comparison — Enter text once and hear how both models synthesize it. Compare quality, naturalness, and pronunciation.
🔮 Meta MMS-TTS
') compare_mms_output = gr.Audio( label="Meta MMS-TTS Output", type="filepath", elem_id="compare-mms-output" ) with gr.Column(): gr.HTML('🌐 Google TTS
') compare_google_output = gr.Audio( label="Google TTS Output", type="filepath", elem_id="compare-google-output" ) gr.Examples( examples=[[text, 1.0, False] for text in example_texts[:4]], inputs=[compare_text, compare_mms_speed, compare_google_slow], label="📌 Try These Examples" ) compare_btn.click( fn=generate_both, inputs=[compare_text, compare_mms_speed, compare_google_slow], outputs=[compare_mms_output, compare_google_output], api_name="compare_both" ) # Footer gr.HTML(""" """) # Launch if __name__ == "__main__": demo.launch()