CoolFace
Apppublic

lenML/ChatTTS-Forge

sourceHugging Faceagpl-3.0updated 2y agoView on Hugging Face
301likes
SSMLHandler.py100 linesDownload Raw Back to handler
1import numpy as np2from fastapi import HTTPException3 4from modules.api.impl.handler.AudioHandler import AudioHandler5from modules.api.impl.model.audio_model import AdjustConfig6from modules.api.impl.model.chattts_model import InferConfig7from modules.api.impl.model.enhancer_model import EnhancerConfig8from modules.Enhancer.ResembleEnhance import apply_audio_enhance_full9from modules.normalization import text_normalize10from modules.ssml_parser.SSMLParser import create_ssml_parser11from modules.SynthesizeSegments import SynthesizeSegments, combine_audio_segments12from modules.utils import audio13 14 15class SSMLHandler(AudioHandler):16    def __init__(17        self,18        ssml_content: str,19        infer_config: InferConfig,20        adjust_config: AdjustConfig,21        enhancer_config: EnhancerConfig,22    ) -> None:23        assert isinstance(ssml_content, str), "ssml_content must be a string."24        assert isinstance(25            infer_config, InferConfig26        ), "infer_config must be an InferConfig object."27        assert isinstance(28            adjust_config, AdjustConfig29        ), "adjest_config should be AdjustConfig"30        assert isinstance(31            enhancer_config, EnhancerConfig32        ), "enhancer_config must be an EnhancerConfig object."33 34        self.ssml_content = ssml_content35        self.infer_config = infer_config36        self.adjest_config = adjust_config37        self.enhancer_config = enhancer_config38 39        self.validate()40 41    def validate(self):42        # TODO params checker43        pass44 45    def enqueue(self) -> tuple[np.ndarray, int]:46        ssml_content = self.ssml_content47        infer_config = self.infer_config48        adjust_config = self.adjest_config49        enhancer_config = self.enhancer_config50 51        parser = create_ssml_parser()52        segments = parser.parse(ssml_content)53        for seg in segments:54            seg["text"] = text_normalize(seg["text"], is_end=True)55 56        if len(segments) == 0:57            raise HTTPException(58                status_code=422, detail="The SSML text is empty or parsing failed."59            )60 61        synthesize = SynthesizeSegments(62            batch_size=infer_config.batch_size,63            eos=infer_config.eos,64            spliter_thr=infer_config.spliter_threshold,65        )66        audio_segments = synthesize.synthesize_segments(segments)67        combined_audio = combine_audio_segments(audio_segments)68 69        sample_rate, audio_data = audio.pydub_to_np(combined_audio)70 71        if enhancer_config.enabled:72            nfe = enhancer_config.nfe73            solver = enhancer_config.solver74            lambd = enhancer_config.lambd75            tau = enhancer_config.tau76 77            audio_data, sample_rate = apply_audio_enhance_full(78                audio_data=audio_data,79                sr=sample_rate,80                nfe=nfe,81                solver=solver,82                lambd=lambd,83                tau=tau,84            )85 86        audio_data = audio.apply_prosody_to_audio_data(87            audio_data=audio_data,88            rate=adjust_config.speed_rate,89            pitch=adjust_config.pitch,90            volume=adjust_config.volume_gain_db,91            sr=sample_rate,92        )93 94        if adjust_config.normalize:95            sample_rate, audio_data = audio.apply_normalize(96                audio_data=audio_data, headroom=adjust_config.headroom, sr=sample_rate97            )98 99        return audio_data, sample_rate100