File size: 3,319 Bytes
d635cd8
 
 
31bcf8c
d635cd8
e261077
 
768990a
d635cd8
 
 
 
 
 
 
e261077
d635cd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e261077
d635cd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e261077
 
 
d635cd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e261077
d635cd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e261077
 
 
 
 
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import requests
import urllib.parse
from typing import Optional, Dict, Any
from gradio import Server
app = Server() 



def generate_tts_audio(
    text: str,
    voice: str = "Sam",
    pitch: int = 100,
    speed: int = 100,
    base_url: str = "https://tetyys.com/SAPI4"
) -> bytes:
    """
    Generate TTS audio using the Tetyys SAPI4 web interface.
    
    Args:
        text: Text to synthesize (required)
        voice: Voice name (optional, default: "Sam")
        pitch: Pitch value (optional, default: 100)
        speed: Speed value (optional, default: 100)
        base_url: Base URL for the API (optional)
    
    Returns:
        bytes: WAV audio file content
    
    Raises:
        requests.RequestException: If the HTTP request fails
        ValueError: If the response is not valid audio
    """
    # URL encode the text to handle special characters
    encoded_text = urllib.parse.quote(text)
    
    # Build the endpoint URL with query parameters
    endpoint = f"{base_url}/SAPI4?text={encoded_text}"
    
    # Add optional parameters if provided
    params = []
    if voice:
        params.append(f"voice={urllib.parse.quote(voice)}")
    if pitch is not None:
        params.append(f"pitch={pitch}")
    if speed is not None:
        params.append(f"speed={speed}")
    
    # Combine base endpoint with optional parameters
    if params:
        endpoint += "&" + "&".join(params)
    
    # Make the request
    response = requests.get(endpoint, timeout=30)
    response.raise_for_status()
    
    # Validate that we received audio content
    content_type = response.headers.get('Content-Type', '')
    if 'audio' not in content_type.lower():
        raise ValueError(
            f"Expected audio response, got: {content_type}. "
            f"Response preview: {response.text[:100]}"
        )
    
    return response.content



@app.api(name="tts")
def save_tts_audio(
    text: str,
    output_path: str,
    voice: str = "Sam",
    pitch: int = 100,
    speed: int = 100,
    base_url: str = "https://tetyys.com/SAPI4"
) -> None:
    """
    Generate TTS audio and save it to a file.
    
    Args:
        text: Text to synthesize
        output_path: Path where the WAV file will be saved
        voice: Voice name (optional, default: "Sam")
        pitch: Pitch value (optional, default: 100)
        speed: Speed value (optional, default: 100)
        base_url: Base URL for the API (optional)
    """
    audio_data = generate_tts_audio(text, voice, pitch, speed, base_url)
    
    with open(output_path, 'wb') as f:
        f.write(audio_data)


def get_voice_limits(
    voice: str,
    base_url: str = "https://tetyys.com/SAPI4"
) -> Dict[str, Any]:
    """
    Get the pitch and speed limitations for a specific voice.
    
    Args:
        voice: Voice name to query
        base_url: Base URL for the API (optional)
    
    Returns:
        dict: Voice limitations data
    """
    encoded_voice = urllib.parse.quote(voice)
    endpoint = f"{base_url}/VoiceLimitations?voice={encoded_voice}"
    
    response = requests.get(endpoint, timeout=30)
    response.raise_for_status()
    
    return response.json()



# ─────────────────────────────────────────────
app.launch()