mavttsd: a pronunciation dictionary, so she says the names right (V-458)
piper reads a Russian sentence with a Russian voice, and a Latin service id inside it comes out spelled, mangled or read as if it were a Russian word: "Vikunja", "SearXNG", "homesrv". The lever available is the text, so the dictionary maps a name to how it should be spelled for the voice to say it, and mavttsd applies it at the last edge before piper — every caller's text passes through that one point, and nothing upstream has to know how a name sounds. Data, not code. deploy/tts-lexicon.json ships 29 names; adding one needs a restart of mavttsd and no rebuild of the daemon that produced the text. Off unless -lexicon is set, like every other optional capability, and a path that is set and unreadable stops startup — saying names wrong in silence is the failure it exists to remove. Two details worth keeping: the alternation is sorted longest-first, or "Home Assistant" reads as "Хоум Assistant"; and the boundaries are written out rather than left to \b, which is ASCII-only and never fires next to a Cyrillic letter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/kami/maven/internal/audio"
|
||||
"github.com/kami/maven/internal/tts"
|
||||
"github.com/kami/maven/internal/worker"
|
||||
)
|
||||
|
||||
@@ -117,3 +118,18 @@ func abs(n int) int {
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// The dictionary that ships in deploy/ must parse and must be non-empty. It is
|
||||
// data, so nothing else would catch a trailing comma before the voice did.
|
||||
func TestShippedLexiconLoads(t *testing.T) {
|
||||
lex, err := tts.LoadLexicon(filepath.Join("..", "..", "deploy", "tts-lexicon.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("deploy/tts-lexicon.json: %v", err)
|
||||
}
|
||||
if lex.Size() < 10 {
|
||||
t.Errorf("shipped dictionary holds %d names, want the full list", lex.Size())
|
||||
}
|
||||
if got := lex.Apply("задача в Vikunja"); got == "задача в Vikunja" {
|
||||
t.Error("the shipped dictionary did not rewrite a name it lists")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user