File size: 2,183 Bytes
41ecf58
 
 
 
82aa895
41ecf58
 
 
 
82aa895
 
41ecf58
 
 
 
82aa895
 
41ecf58
 
 
82aa895
 
 
 
41ecf58
e44db73
82aa895
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41ecf58
82aa895
 
41ecf58
82aa895
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import FastAPI, Response
from pydantic import BaseModel
from kokoro import KPipeline
import soundfile as sf
import numpy as np
import io

app = FastAPI()

# Initialisation du pipeline STRICTEMENT en français (lang_code 'f')
# Cela force toutes les voix (même anglaises) à lire avec les règles du français
pipeline = KPipeline(lang_code='f')

class TTSRequest(BaseModel):
    input: str
    voice: str = "ff_siwis" # Voix 100% française par défaut
    speed: float = 1.0

@app.get("/")
def home():
    return {
        "status": "En ligne", 
        "astuce": "Utilisez le format 'voix1+voix2' pour fusionner des voix avec un accent !"
    }
@app.post("/v1/audio/speech")
def generate_audio(request: TTSRequest):
    # 1. GESTION DE LA FUSION DE VOIX (Voice Blending)
    if "+" in request.voice:
        # Si l'utilisateur demande "ff_siwis+am_michael"
        voice_names = request.voice.split("+")
        tensors = []
        for name in voice_names:
            try:
                # On télécharge/charge le profil de la voix
                t = pipeline.load_voice(name.strip())
                tensors.append(t)
            except Exception as e:
                print(f"Erreur avec la voix {name}: {e}")
        
        # On calcule la moyenne mathématique des voix pour créer une voix hybride
        if tensors:
            voice_param = sum(tensors) / len(tensors)
        else:
            voice_param = "ff_siwis"
    else:
        # Voix simple classique
        voice_param = request.voice

    # 2. GÉNÉRATION DE L'AUDIO
    generator = pipeline(request.input, voice=voice_param, speed=request.speed)
    
    # 3. ASSEMBLAGE (Pratique pour les textes longs)
    audio_chunks = []
    for _, _, audio in generator:
        audio_chunks.append(audio)
        
    if not audio_chunks:
        return Response(status_code=500, content="Erreur lors de la génération")
        
    # On colle tous les morceaux ensemble
    final_audio = np.concatenate(audio_chunks)
    
    # 4. EXPORTATION EN WAV
    out = io.BytesIO()
    sf.write(out, final_audio, 24000, format='wav')
    return Response(content=out.getvalue(), media_type="audio/wav")