aboutsummaryrefslogtreecommitdiff
path: root/app/converter/clients/speakers.py
blob: a68af682b13132bc4a3a1939bf8d497dfc8bb0a4 (plain)
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
"""Qwen3-TTS built-in speaker names and their wire (display) forms."""

from typing import Optional

# Built-in CustomVoice speaker names for the Qwen3-TTS family. Shared by the
# qwen-tts demo backend (the qwen setup/form) and the audio.cpp audiocpp
# backend's CustomVoice entry (the Convert form's Speaker picker). Entries
# are the canonical form; speaker_display_name_for() maps them to the wire
# (display) form via SPEAKER_DISPLAY_NAMES below.
QWEN3_TTS_SPEAKERS = ("Vivian", "Serena", "Uncle_Fu", "Dylan", "Eric",
                      "Ryan", "Aiden", "Ono_Anna", "Sohee")

# Canonical speaker names -> display names used by the qwen-tts demo.
SPEAKER_DISPLAY_NAMES = {
    "ryan": "Ryan",
    "serena": "Serena",
    "vivian": "Vivian",
    "uncle_fu": "Uncle Fu",
    "aiden": "Aiden",
    "ono_anna": "Ono Anna",
    "sohee": "Sohee",
    "eric": "Eric",
    "dylan": "Dylan",
}


def speaker_display_name_for(name: str) -> str:
    """Return the wire (display) form of a Qwen3-TTS CustomVoice speaker NAME.

    Accepts either the canonical/config form (e.g. "uncle_fu", "Uncle_Fu")
    or the display form ("Uncle Fu"), case-insensitively; unknown names pass
    through unchanged. Used by AudioCppTTSClient to normalize the --voice /
    Speaker-picker value into what audiocpp_server expects in the request's
    voice field.
    """
    return SPEAKER_DISPLAY_NAMES.get((name or "").lower(), name)


def is_builtin_speaker(name: Optional[str]) -> bool:
    """True when NAME is one of the Qwen3-TTS CustomVoice built-in speakers.

    Matches case-insensitively across the canonical ("Uncle_Fu"), display
    ("Uncle Fu") and shorthand ("uncle_fu") forms, so the --voice flag and
    the Convert form's Speaker picker resolve to the same set.
    """
    if not name:
        return False
    norm = name.lower().replace("_", " ").replace("-", " ")
    return any(norm == speaker.lower().replace("_", " ")
               for speaker in QWEN3_TTS_SPEAKERS)