bafifi4972 commited on
Commit
c43dd80
·
verified ·
1 Parent(s): c8591c3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -12
app.py CHANGED
@@ -2,7 +2,7 @@ import os
2
  import io
3
  import traceback
4
  import numpy as np
5
- import soundfile as sf
6
  from fastapi import FastAPI, HTTPException
7
  from fastapi.responses import Response
8
  from pydantic import BaseModel
@@ -11,13 +11,11 @@ import uvicorn
11
 
12
  app = FastAPI(title="Supertonic TTS API")
13
 
14
- # Модели для валидации запросов
15
  class TTSRequest(BaseModel):
16
  text: str
17
  lang: str = "ru"
18
  voice: str = "M2"
19
 
20
- # Глобальная загрузка модели
21
  print("Загрузка модели Supertonic TTS...")
22
  tts = TTS(auto_download=True)
23
  default_style = tts.get_voice_style(voice_name="M2")
@@ -35,37 +33,50 @@ async def root():
35
  @app.post("/api/tts")
36
  async def synthesize(request: TTSRequest):
37
  try:
38
- # Получаем стиль голоса
39
  if request.voice == "M2":
40
  style = default_style
41
  else:
42
  style = tts.get_voice_style(voice_name=request.voice)
43
 
44
- # Синтез
45
  wav, duration = tts.synthesize(request.text, voice_style=style, lang=request.lang)
46
 
47
- # Конвертация тензоров в numpy если нужно
48
  if hasattr(wav, 'cpu'):
49
  wav = wav.cpu().numpy()
50
  elif hasattr(wav, 'numpy'):
51
  wav = wav.numpy()
52
 
53
- wav = np.asarray(wav, dtype=np.float32)
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- # Получаем sample rate
56
  sample_rate = getattr(tts, 'sample_rate', 24000)
57
 
58
- # Записываем в память
59
  out = io.BytesIO()
60
- sf.write(out, wav, samplerate=sample_rate, format='WAV', subtype='PCM_16')
61
  audio_bytes = out.getvalue()
62
 
63
- # Возвращаем аудио
64
  return Response(
65
  content=audio_bytes,
66
  media_type='audio/wav',
67
  headers={
68
- "Content-Disposition": f"attachment; filename=speech.wav",
69
  "X-Audio-Duration": str(round(duration, 2))
70
  }
71
  )
 
2
  import io
3
  import traceback
4
  import numpy as np
5
+ import scipy.io.wavfile as wavfile # Используем scipy вместо soundfile
6
  from fastapi import FastAPI, HTTPException
7
  from fastapi.responses import Response
8
  from pydantic import BaseModel
 
11
 
12
  app = FastAPI(title="Supertonic TTS API")
13
 
 
14
  class TTSRequest(BaseModel):
15
  text: str
16
  lang: str = "ru"
17
  voice: str = "M2"
18
 
 
19
  print("Загрузка модели Supertonic TTS...")
20
  tts = TTS(auto_download=True)
21
  default_style = tts.get_voice_style(voice_name="M2")
 
33
  @app.post("/api/tts")
34
  async def synthesize(request: TTSRequest):
35
  try:
36
+ # 1. Получаем стиль голоса
37
  if request.voice == "M2":
38
  style = default_style
39
  else:
40
  style = tts.get_voice_style(voice_name=request.voice)
41
 
42
+ # 2. Синтез
43
  wav, duration = tts.synthesize(request.text, voice_style=style, lang=request.lang)
44
 
45
+ # 3. Конвертация в numpy (если модель вернула тензор PyTorch)
46
  if hasattr(wav, 'cpu'):
47
  wav = wav.cpu().numpy()
48
  elif hasattr(wav, 'numpy'):
49
  wav = wav.numpy()
50
 
51
+ wav = np.asarray(wav)
52
+
53
+ # 4. Убираем лишние измерения (например, если форма (1, 48000) -> (48000,))
54
+ wav = wav.squeeze()
55
+
56
+ # 5. Нормализация и конвертация в int16 (стандарт для WAV)
57
+ # Сначала приводим к float32 для безопасной нормализации
58
+ wav = wav.astype(np.float32)
59
+ max_val = np.max(np.abs(wav))
60
+ if max_val > 1.0:
61
+ wav = wav / max_val
62
+
63
+ # Конвертируем в int16 (от -32768 до 32767)
64
+ wav_int16 = (wav * 32767).astype(np.int16)
65
 
66
+ # 6. Получаем sample rate
67
  sample_rate = getattr(tts, 'sample_rate', 24000)
68
 
69
+ # 7. Записываем в память через scipy (работает безотказно)
70
  out = io.BytesIO()
71
+ wavfile.write(out, sample_rate, wav_int16)
72
  audio_bytes = out.getvalue()
73
 
74
+ # 8. Возвращаем аудио
75
  return Response(
76
  content=audio_bytes,
77
  media_type='audio/wav',
78
  headers={
79
+ "Content-Disposition": "attachment; filename=speech.wav",
80
  "X-Audio-Duration": str(round(duration, 2))
81
  }
82
  )