MatrixCoder0101 commited on
Commit
c2d5ee4
Β·
1 Parent(s): 41964f0
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. app.py +55 -30
Dockerfile CHANGED
@@ -2,7 +2,7 @@ FROM python:3.9-slim
2
 
3
  WORKDIR /app
4
 
5
- # ffmpeg install karo β€” pydub ke liye zaroori
6
  RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/*
7
 
8
  COPY requirements.txt .
 
2
 
3
  WORKDIR /app
4
 
5
+ # ffmpeg β€” pydub ke liye zaroori
6
  RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/*
7
 
8
  COPY requirements.txt .
app.py CHANGED
@@ -1,49 +1,77 @@
1
- from flask import Flask, request, send_file
 
 
 
 
 
2
  import os
 
 
3
  from gtts import gTTS
4
  from pydub import AudioSegment
 
5
 
6
  app = Flask(__name__)
7
 
8
- BASE_DIR = os.path.dirname(os.path.abspath(__file__))
9
- TMP_DIR = os.path.join(BASE_DIR, "tts_tmp")
10
- os.makedirs(TMP_DIR, exist_ok=True)
11
-
12
 
13
- def text_to_wav(text, lang, wav_path):
14
- mp3_path = os.path.join(TMP_DIR, "temp.mp3")
15
 
16
- # gTTS se MP3
 
 
17
  tts = gTTS(text, lang=lang)
18
- tts.save(mp3_path)
19
- print(f"[gTTS] MP3 ready")
20
 
21
- # pydub se convert β€” 44100Hz, Stereo, 16-bit (original jaisa exactly)
22
- audio = AudioSegment.from_mp3(mp3_path)
23
  audio = audio.set_frame_rate(44100).set_channels(2).set_sample_width(2)
24
- audio.export(wav_path, format="wav")
25
- print(f"[WAV] 44100Hz Stereo 16-bit ready")
26
 
27
- if os.path.exists(mp3_path):
28
- os.remove(mp3_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- return wav_path
 
 
 
 
 
 
31
 
32
 
33
  @app.route("/tts", methods=["GET"])
34
  def tts_get():
35
- text = request.args.get("text", "Hello")
36
  lang = request.args.get("lang", "en")
37
- print(f"\n[TTS] Text: \"{text}\" | Lang: {lang}")
38
-
39
- wav_path = os.path.join(TMP_DIR, "response.wav")
40
  try:
41
- text_to_wav(text, lang, wav_path)
42
  except Exception as e:
43
  print(f"[ERROR] {e}")
44
  return f"Error: {e}", 500
45
-
46
- return send_file(wav_path, mimetype="audio/wav")
47
 
48
 
49
  @app.route("/tts", methods=["POST"])
@@ -51,16 +79,13 @@ def tts_post():
51
  data = request.get_json(silent=True) or {}
52
  text = data.get("text", "Hello")
53
  lang = data.get("lang", "en")
54
- print(f"\n[TTS] Text: \"{text}\" | Lang: {lang}")
55
-
56
- wav_path = os.path.join(TMP_DIR, "response.wav")
57
  try:
58
- text_to_wav(text, lang, wav_path)
59
  except Exception as e:
60
  print(f"[ERROR] {e}")
61
  return f"Error: {e}", 500
62
-
63
- return send_file(wav_path, mimetype="audio/wav")
64
 
65
 
66
  @app.route("/ping")
 
1
+ """
2
+ ESP32 TTS Server β€” Hugging Face Space
3
+ WAV: 44100Hz, Stereo, 16-bit, Normalized + Boosted
4
+ """
5
+
6
+ from flask import Flask, request, Response
7
  import os
8
+ import io
9
+ import hashlib
10
  from gtts import gTTS
11
  from pydub import AudioSegment
12
+ from pydub.effects import normalize
13
 
14
  app = Flask(__name__)
15
 
16
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
17
+ CACHE_DIR = os.path.join(BASE_DIR, "tts_cache")
18
+ os.makedirs(CACHE_DIR, exist_ok=True)
 
19
 
 
 
20
 
21
+ def text_to_wav_bytes(text, lang):
22
+ # Step 1: gTTS β†’ MP3 in memory (no disk write)
23
+ mp3_buf = io.BytesIO()
24
  tts = gTTS(text, lang=lang)
25
+ tts.write_to_fp(mp3_buf)
26
+ mp3_buf.seek(0)
27
 
28
+ # Step 2: Load + convert β€” 44100Hz, Stereo, 16-bit
29
+ audio = AudioSegment.from_file(mp3_buf, format="mp3")
30
  audio = audio.set_frame_rate(44100).set_channels(2).set_sample_width(2)
 
 
31
 
32
+ # Step 3: Normalize β€” consistent volume
33
+ audio = normalize(audio)
34
+
35
+ # Step 4: +3dB boost β€” DAC output thoda weak hota hai
36
+ audio = audio + 3
37
+
38
+ # Step 5: WAV bytes in memory
39
+ wav_buf = io.BytesIO()
40
+ audio.export(wav_buf, format="wav")
41
+ wav_buf.seek(0)
42
+ return wav_buf.read()
43
+
44
+
45
+ def get_wav(text, lang):
46
+ # Cache check β€” same text pe instantly serve
47
+ key = hashlib.md5((text + lang).encode()).hexdigest()
48
+ cache_path = os.path.join(CACHE_DIR, key + ".wav")
49
+
50
+ if os.path.exists(cache_path):
51
+ print(f'[Cache HIT] "{text}"')
52
+ with open(cache_path, "rb") as f:
53
+ return f.read()
54
 
55
+ print(f'[Generating] "{text}" | {lang}')
56
+ wav_data = text_to_wav_bytes(text, lang)
57
+
58
+ with open(cache_path, "wb") as f:
59
+ f.write(wav_data)
60
+
61
+ return wav_data
62
 
63
 
64
  @app.route("/tts", methods=["GET"])
65
  def tts_get():
66
+ text = request.args.get("text", "Hello").replace("+", " ")
67
  lang = request.args.get("lang", "en")
 
 
 
68
  try:
69
+ wav_data = get_wav(text, lang)
70
  except Exception as e:
71
  print(f"[ERROR] {e}")
72
  return f"Error: {e}", 500
73
+ return Response(wav_data, mimetype="audio/wav",
74
+ headers={"Content-Length": str(len(wav_data))})
75
 
76
 
77
  @app.route("/tts", methods=["POST"])
 
79
  data = request.get_json(silent=True) or {}
80
  text = data.get("text", "Hello")
81
  lang = data.get("lang", "en")
 
 
 
82
  try:
83
+ wav_data = get_wav(text, lang)
84
  except Exception as e:
85
  print(f"[ERROR] {e}")
86
  return f"Error: {e}", 500
87
+ return Response(wav_data, mimetype="audio/wav",
88
+ headers={"Content-Length": str(len(wav_data))})
89
 
90
 
91
  @app.route("/ping")