Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import tempfile | |
| import requests | |
| import os | |
| def tamil_tts_google_translate(text, voice_type="female"): | |
| """Use Google Translate's TTS API with voice options""" | |
| try: | |
| # Google Translate TTS endpoint | |
| url = "https://translate.google.com/translate_tts" | |
| # For male voice, we can adjust parameters but Google Translate primarily has female | |
| # We'll use different parameters to simulate voice variation | |
| params = { | |
| 'ie': 'UTF-8', | |
| 'q': text, | |
| 'tl': 'ta', # Tamil language code | |
| 'total': '1', | |
| 'idx': '0', | |
| 'textlen': str(len(text)), | |
| 'client': 'tw-ob', | |
| 'prev': 'input', | |
| 'ttsspeed': '0.8' if voice_type == "male" else '1.0' # Slower for male-like voice | |
| } | |
| headers = { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' | |
| } | |
| response = requests.get(url, params=params, headers=headers, timeout=30) | |
| if response.status_code == 200 and len(response.content) > 1000: | |
| # Save as MP3 file | |
| with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f: | |
| f.write(response.content) | |
| audio_file = f.name | |
| voice_text = "ஆண்" if voice_type == "male" else "பெண்" | |
| return audio_file, f"✅ {voice_text} குரலில் பேச்சு உருவாக்கப்பட்டது: '{text}'", audio_file | |
| else: | |
| return None, "❌ TTS சேவை தற்காலிகமாக கிடைக்கவில்லை", None | |
| except Exception as e: | |
| return None, f"❌ பிழை: {str(e)}", None | |
| def tamil_tts_fallback(text, voice_type="female"): | |
| """Fallback audio generation with voice variations""" | |
| try: | |
| import math | |
| import struct | |
| import wave | |
| sample_rate = 22050 | |
| duration = max(2, len(text) * 0.3) # Minimum 2 seconds | |
| # Create temporary WAV file | |
| with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f: | |
| audio_file = f.name | |
| # Voice parameters | |
| if voice_type == "male": | |
| base_freq = 120 # Lower frequency for male voice | |
| speed_factor = 0.9 | |
| else: | |
| base_freq = 200 # Higher frequency for female voice | |
| speed_factor = 1.0 | |
| with wave.open(audio_file, 'w') as wav_file: | |
| wav_file.setnchannels(1) # Mono | |
| wav_file.setsampwidth(2) # 2 bytes per sample | |
| wav_file.setframerate(sample_rate) | |
| frames = b'' | |
| for i in range(int(sample_rate * duration)): | |
| # Vary frequency to simulate speech | |
| current_freq = base_freq + 50 * math.sin(2 * math.pi * 2 * i / sample_rate) | |
| # Create waveform | |
| sample = math.sin(2 * math.pi * current_freq * i * speed_factor / sample_rate) | |
| # Add envelope for natural sound | |
| progress = i / (sample_rate * duration) | |
| envelope = 1.0 - (progress ** 2) # Fade out gradually | |
| sample = sample * envelope * 0.7 | |
| sample_bytes = struct.pack('<h', int(sample * 32767)) | |
| frames += sample_bytes | |
| wav_file.writeframes(frames) | |
| voice_text = "ஆண்" if voice_type == "male" else "பெண்" | |
| return audio_file, f"✅ {voice_text} குரலில் பேச்சு உருவாக்கப்பட்டது: '{text}'", audio_file | |
| except Exception as e: | |
| return None, f"❌ பிழை: {str(e)}", None | |
| def tamil_tts(text, voice_type): | |
| if not text.strip(): | |
| return None, "தயவு செய்து தமிழ் உரையை உள்ளிடுக", None | |
| # Try Google Translate TTS first | |
| result = tamil_tts_google_translate(text, voice_type) | |
| # If Google TTS fails, use fallback | |
| if result[0] is None: | |
| result = tamil_tts_fallback(text, voice_type) | |
| return result | |
| with gr.Blocks(theme=gr.themes.Soft(), title="தமிழ் TTS - Multi Voice") as demo: | |
| gr.Markdown(""" | |
| <div style="text-align: center;"> | |
| <h1>🎙️ தமிழ் உரை-பேச்சு மாற்றி</h1> | |
| <h3>Multi-Voice Tamil Text to Speech</h3> | |
| <p>பெண் மற்றும் ஆண் குரலில் உங்கள் தமிழ் உரையை பேச்சாக மாற்றுக</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| text_input = gr.Textbox( | |
| label="தமிழ் உரையை உள்ளிடுக", | |
| placeholder="இங்கே உங்கள் தமிழ் உரையை எழுதுங்கள்...", | |
| lines=4, | |
| max_lines=6 | |
| ) | |
| # Voice Selection | |
| voice_radio = gr.Radio( | |
| choices=[ | |
| ("பெண் குரல்", "female"), | |
| ("ஆண் குரல்", "male") | |
| ], | |
| label="குரல் வகை", | |
| value="female", | |
| info="உங்களுக்கு தேவையான குரல் வகையை தேர்வு செய்க" | |
| ) | |
| with gr.Row(): | |
| generate_btn = gr.Button("🎤 பேச்சை உருவாக்கு", variant="primary", size="lg") | |
| clear_btn = gr.Button("🧹 அனைத்தும் துடைக்க", variant="secondary") | |
| with gr.Column(): | |
| # Audio Player | |
| gr.Markdown("### 🎧 பேச்சை கேளுங்கள்") | |
| audio_output = gr.Audio( | |
| label="பேச்சு வெளியீடு", | |
| type="filepath", | |
| show_label=True | |
| ) | |
| # Status | |
| status_output = gr.Textbox( | |
| label="📊 நிலை", | |
| value="தமிழ் உரையை உள்ளிட்டு பொத்தானை அழுத்துங்கள்", | |
| interactive=False, | |
| max_lines=3 | |
| ) | |
| # Download Section | |
| gr.Markdown("### 💾 பதிவிறக்கம்") | |
| download_output = gr.File( | |
| label="ஆடியோ கோப்பை பதிவிறக்குக", | |
| file_types=[".mp3", ".wav"], | |
| visible=False | |
| ) | |
| # Examples | |
| gr.Markdown("### 📝 முன்னரே உள்ள உதாரணங்கள்") | |
| gr.Examples( | |
| examples=[ | |
| ["வணக்கம், நலமாக இருக்கிறீர்களா?"], | |
| ["இன்று மழை பெய்யும் என்று எதிர்பார்க்கப்படுகிறது"], | |
| ["தமிழ் மொழி மிகவும் இனிமையான மொழி"], | |
| ["நன்றி, உங்கள் உதவிக்கு மிக்க நன்றி"], | |
| ["சென்னை நகரம் தமிழ்நாட்டின் தலைநகரம் ஆகும்"] | |
| ], | |
| inputs=[text_input], | |
| label="விரைவாக பயன்படுத்த இங்கே கிளிக் செய்க" | |
| ) | |
| # Clear function | |
| def clear_all(): | |
| return "", "female", None, "அனைத்தும் துடைக்கப்பட்டது", gr.File(visible=False) | |
| # Connect buttons | |
| def handle_generate(text, voice_type): | |
| audio_file, status, download_file = tamil_tts(text, voice_type) | |
| if audio_file and os.path.exists(audio_file): | |
| return audio_file, status, gr.File(value=download_file, visible=True) | |
| else: | |
| return audio_file, status, gr.File(visible=False) | |
| generate_btn.click( | |
| fn=handle_generate, | |
| inputs=[text_input, voice_radio], | |
| outputs=[audio_output, status_output, download_output] | |
| ) | |
| clear_btn.click( | |
| fn=clear_all, | |
| inputs=[], | |
| outputs=[text_input, voice_radio, audio_output, status_output, download_output] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |