76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
package provider
|
|||
|
|
|
||
|
|
import "sort"
|
||
|
|
|
||
|
|
// voiceDefaults sind die neutralen Repo-Defaults je Provider und Sprache
|
||
|
|
// (Teil des öffentlichen Vertrags: `talk voices` aus Task 08 listet sie,
|
||
|
|
// überschrieben werden sie durch voice.<provider>.<lang> in der config.toml
|
||
|
|
// oder das CLI-Flag --voice).
|
||
|
|
//
|
||
|
|
// Entscheidungsnotiz ElevenLabs-Stimme: Spec und Plan führen die persönliche
|
||
|
|
// Stimme KXxZd16DiBqt82nbarJx ausdrücklich als PRIVATEN Default des Nutzers
|
||
|
|
// („nicht Repo-Default", Spec Further Notes); der Repo-Default ist deshalb
|
||
|
|
// die neutrale, mehrsprachige Standardstimme „Rachel" (21m00Tcm4TlvDq8ikWAM
|
||
|
|
// aus dem öffentlichen ElevenLabs-Katalog). Die persönliche Stimme gehört in
|
||
|
|
// die eigene config.toml:
|
||
|
|
//
|
||
|
|
// [voice.elevenlabs]
|
||
|
|
// de = "KXxZd16DiBqt82nbarJx"
|
||
|
|
// en = "KXxZd16DiBqt82nbarJx"
|
||
|
|
//
|
||
|
|
// OpenAI „alloy" und die Edge-Neural-Stimmen (de-DE-KatjaNeural,
|
||
|
|
// en-US-AriaNeural) sind die jeweils neutralen Standardstimmen der APIs
|
||
|
|
// (Edge-Stimmen sind im Task-Brief vorgegeben).
|
||
|
|
var voiceDefaults = map[string]map[string]string{
|
||
|
|
"elevenlabs": {
|
||
|
|
"de": "21m00Tcm4TlvDq8ikWAM", // „Rachel", multilingual
|
||
|
|
"en": "21m00Tcm4TlvDq8ikWAM",
|
||
|
|
},
|
||
|
|
"openai": {
|
||
|
|
"de": "alloy",
|
||
|
|
"en": "alloy",
|
||
|
|
},
|
||
|
|
"edge": {
|
||
|
|
"de": "de-DE-KatjaNeural",
|
||
|
|
"en": "en-US-AriaNeural",
|
||
|
|
},
|
||
|
|
"osbuiltin": {
|
||
|
|
// osbuiltin mappt intern selbst (macOS Anna/Samantha, SAPI-Kultur,
|
||
|
|
// espeak -v <lang>) und kennt keine Voice-IDs — hier nur der
|
||
|
|
// Vollständigkeit wegen dokumentiert.
|
||
|
|
"de": "",
|
||
|
|
"en": "",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
// resolveVoice liefert die Voice-ID für einen Provider und eine Sprache.
|
||
|
|
// Rangfolge: override (CLI-Flag --voice bzw. PinVoice) > Mapping aus der
|
||
|
|
// config.toml > neutrales Repo-Default > en-Default > alphabetisch erstes
|
||
|
|
// Default. Ein leerer Rückgabewert heißt: der Provider kennt für diese
|
||
|
|
// Sprache keine Stimme (osbuiltin) und entscheidet selbst.
|
||
|
|
func resolveVoice(name, lang, override string, cfgVoices map[string]string) string {
|
||
|
|
if override != "" {
|
||
|
|
return override
|
||
|
|
}
|
||
|
|
if v := cfgVoices[lang]; v != "" {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
def := voiceDefaults[name]
|
||
|
|
if v := def[lang]; v != "" {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
if v := def["en"]; v != "" {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
keys := make([]string, 0, len(def))
|
||
|
|
for k := range def {
|
||
|
|
keys = append(keys, k)
|
||
|
|
}
|
||
|
|
sort.Strings(keys)
|
||
|
|
for _, k := range keys {
|
||
|
|
if v := def[k]; v != "" {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return ""
|
||
|
|
}
|