Kokoro-FastAPI ships English, Spanish, French, Hindi, Italian, Japanese, Portuguese and Chinese voices only. The German presets pointed at voice ids no Kokoro server has, so German users either got English voices or picked a voice that failed to speak. The local voice now also lists the German voices whose Piper model is installed (PIPER_BASE_URL) and speaks them through Piper's /synthesize as WAV. Thorsten, the clearest model, is the German default. Mobile plays WAV as well as MP3, and the E2E voice stub stands in for Piper. Claude-Session: https://claude.ai/code/session_01KWEAjTw26eRf3ZXTXfRjmD Co-authored-by: Claude <noreply@anthropic.com>
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
defaultOnboardingVoiceId,
|
|
offlineOnboardingVoices,
|
|
onboardingVoicesFromList,
|
|
} from "./onboarding-voices.js";
|
|
|
|
describe("offlineOnboardingVoices", () => {
|
|
it("offers German voices for de", () => {
|
|
expect(offlineOnboardingVoices("de").map((voice) => voice.id)).toEqual([
|
|
"dm_thorsten",
|
|
"df_kerstin",
|
|
"df_eva",
|
|
"df_ramona",
|
|
"dm_karlsson",
|
|
]);
|
|
});
|
|
|
|
it("offers English voices for en", () => {
|
|
const ids = offlineOnboardingVoices("en").map((voice) => voice.id);
|
|
expect(ids).toContain("af_heart");
|
|
expect(ids).not.toContain("df_eva");
|
|
});
|
|
});
|
|
|
|
describe("onboardingVoicesFromList", () => {
|
|
it("uses offline German presets when the server only lists English voices", () => {
|
|
const englishOnly = [{ id: "af_alloy", label: "Alloy", description: "neutral" }];
|
|
expect(onboardingVoicesFromList(englishOnly, "de").map((voice) => voice.id)).toEqual([
|
|
"dm_thorsten",
|
|
"df_kerstin",
|
|
"df_eva",
|
|
"df_ramona",
|
|
"dm_karlsson",
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("defaultOnboardingVoiceId", () => {
|
|
it("prefers Thorsten for German", () => {
|
|
expect(defaultOnboardingVoiceId("de", offlineOnboardingVoices("de"))).toBe("dm_thorsten");
|
|
});
|
|
});
|