Spaces:
Paused
Paused
File size: 2,714 Bytes
c2d5ee4 c1f680b c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 c1f680b c2d5ee4 41964f0 c2d5ee4 c1f680b c2d5ee4 41964f0 c2d5ee4 41964f0 c1f680b c2d5ee4 41964f0 c2d5ee4 c1f680b c2d5ee4 c1f680b c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 c2d5ee4 41964f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | """
ESP32 TTS Server — Hugging Face Space
WAV output: 22050Hz, Mono, 8-bit unsigned
ESP32 DAC ke liye perfect — direct mapping, no conversion
"""
from flask import Flask, request, Response
import os
import io
import hashlib
from gtts import gTTS
from pydub import AudioSegment
from pydub.effects import normalize
app = Flask(__name__)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CACHE_DIR = os.path.join(BASE_DIR, "tts_cache")
os.makedirs(CACHE_DIR, exist_ok=True)
def text_to_wav_bytes(text, lang):
# Step 1: gTTS → MP3 in memory
mp3_buf = io.BytesIO()
tts = gTTS(text, lang=lang)
tts.write_to_fp(mp3_buf)
mp3_buf.seek(0)
# Step 2: Load audio
audio = AudioSegment.from_file(mp3_buf, format="mp3")
# Step 3: Normalize — consistent volume
audio = normalize(audio)
# Step 4: Convert — 22050Hz, Mono, 8-bit unsigned
# ESP32 DAC = 8-bit (0-255), 22050Hz enough for clear voice
audio = audio.set_frame_rate(22050)
audio = audio.set_channels(1)
audio = audio.set_sample_width(1) # 8-bit unsigned (0-255)
# Step 5: WAV bytes
wav_buf = io.BytesIO()
audio.export(wav_buf, format="wav")
wav_buf.seek(0)
return wav_buf.read()
def get_wav(text, lang):
key = hashlib.md5((text + lang).encode()).hexdigest()
cache_path = os.path.join(CACHE_DIR, key + ".wav")
if os.path.exists(cache_path):
print(f'[Cache HIT] "{text}"')
with open(cache_path, "rb") as f:
return f.read()
print(f'[Generating] "{text}" | {lang}')
wav_data = text_to_wav_bytes(text, lang)
with open(cache_path, "wb") as f:
f.write(wav_data)
return wav_data
@app.route("/tts", methods=["GET"])
def tts_get():
text = request.args.get("text", "Hello").replace("+", " ")
lang = request.args.get("lang", "en")
try:
wav_data = get_wav(text, lang)
except Exception as e:
print(f"[ERROR] {e}")
return f"Error: {e}", 500
return Response(wav_data, mimetype="audio/wav",
headers={"Content-Length": str(len(wav_data))})
@app.route("/tts", methods=["POST"])
def tts_post():
data = request.get_json(silent=True) or {}
text = data.get("text", "Hello")
lang = data.get("lang", "en")
try:
wav_data = get_wav(text, lang)
except Exception as e:
print(f"[ERROR] {e}")
return f"Error: {e}", 500
return Response(wav_data, mimetype="audio/wav",
headers={"Content-Length": str(len(wav_data))})
@app.route("/ping")
def ping():
return {"status": "ok", "server": "ESP32 TTS Server"}
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False)
|