| 1 | from fastapi import FastAPI, Request |
| 2 | from fastapi.responses import FileResponse |
| 3 | import uvicorn |
| 4 | import torch |
| 5 | import soundfile |
| 6 | import ChatTTS |
| 7 | import json |
| 8 | import os |
| 9 | |
| 10 | app = FastAPI() |
| 11 | ROOT = "/Path to/TTS" |
| 12 | |
| 13 | torch._dynamo.config.cache_size_limit = 64 |
| 14 | torch._dynamo.config.suppress_errors = True |
| 15 | torch.set_float32_matmul_precision('high') |
| 16 | |
| 17 | chat = ChatTTS.Chat() |
| 18 | # compile=True works well, but is slower |
| 19 | chat.load_models(source='custom', custom_path=os.path.join(ROOT, "model/ChatTTS"), compile=False) |
| 20 | |
| 21 | |
| 22 | spk = {"male": [], "female": []} |
| 23 | male_path = os.path.join(ROOT, "spk/male") |
| 24 | for file in os.listdir(male_path): |
| 25 | t = torch.load(os.path.join(male_path, file)) |
| 26 | spk['male'].append(t) |
| 27 | female_path = os.path.join(ROOT, "spk/female") |
| 28 | for file in os.listdir(female_path): |
| 29 | t = torch.load(os.path.join(female_path, file)) |
| 30 | spk['female'].append(t) |
| 31 | |
| 32 | |
| 33 | def cretae_new_path(path, filetype): |
| 34 | if not os.path.exists(path): |
| 35 | os.makedirs(path) |
| 36 | files = os.listdir(path) |
| 37 | if len(files) == 0: |
| 38 | return os.path.join(path, f'0.{filetype}') |
| 39 | else: |
| 40 | max = 0 |
| 41 | for file in files: |
| 42 | max = max if max>=int(os.path.splitext(file)[0]) else int(os.path.splitext(file)[0]) |
| 43 | return os.path.join(path, str(max+1) + f'.{filetype}') |
| 44 | |
| 45 | |
| 46 | |
| 47 | @app.post("/") |
| 48 | async def AudioGenerate(request: Request): |
| 49 | params = await request.json() |
| 50 | speaker = spk[params['gender']][params['id']] |
| 51 | |
| 52 | params_refine_text = params['params_refine_text'] |
| 53 | params_infer_code = params['params_infer_code'] |
| 54 | params_infer_code['spk_emb'] = speaker |
| 55 | |
| 56 | print("text: ", params['text']) |
| 57 | wavs = chat.infer(params['text'], |
| 58 | # do_text_normalization=True, |
| 59 | skip_refine_text=True, |
| 60 | params_refine_text=params_refine_text, |
| 61 | params_infer_code=params_infer_code) |
| 62 | |
| 63 | file_path = cretae_new_path(os.path.join(ROOT, "Audio"), "wav") |
| 64 | soundfile.write(file_path, wavs[0][0], 24000) |
| 65 | |
| 66 | return FileResponse(path=file_path, filename=os.path.basename(file_path), media_type='audio/wav') |
| 67 | |
| 68 | |
| 69 | if __name__ == '__main__': |
| 70 | uvicorn.run(app, host="0.0.0.0", port=8080) |
| 71 |