diff --git a/.gitattributes b/.gitattributes
index a6344aac8c09253b3b630fb776ae94478aa0275b..cf46d176234e5246fca351fd36495c545567b37a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -33,3 +33,21 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/clara.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/colette.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/emma.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/henri.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/henry.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/lucy.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/miles.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/oliver.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/oscar.opus filter=lfs diff=lfs merge=lfs -text
+audio/loudr-1/sophie.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/clara.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/emma.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/henry.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/lucy.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/miles.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/oliver.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/oscar.opus filter=lfs diff=lfs merge=lfs -text
+audio/turbo/sophie.opus filter=lfs diff=lfs merge=lfs -text
diff --git a/README.md b/README.md
index bfab8cee20dfe6f6a1a664901c94731c3d1b39cf..5b5c31368c1693dc61902ed1a3ceb7fd91b1792e 100644
--- a/README.md
+++ b/README.md
@@ -9,56 +9,48 @@ python_version: "3.12.12"
app_file: app.py
pinned: false
license: apache-2.0
-short_description: On-device TTS. Twenty voices, ten languages, one engine.
+short_description: On-device TTS. 28 voices, ten languages, two models.
models:
- loudreader/loudr-1
+ - loudreader/loudr-1-turbo
preload_from_hub:
- - loudreader/loudr-1 loudr-1.safetensors,loudr-1-enrollment.safetensors,ve.safetensors,manifest.json,release.json,SHA256SUMS,voices/carmen.safetensors,voices/colette.safetensors,voices/dante.safetensors,voices/darkman.safetensors,voices/dave.safetensors,voices/freja.safetensors,voices/gosia.safetensors,voices/henri.safetensors,voices/ines.safetensors,voices/joe.safetensors,voices/kathleen.safetensors,voices/kerstin.safetensors,voices/nathalie.safetensors,voices/nils.safetensors,voices/paola.safetensors,voices/pim.safetensors,voices/selma.safetensors,voices/soren.safetensors,voices/thorsten.safetensors,voices/tugao.safetensors
+ - loudreader/loudr-1 loudr-1.safetensors,loudr-1-enrollment.safetensors,ve.safetensors,tokenizer.json,manifest.json,release.json,SHA256SUMS,voices/carmen.safetensors,voices/clara.safetensors,voices/colette.safetensors,voices/dante.safetensors,voices/darkman.safetensors,voices/dave.safetensors,voices/emma.safetensors,voices/freja.safetensors,voices/gosia.safetensors,voices/henri.safetensors,voices/henry.safetensors,voices/ines.safetensors,voices/joe.safetensors,voices/kathleen.safetensors,voices/kerstin.safetensors,voices/lucy.safetensors,voices/miles.safetensors,voices/nathalie.safetensors,voices/nils.safetensors,voices/oliver.safetensors,voices/oscar.safetensors,voices/paola.safetensors,voices/pim.safetensors,voices/selma.safetensors,voices/sophie.safetensors,voices/soren.safetensors,voices/thorsten.safetensors,voices/tugao.safetensors
+ - loudreader/loudr-1-turbo loudr-1-turbo.safetensors,tokenizer.json,manifest.json,release.json,SHA256SUMS
---
# loudkit
-Twenty voices across ten languages, from [loudreader/loudr-1](https://huggingface.co/loudreader/loudr-1),
+Twenty-eight voices across ten languages, on two models:
+[loudreader/loudr-1](https://huggingface.co/loudreader/loudr-1) and
+[loudreader/loudr-1-turbo](https://huggingface.co/loudreader/loudr-1-turbo),
running the [loudkit](https://github.com/loudreader/loudkit) engine on ZeroGPU.
## Two tabs
-- **Voices.** Twenty voices, each beside the reference recording it was enrolled
- from. English first, with a dropdown for the other nine languages. The samples
- were rendered ahead of time and ship in this repo, so playing them uses no GPU.
- Under them is a box for your own text, up to 1,000 characters.
-- **Clone.** A voice from about ten seconds of audio. Try a shipped example, or
- record yourself.
+- **Voices.** Twenty-eight voices, each beside the reference recording it was
+ enrolled from, and each rendered on both models from the same passage at the
+ same seed. English first, with a dropdown for the other nine languages. The
+ samples were rendered ahead of time and ship in this repo, so playing them
+ uses no GPU. Under them is a box for your own text, up to 1,000 characters,
+ and one that renders the same words on both models side by side.
+- **Clone.** A voice from about ten seconds of a recording, then speak with it
+ on either model. One profile serves both, which is what a portable voice
+ profile means. The microphone is the default path; an upload is gated on a
+ confirmation, and neither recording outlives the request.
-ZeroGPU bills GPU time to the visitor, not to the owner. An anonymous visitor
-gets about two minutes a day. A signed-in free account gets about five. Listening
-costs none of it.
+## What this demo is honest about
-## Cloning and consent
+ZeroGPU bills GPU time to the visitor. Listening costs nothing, because the
+fifty-six samples are files. Speaking and cloning spend the visitor's own daily
+quota, which is why the text boxes are capped well below what the library takes.
-Clone your own voice, or a voice you have permission to use.
+Both models are pinned to an immutable Hub commit rather than to a branch, so
+the fingerprint the page prints is the fingerprint of the bytes it ran.
-- Four shipped examples let you hear cloning without recording anything. Their
- donors released them for building TTS voices.
-- Recording yourself is the next path. It clears the example.
-- An upload is last, and needs an explicit confirmation.
-- Recordings are deleted when the request ends. The voice embeddings are never
- written to disk and never leave the process.
-- Cloned audio carries no download button.
+Output files carry C2PA provenance: the algorithm fingerprint, the recipe and
+the seed.
-See [RESPONSIBLE_USE](https://github.com/loudreader/loudkit/blob/main/RESPONSIBLE_USE.md).
-
-## Determinism
-
-The Voices tab has a determinism check. It renders the same text twice at the same
-seed and prints the SHA-256 of both waveforms. They match.
-
-That holds within this build and this device. loudkit promises a bit-identical
-waveform for the same seed, build, backend and input. It does not promise that
-your machine matches this GPU. See the
-[identity contract](https://github.com/loudreader/loudkit/blob/main/docs/reference/IDENTITY-CONTRACT.md).
-
-## Run it locally
+## Running it locally instead
```bash
pip install "loudkit[torch,audio,enroll,hub]"
@@ -67,16 +59,9 @@ pip install "loudkit[torch,audio,enroll,hub]"
```python
import loudkit as lk
-engine = lk.load("loudreader/loudr-1")
-voice = lk.voice("kathleen", repo="loudreader/loudr-1")
+engine = lk.load("loudreader/loudr-1", revision="v0.1.1")
+voice = lk.voice("kathleen", repo="loudreader/loudr-1", revision="v0.1.1")
engine.synthesize_long("Hello from loudkit.", voice, seed=7).save("hello.wav")
```
-Audio in this Space, and from `Result.save`, carries C2PA provenance: the
-algorithm fingerprint, the recipe and the seed.
-
-## Voice sources
-
-Every voice is enrolled from a public-domain or openly licensed recording.
-`voices.json` in this repo carries the full record for each one: donor, source,
-licence, consent, and the SHA-256 of both the reference and the sample.
+Nothing is queued and nothing is metered.
diff --git a/app.py b/app.py
index 06e2ccfe04d495538e230c2e4bb8046cd86923a6..ba078e0c664963125567debfc3ed641fa25812da 100644
--- a/app.py
+++ b/app.py
@@ -1,24 +1,32 @@
-"""The loudkit demo Space: hear twenty voices, speak your own text, clone your own.
+"""The loudkit demo Space: twenty-eight voices, two models, one engine.
ZeroGPU bills GPU time to the *visitor*, not to the owner: an anonymous visitor
gets about two minutes a day, a signed-in free account about five. A demo whose
first click spends that budget is one most people bounce off before they have
-heard anything at all. So the Listen tab is twenty pre-rendered files served
-straight out of this repo — no GPU, no queue, no quota — and the GPU is spent
-only on what a visitor types or records.
-
-The engine and the enroller are both built on `cuda` at module level, which is
-what ZeroGPU asks for: CUDA transfers are optimised for start-up placement, and
-lazy-loading inside a `@spaces.GPU` function is explicitly discouraged. Each
-decorated call then runs in a freshly forked, short-lived process, which is also
-why there is no `torch.compile` and no CUDA graph capture here: both pay their
-cost once per process and would never amortise.
-
-Cloning is exposed, which the CPU scaffold this replaces deliberately did not do.
-The reasoning that kept it out was about consent, not about capability, so the
-consent is built into the shape of the tab rather than written beside it: the
-microphone is the default path, an upload is secondary and gated on an explicit
-confirmation, and neither recording outlives the request that carried it.
+heard anything at all. So the Voices tab is fifty-six pre-rendered files served
+straight out of this repo, twenty-eight voices on each model, and the GPU is
+spent only on what a visitor types or records.
+
+Both models are here because the choice between them is the first real decision
+an adopter makes, and it is not one a table of numbers settles. Every voice
+reads the same passage on both, at the same seed, so switching the model is the
+only thing that changes. loudr-1 is the natural one; loudr-1-turbo renders
+about twice as fast from a two-token decode.
+
+Both are loaded at module level on `cuda`, which is what ZeroGPU asks for: CUDA
+transfers are optimised for start-up placement, and lazy-loading inside a
+`@spaces.GPU` function is explicitly discouraged. Each decorated call then runs
+in a freshly forked, short-lived process, which is also why there is no
+`torch.compile` and no CUDA graph capture here: both pay their cost once per
+process and would never amortise.
+
+Cloning is exposed, and the consent is built into the shape of the tab rather
+than written beside it: the microphone is the default path, an upload is
+secondary and gated on an explicit confirmation, and neither recording outlives
+the request that carried it.
+
+Every load is pinned to a Hub revision. A demo that says what a build does must
+be able to say which build, and `main` is not an answer that stays true.
"""
from __future__ import annotations
@@ -43,10 +51,29 @@ import loudkit as lk
from loudkit.backends.torch_backend import build_torch_enroller
from loudkit.hub import resolve_enrollment_checkpoint, resolve_voice_encoder
-REPO = "loudreader/loudr-1"
DEVICE = "cuda"
HERE = Path(__file__).parent
+# The two published bundles, pinned. The tag moves when a release is cut; the
+# commit does not, and a demo that claims a fingerprint should be reproducible
+# from the same bytes a year from now.
+MODELS = {
+ "loudr-1": {
+ "repo": "loudreader/loudr-1",
+ "revision": "7516673ee74ab2228ffc4e99223d296d8904d7ff",
+ "label": "loudr-1 · the natural one",
+ "blurb": "Single-token decode. The reference model.",
+ },
+ "turbo": {
+ "repo": "loudreader/loudr-1-turbo",
+ "revision": "366f140a5f7ebe215e5b43cdd73384746c83bae6",
+ "label": "loudr-1-turbo · about twice as fast",
+ "blurb": "Two-token decode, one flow step. Same voices, same profiles.",
+ },
+}
+DEFAULT_MODEL = "loudr-1"
+MODEL_CHOICES = [(cfg["label"], key) for key, cfg in MODELS.items()]
+
# The CPU scaffold capped text at 300 characters because CPU synthesis ran at
# roughly a tenth of real time. On a GPU the cap is about the visitor's daily
# quota instead, which is a far looser bound: 1000 characters is ~70 s of speech.
@@ -66,14 +93,14 @@ RESPONSIBLE_USE = f"{DOCS}/blob/main/RESPONSIBLE_USE.md"
ROSTER = json.loads((HERE / "voices.json").read_text(encoding="utf-8"))
BY_NAME = {entry["name"]: entry for entry in ROSTER}
ORDERED = sorted(ROSTER, key=lambda e: (e["language"], e["name"]))
-VOICE_CHOICES = [(f"{e['name']} · {e['language']} ({e['gender']})", e["name"]) for e in ORDERED]
# English leads. A visitor who does not read the other nine should not have to
# hunt for the one they do, and alphabetical order put Danish first.
FIRST_LANGUAGE = "en"
_LANG_OF = {e["language_id"]: e["language"] for e in ROSTER}
LANGUAGE_FILTER = [(_LANG_OF[FIRST_LANGUAGE], FIRST_LANGUAGE)] + [
- (name, code) for code, name in sorted(_LANG_OF.items(), key=lambda kv: kv[1])
+ (name, code)
+ for code, name in sorted(_LANG_OF.items(), key=lambda kv: kv[1])
if code != FIRST_LANGUAGE
]
@@ -101,24 +128,32 @@ EXAMPLE_CHOICES = [("Nothing selected", "")] + [
# Module-level model placement, per the ZeroGPU contract.
# --------------------------------------------------------------------------
-engine = lk.load(REPO, device=DEVICE)
+ENGINES = {
+ key: lk.load(cfg["repo"], revision=cfg["revision"], device=DEVICE)
+ for key, cfg in MODELS.items()
+}
# Voice profiles are numpy, not torch, so they are device-agnostic and cost a
-# few hundred kilobytes each. Loading all twenty up front means switching voice
-# in the Speak tab never blocks on a download.
-PROFILES = {entry["name"]: lk.voice(entry["name"], repo=REPO) for entry in ROSTER}
+# few hundred kilobytes each. They are also identical in both bundles, which is
+# the point of a portable profile: one clone, either model.
+BASE = MODELS[DEFAULT_MODEL]
+PROFILES = {
+ entry["name"]: lk.voice(entry["name"], repo=BASE["repo"], revision=BASE["revision"])
+ for entry in ROSTER
+}
# Enrollment reads the other half of the release: the speech tokenizer and the
# speaker encoder, which synthesis never touches, plus the utterance voice
-# encoder that sits beside both. `lk.enroll()` builds this per call by design;
-# a Space would pay the load on every clone, so it is built once here instead.
+# encoder that sits beside both. One enroller serves both models, because the
+# profile it produces is the same file either way. `lk.enroll()` builds this per
+# call by design; a Space would pay the load on every clone.
enroller = build_torch_enroller(
- str(resolve_enrollment_checkpoint(REPO)),
+ str(resolve_enrollment_checkpoint(BASE["repo"], revision=BASE["revision"])),
device=DEVICE,
- voice_encoder_weights=str(resolve_voice_encoder(REPO)),
+ voice_encoder_weights=str(resolve_voice_encoder(BASE["repo"], revision=BASE["revision"])),
)
-FINGERPRINT = engine.algorithm.fingerprint()
+FINGERPRINTS = {key: engine.algorithm.fingerprint() for key, engine in ENGINES.items()}
_LANGUAGE_NAMES = {e["language_id"]: e["language"] for e in ROSTER}
LANGUAGE_CHOICES = [("Follow the voice", "")] + [
@@ -153,11 +188,11 @@ def _write(result: lk.Result, *, voice: str, language: str) -> str:
return out.name
-def _stats(result: lk.Result) -> str:
+def _stats(result: lk.Result, model: str) -> str:
seconds = len(result.audio) / result.sample_rate
return (
f"**{seconds:.1f} s of audio.** {result.timings.describe(seconds)}\n\n"
- f"`algo[{result.algorithm_fingerprint}]` · seed `{result.seed}` · "
+ f"`{model}` · `algo[{result.algorithm_fingerprint}]` · seed `{result.seed}` · "
f"speed `{result.speed:g}x` · {result.sample_rate} Hz"
)
@@ -183,21 +218,26 @@ def _check(text: str, limit: int) -> str:
return text
+def _engine(model: str) -> lk.Engine:
+ return ENGINES[model if model in ENGINES else DEFAULT_MODEL]
+
+
# --------------------------------------------------------------------------
# Listen. No GPU: these files were rendered ahead of time and ship in the repo.
# --------------------------------------------------------------------------
-def listen(name: str):
+def listen(name: str, model: str):
entry = BY_NAME[name]
sample, reference, source = entry["sample"], entry["reference"], entry["source"]
+ model = model if model in MODELS else DEFAULT_MODEL
lines = [
f"### {entry['name']}. {entry['language']} ({entry['gender']}).",
"",
f"> {sample['text']}",
"",
- f"From *{sample['work']}*, seed `{sample['seed']}`.",
+ f"From *{sample['work']}*, seed `{sample['seed']}`, rendered on `{model}`.",
"",
f"- Reference recording: {reference['duration_s']:.1f} s, {reference['construction']}.",
f"- Source: [{source['name']}]({source['url']}), {source['license']}.",
@@ -206,10 +246,10 @@ def listen(name: str):
similarity = entry.get("speaker_similarity")
if similarity is not None:
lines.append(f"- Speaker similarity to the reference: {similarity:.3f}.")
- lines.append(f"- Voice profile: `{entry['profile']['hf_path']}`.")
+ lines.append(f"- Voice profile: `{entry['profile']['hf_path']}`, the same file in both models.")
return (
- str(HERE / sample["audio"]),
+ str(HERE / sample["audio"][model]),
str(HERE / reference["public_preview"]),
"\n".join(lines),
)
@@ -232,14 +272,14 @@ ROSTER_TABLE = [
# --------------------------------------------------------------------------
-def _speak_duration(text, name, language, seed, speed):
+def _speak_duration(text, name, model, language, seed, speed):
return _estimate(text, overhead=15.0)
@spaces.GPU(duration=_speak_duration)
-def speak(text: str, name: str, language: str, seed: float, speed: float):
+def speak(text: str, name: str, model: str, language: str, seed: float, speed: float):
text = _check(text, MAX_CHARS)
- result = engine.synthesize_long(
+ result = _engine(model).synthesize_long(
text,
PROFILES[name],
seed=int(seed),
@@ -247,7 +287,46 @@ def speak(text: str, name: str, language: str, seed: float, speed: float):
speed=float(speed),
)
label = language or BY_NAME[name]["language_id"]
- return _write(result, voice=name, language=label), _stats(result)
+ return _write(result, voice=name, language=label), _stats(result, model)
+
+
+# --------------------------------------------------------------------------
+# Both models on one text. GPU. The comparison the model choice is really about.
+# --------------------------------------------------------------------------
+
+
+def _compare_duration(text, name, seed):
+ return _estimate(text, passes=2, overhead=20.0)
+
+
+@spaces.GPU(duration=_compare_duration)
+def compare(text: str, name: str, seed: float):
+ """The same words, the same voice, the same seed, on both models."""
+ text = _check(text, MAX_PROBE_CHARS)
+ profile = PROFILES[name]
+ out = {}
+ for key, engine in ENGINES.items():
+ result = engine.synthesize_long(text, profile, seed=int(seed))
+ out[key] = (
+ _write(result, voice=name, language=BY_NAME[name]["language_id"]),
+ len(result.audio) / result.sample_rate,
+ result.algorithm_fingerprint,
+ )
+
+ note = "\n".join(
+ [
+ "| model | audio | fingerprint |",
+ "|---|---:|---|",
+ *(
+ f"| `{key}` | {seconds:.2f} s | `{fingerprint}` |"
+ for key, (_, seconds, fingerprint) in out.items()
+ ),
+ "",
+ "Two models, two fingerprints, and the same voice profile in both. "
+ "Which one to ship is an ear question, not a table question.",
+ ]
+ )
+ return out["loudr-1"][0], out["turbo"][0], note
# --------------------------------------------------------------------------
@@ -255,14 +334,14 @@ def speak(text: str, name: str, language: str, seed: float, speed: float):
# --------------------------------------------------------------------------
-def _clone_duration(example, mic, upload, consent, text, language, seed, speed):
+def _clone_duration(example, mic, upload, consent, text, model, language, seed, speed):
# Enrollment is a fixed cost on top of the render: two encoders and a
# tokenizer over at most 20 s of audio.
return _estimate(text, overhead=30.0)
@spaces.GPU(duration=_clone_duration)
-def clone(example, mic, upload, consent: bool, text: str, language: str, seed, speed):
+def clone(example, mic, upload, consent: bool, text: str, model: str, language: str, seed, speed):
"""Enroll a voice, speak with it, keep nothing.
Three ways in, and they do not carry the same consent story, so they are
@@ -315,10 +394,10 @@ def clone(example, mic, upload, consent: bool, text: str, language: str, seed, s
# and read its text through the English funnel.
profile = dataclasses.replace(profile, language=language or "en")
- result = engine.synthesize_long(
+ result = _engine(model).synthesize_long(
text, profile, seed=int(seed), language=language or None, speed=float(speed)
)
- return _write(result, voice=label, language=profile.language), _stats(result)
+ return _write(result, voice=label, language=profile.language), _stats(result, model)
finally:
# Nothing the visitor recorded outlives the request that carried it.
# A shipped example is not the visitor's and is not ours to delete.
@@ -332,13 +411,14 @@ def clone(example, mic, upload, consent: bool, text: str, language: str, seed, s
# --------------------------------------------------------------------------
-def _probe_duration(text, name, seed):
+def _probe_duration(text, name, model, seed):
return _estimate(text, passes=2, overhead=20.0)
@spaces.GPU(duration=_probe_duration)
-def probe(text: str, name: str, seed: float):
+def probe(text: str, name: str, model: str, seed: float):
text = _check(text, MAX_PROBE_CHARS)
+ engine = _engine(model)
profile = PROFILES[name]
first = engine.synthesize_long(text, profile, seed=int(seed))
second = engine.synthesize_long(text, profile, seed=int(seed))
@@ -353,12 +433,13 @@ def probe(text: str, name: str, seed: float):
"```",
f"render 1 sha256 {left}",
f"render 2 sha256 {right}",
- f" algo[{first.algorithm_fingerprint}] seed {int(seed)}",
+ f" algo[{first.algorithm_fingerprint}] seed {int(seed)} {model}",
"```",
"",
"Identical within this build and this device. loudkit promises a "
"bit-identical waveform for the same seed, build, backend and input. "
- "It does not promise that your laptop matches this GPU. "
+ "It does not promise that your laptop matches this GPU, and the two "
+ "models are two different builds by construction. "
f"[Read the identity contract]({IDENTITY_CONTRACT}).",
]
)
@@ -416,14 +497,17 @@ THEME = gr.themes.Soft(
with gr.Blocks(title="loudkit", theme=THEME, css=CSS, js=FORCE_LIGHT, fill_width=False) as demo:
gr.Markdown(
f"""
-# Twenty voices. Ten languages. One engine.
+# Twenty-eight voices. Ten languages. Two models.
On-device text to speech, running here on ZeroGPU.
-[Model](https://huggingface.co/{REPO}) · [Code]({DOCS}) · [Responsible use]({RESPONSIBLE_USE})
+[loudr-1](https://huggingface.co/{MODELS["loudr-1"]["repo"]}) ·
+[loudr-1-turbo](https://huggingface.co/{MODELS["turbo"]["repo"]}) ·
+[Code]({DOCS}) · [Responsible use]({RESPONSIBLE_USE})
Listening costs no GPU
Speaking and cloning spend your daily quota
-algo[{FINGERPRINT}]
+algo[{FINGERPRINTS["loudr-1"]}]
+algo[{FINGERPRINTS["turbo"]}]
""",
elem_id="lk-head",
)
@@ -432,18 +516,23 @@ On-device text to speech, running here on ZeroGPU.
# ------------- Voices: listen for free, then type your own -------------
with gr.Tab("Voices"):
gr.Markdown(
- "Pick a voice and the sample plays at once. Those are rendered "
- "ahead of time and use no GPU. Type your own text underneath."
+ "Pick a voice and the sample plays at once. Every voice is here "
+ "twice, once per model, reading the same passage at the same "
+ "seed. Those files were rendered ahead of time and use no GPU."
)
with gr.Row():
with gr.Column(scale=1):
+ model_pick = gr.Radio(
+ MODEL_CHOICES,
+ value=DEFAULT_MODEL,
+ label="Model",
+ info="Switching this changes the sample and what the buttons below run.",
+ )
with gr.Row():
lang_pick = gr.Dropdown(
LANGUAGE_FILTER, value=FIRST_LANGUAGE, label="Language"
)
- pick = gr.Dropdown(
- FIRST_VOICES, value=FIRST_VOICE, label="Voice"
- )
+ pick = gr.Dropdown(FIRST_VOICES, value=FIRST_VOICE, label="Voice")
made = gr.Audio(label="loudkit", type="filepath", interactive=False)
ref = gr.Audio(
label="Reference recording", type="filepath", interactive=False
@@ -484,22 +573,49 @@ On-device text to speech, running here on ZeroGPU.
say_stats = gr.Markdown()
say_go.click(
- speak, [say, pick, say_lang, say_seed, say_speed], [say_out, say_stats]
+ speak,
+ [say, pick, model_pick, say_lang, say_seed, say_speed],
+ [say_out, say_stats],
)
- def on_language(language):
+ def on_language(language, model):
choices = voices_in(language)
name = choices[0][1]
- return (gr.Dropdown(choices=choices, value=name), *listen(name))
+ return (gr.Dropdown(choices=choices, value=name), *listen(name, model))
+
+ lang_pick.change(on_language, [lang_pick, model_pick], [pick, made, ref, card])
+ pick.change(listen, [pick, model_pick], [made, ref, card])
+ model_pick.change(listen, [pick, model_pick], [made, ref, card])
+ demo.load(listen, [pick, model_pick], [made, ref, card])
- lang_pick.change(on_language, lang_pick, [pick, made, ref, card])
- pick.change(listen, pick, [made, ref, card])
- demo.load(listen, pick, [made, ref, card])
+ with gr.Accordion("Hear both models on your own words", open=False):
+ gr.Markdown(
+ "The same text, the same voice, the same seed, rendered on "
+ "both. This is the comparison the model choice is about, and "
+ "it costs two renders of your quota."
+ )
+ with gr.Row():
+ cmp_text = gr.Textbox(
+ value="The same words, on both models.",
+ label="Text",
+ lines=1,
+ max_lines=2,
+ max_length=MAX_PROBE_CHARS,
+ scale=3,
+ )
+ cmp_seed = gr.Number(value=7, precision=0, label="Seed", scale=1)
+ cmp_go = gr.Button("Render on both")
+ with gr.Row():
+ cmp_base = gr.Audio(label="loudr-1", type="filepath")
+ cmp_turbo = gr.Audio(label="loudr-1-turbo", type="filepath")
+ cmp_note = gr.Markdown()
+ cmp_go.click(compare, [cmp_text, pick, cmp_seed], [cmp_base, cmp_turbo, cmp_note])
with gr.Accordion("Determinism check", open=False):
gr.Markdown(
- "This renders the same text twice at the same seed and hashes "
- "both waveforms. The digests must match."
+ "This renders the same text twice at the same seed on the "
+ "selected model and hashes both waveforms. The digests must "
+ "match."
)
with gr.Row():
probe_text = gr.Textbox(
@@ -513,16 +629,18 @@ On-device text to speech, running here on ZeroGPU.
probe_seed = gr.Number(value=7, precision=0, label="Seed", scale=1)
probe_go = gr.Button("Render twice")
probe_out = gr.Markdown()
- probe_go.click(probe, [probe_text, pick, probe_seed], probe_out)
+ probe_go.click(probe, [probe_text, pick, model_pick, probe_seed], probe_out)
# ---------------------------- Clone ----------------------------
with gr.Tab("Clone"):
gr.Markdown(
f"""
-Clone a voice from a short recording, then speak with it.
+Clone a voice from a short recording, then speak with it on either model.
- Try one of the shipped examples, or record yourself.
- Clone only your own voice, or a voice you have permission to use.
+- One profile serves both models. That is what a portable voice profile means:
+ enroll once, and the file works wherever the engine does.
- Nothing is kept. The recording and the voice embeddings are discarded when the
request ends, and neither is offered for download.
- See [Responsible use]({RESPONSIBLE_USE}).
@@ -558,6 +676,9 @@ Clone a voice from a short recording, then speak with it.
),
)
with gr.Column(scale=1):
+ clone_model = gr.Radio(
+ MODEL_CHOICES, value=DEFAULT_MODEL, label="Speak it with"
+ )
clone_text = gr.Textbox(
label="Text to speak",
placeholder="Now in my own voice.",
@@ -596,7 +717,17 @@ Clone a voice from a short recording, then speak with it.
clone_go.click(
clone,
- [example, mic, upload, consent, clone_text, clone_lang, clone_seed, clone_speed],
+ [
+ example,
+ mic,
+ upload,
+ consent,
+ clone_text,
+ clone_model,
+ clone_lang,
+ clone_seed,
+ clone_speed,
+ ],
[clone_out, clone_stats],
)
@@ -612,16 +743,22 @@ pip install "loudkit[torch,audio,enroll,hub]"
```python
import loudkit as lk
-engine = lk.load("{REPO}")
-voice = lk.voice("kathleen", repo="{REPO}")
+engine = lk.load("{MODELS["loudr-1"]["repo"]}", revision="v0.1.1")
+voice = lk.voice("kathleen", repo="{MODELS["loudr-1"]["repo"]}", revision="v0.1.1")
engine.synthesize_long("Hello from loudkit.", voice, seed=7).save("hello.wav")
```
+The same profile reads on the faster model by changing one string:
+
+```python
+engine = lk.load("{MODELS["turbo"]["repo"]}", revision="v0.1.1")
+```
+
Output files carry C2PA provenance: the fingerprint, the recipe and the seed.
"""
)
-# The engine holds one set of weights and renders with an internal producer
+# Each engine holds one set of weights and renders with an internal producer
# thread. One render at a time keeps two requests off the same buffers.
demo.queue(default_concurrency_limit=1, max_size=24)
diff --git a/audio/carmen.opus b/audio/carmen.opus
deleted file mode 100644
index e1e18609163ff3cd67315d85497818f104d33a58..0000000000000000000000000000000000000000
Binary files a/audio/carmen.opus and /dev/null differ
diff --git a/audio/colette.opus b/audio/colette.opus
deleted file mode 100644
index 682389d876f822ca755d906f05db376a18ff68d9..0000000000000000000000000000000000000000
Binary files a/audio/colette.opus and /dev/null differ
diff --git a/audio/dante.opus b/audio/dante.opus
deleted file mode 100644
index 6628f6858d4f71d379c47411baee9507f8192928..0000000000000000000000000000000000000000
Binary files a/audio/dante.opus and /dev/null differ
diff --git a/audio/darkman.opus b/audio/darkman.opus
deleted file mode 100644
index 7a6ce2e7c75e4206475b532df2fe8a9850a29929..0000000000000000000000000000000000000000
Binary files a/audio/darkman.opus and /dev/null differ
diff --git a/audio/dave.opus b/audio/dave.opus
deleted file mode 100644
index 502d2da2e6fdf140c6310a3336457eb210a7bc31..0000000000000000000000000000000000000000
Binary files a/audio/dave.opus and /dev/null differ
diff --git a/audio/freja.opus b/audio/freja.opus
deleted file mode 100644
index 2160a36de61672adf91284b9c74c692b59f07206..0000000000000000000000000000000000000000
Binary files a/audio/freja.opus and /dev/null differ
diff --git a/audio/gosia.opus b/audio/gosia.opus
deleted file mode 100644
index 853a342df5107a4894770834ef16a8539ecf1f6f..0000000000000000000000000000000000000000
Binary files a/audio/gosia.opus and /dev/null differ
diff --git a/audio/henri.opus b/audio/henri.opus
deleted file mode 100644
index 97c0f1a5a9bd18e1516d97a70f26fe3a5b3ae0bb..0000000000000000000000000000000000000000
Binary files a/audio/henri.opus and /dev/null differ
diff --git a/audio/ines.opus b/audio/ines.opus
deleted file mode 100644
index 2f988d7adb9dc0bd7041089ac470d0cbee02c832..0000000000000000000000000000000000000000
Binary files a/audio/ines.opus and /dev/null differ
diff --git a/audio/joe.opus b/audio/joe.opus
deleted file mode 100644
index d35624d4b0cd92eb44d278737e92a65c95db9892..0000000000000000000000000000000000000000
Binary files a/audio/joe.opus and /dev/null differ
diff --git a/audio/kathleen.opus b/audio/kathleen.opus
deleted file mode 100644
index afab998420c69de122c666484f135471301633ef..0000000000000000000000000000000000000000
Binary files a/audio/kathleen.opus and /dev/null differ
diff --git a/audio/kerstin.opus b/audio/kerstin.opus
deleted file mode 100644
index bc9b99ead23656b1e5f2ca7af21146bc1923b6ef..0000000000000000000000000000000000000000
Binary files a/audio/kerstin.opus and /dev/null differ
diff --git a/audio/loudr-1/carmen.opus b/audio/loudr-1/carmen.opus
new file mode 100644
index 0000000000000000000000000000000000000000..3ad1f9d4381b12d23639de637f6102aeb269d1aa
Binary files /dev/null and b/audio/loudr-1/carmen.opus differ
diff --git a/audio/loudr-1/clara.opus b/audio/loudr-1/clara.opus
new file mode 100644
index 0000000000000000000000000000000000000000..cd3b3b9505e11534fff10d63d9fca719c96fb4c4
--- /dev/null
+++ b/audio/loudr-1/clara.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d218b620146d5954adefb4dbf631c169b4647967bf49b7383e03997468a636e3
+size 132921
diff --git a/audio/loudr-1/colette.opus b/audio/loudr-1/colette.opus
new file mode 100644
index 0000000000000000000000000000000000000000..3570259561ccbe7cef0234ae1a82c55878187a46
--- /dev/null
+++ b/audio/loudr-1/colette.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:04a10c727da4572bb53cf7919fa3404c3a46376a7603fe370ddcd1d62dfb977a
+size 106160
diff --git a/audio/loudr-1/dante.opus b/audio/loudr-1/dante.opus
new file mode 100644
index 0000000000000000000000000000000000000000..94d6ac4b4f59836b3e9a7cf1db3fd33ce3f8cb94
Binary files /dev/null and b/audio/loudr-1/dante.opus differ
diff --git a/audio/loudr-1/darkman.opus b/audio/loudr-1/darkman.opus
new file mode 100644
index 0000000000000000000000000000000000000000..ecbb8290553b72ef55fff5d660567048eb4c7041
Binary files /dev/null and b/audio/loudr-1/darkman.opus differ
diff --git a/audio/loudr-1/dave.opus b/audio/loudr-1/dave.opus
new file mode 100644
index 0000000000000000000000000000000000000000..da347c7f320caaef874e803a4bcceedfd4b3a46f
Binary files /dev/null and b/audio/loudr-1/dave.opus differ
diff --git a/audio/loudr-1/emma.opus b/audio/loudr-1/emma.opus
new file mode 100644
index 0000000000000000000000000000000000000000..874bf35266f371977fcdb92cda5c6fdcdd426538
--- /dev/null
+++ b/audio/loudr-1/emma.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a89a1dda44d632f9a32bf08db296e3a17cafb28f73aa7b354f7882c502dd9340
+size 125680
diff --git a/audio/loudr-1/freja.opus b/audio/loudr-1/freja.opus
new file mode 100644
index 0000000000000000000000000000000000000000..e9ccc2b31823a7d34192344d748de7f007dec8e7
Binary files /dev/null and b/audio/loudr-1/freja.opus differ
diff --git a/audio/loudr-1/gosia.opus b/audio/loudr-1/gosia.opus
new file mode 100644
index 0000000000000000000000000000000000000000..f4095ce48cd33a20b61c8d3dca8a86c41578ad20
Binary files /dev/null and b/audio/loudr-1/gosia.opus differ
diff --git a/audio/loudr-1/henri.opus b/audio/loudr-1/henri.opus
new file mode 100644
index 0000000000000000000000000000000000000000..cba778d38e305dfa2ff6a140b408dbe54604dab3
--- /dev/null
+++ b/audio/loudr-1/henri.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3fd1de078ca5bffece9b03b6cc11100a6ea88125ab90ca64337ce0e5ce08fac2
+size 102335
diff --git a/audio/loudr-1/henry.opus b/audio/loudr-1/henry.opus
new file mode 100644
index 0000000000000000000000000000000000000000..39941881a3e0e58cb89cf5c9045f7ac85fa48c0d
--- /dev/null
+++ b/audio/loudr-1/henry.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:816ac99dcadf1b6132675b8e8f9444f19346c13e271bb42c0298735835c7c691
+size 159500
diff --git a/audio/loudr-1/ines.opus b/audio/loudr-1/ines.opus
new file mode 100644
index 0000000000000000000000000000000000000000..ccf90ab9bb38719ee7e5fac5be9f57241291d666
Binary files /dev/null and b/audio/loudr-1/ines.opus differ
diff --git a/audio/loudr-1/joe.opus b/audio/loudr-1/joe.opus
new file mode 100644
index 0000000000000000000000000000000000000000..4fa31f735e27b5c4e4ea015bfa5ae8b26d4e1133
Binary files /dev/null and b/audio/loudr-1/joe.opus differ
diff --git a/audio/loudr-1/kathleen.opus b/audio/loudr-1/kathleen.opus
new file mode 100644
index 0000000000000000000000000000000000000000..8cc3747886a5ee2575df7b47d498f0552a7d781d
Binary files /dev/null and b/audio/loudr-1/kathleen.opus differ
diff --git a/audio/loudr-1/kerstin.opus b/audio/loudr-1/kerstin.opus
new file mode 100644
index 0000000000000000000000000000000000000000..3ba9811ea4544e39b2fbc58830b1940d9e86d679
Binary files /dev/null and b/audio/loudr-1/kerstin.opus differ
diff --git a/audio/loudr-1/lucy.opus b/audio/loudr-1/lucy.opus
new file mode 100644
index 0000000000000000000000000000000000000000..dcb5ed9a4da6aa08f8c3df8267b8e9565945cd3f
--- /dev/null
+++ b/audio/loudr-1/lucy.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:34d32240a95c4765c0e38b12a031f0d054be0d1c29de6739069454523d2b6a5e
+size 124298
diff --git a/audio/loudr-1/miles.opus b/audio/loudr-1/miles.opus
new file mode 100644
index 0000000000000000000000000000000000000000..d51a76b561451b93b5e5a130dd3865fd14c1935c
--- /dev/null
+++ b/audio/loudr-1/miles.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:81734391dc7570f8b632244ee948b2736b7f02b3449ca88522caa5304a1973f0
+size 166129
diff --git a/audio/loudr-1/nathalie.opus b/audio/loudr-1/nathalie.opus
new file mode 100644
index 0000000000000000000000000000000000000000..fe5e6288a66996002252c685f0b940be2525cf44
Binary files /dev/null and b/audio/loudr-1/nathalie.opus differ
diff --git a/audio/loudr-1/nils.opus b/audio/loudr-1/nils.opus
new file mode 100644
index 0000000000000000000000000000000000000000..8ae0cbee9e1875f6dc8c8ba0c1945967706713c2
Binary files /dev/null and b/audio/loudr-1/nils.opus differ
diff --git a/audio/loudr-1/oliver.opus b/audio/loudr-1/oliver.opus
new file mode 100644
index 0000000000000000000000000000000000000000..3dda64b5878e0a712bcca03e18ef2ecee4615a1d
--- /dev/null
+++ b/audio/loudr-1/oliver.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:920cb343127a0bca928c1b67a846dd431f9e63b696210dd693007f8efcaa8319
+size 141153
diff --git a/audio/loudr-1/oscar.opus b/audio/loudr-1/oscar.opus
new file mode 100644
index 0000000000000000000000000000000000000000..29b3b086328e358b2f75c1e96d7619728098071c
--- /dev/null
+++ b/audio/loudr-1/oscar.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e696f00b74d4fe3cc1d89f95d40c6999756f33269b002c50f181c6658667257c
+size 140099
diff --git a/audio/loudr-1/paola.opus b/audio/loudr-1/paola.opus
new file mode 100644
index 0000000000000000000000000000000000000000..b57cb57dc255f60c7f570b7a67fe5af9994d1ebd
Binary files /dev/null and b/audio/loudr-1/paola.opus differ
diff --git a/audio/loudr-1/pim.opus b/audio/loudr-1/pim.opus
new file mode 100644
index 0000000000000000000000000000000000000000..312f86a7af5f07fd46f1d509335a7e0ce60b84a5
Binary files /dev/null and b/audio/loudr-1/pim.opus differ
diff --git a/audio/loudr-1/selma.opus b/audio/loudr-1/selma.opus
new file mode 100644
index 0000000000000000000000000000000000000000..bbe2c88f0778d4bde4a3851c001d0ea5435243e2
Binary files /dev/null and b/audio/loudr-1/selma.opus differ
diff --git a/audio/loudr-1/sophie.opus b/audio/loudr-1/sophie.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6b8e52bf6d081ea001d2762eb93175123d63798f
--- /dev/null
+++ b/audio/loudr-1/sophie.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b44b159cc733894d77a14c97105442092c65d42bb2e2422927af2e631704d149
+size 147289
diff --git a/audio/loudr-1/soren.opus b/audio/loudr-1/soren.opus
new file mode 100644
index 0000000000000000000000000000000000000000..d279b27f828f3050069c1bdb3d8b8d30fe6299c0
Binary files /dev/null and b/audio/loudr-1/soren.opus differ
diff --git a/audio/loudr-1/thorsten.opus b/audio/loudr-1/thorsten.opus
new file mode 100644
index 0000000000000000000000000000000000000000..f257f60bf0929a771adc5663bce78e36bea8ba52
Binary files /dev/null and b/audio/loudr-1/thorsten.opus differ
diff --git a/audio/loudr-1/tugao.opus b/audio/loudr-1/tugao.opus
new file mode 100644
index 0000000000000000000000000000000000000000..a2c6e3c7b6db0b3d0cc98e23498309e98f205f67
Binary files /dev/null and b/audio/loudr-1/tugao.opus differ
diff --git a/audio/nathalie.opus b/audio/nathalie.opus
deleted file mode 100644
index 78d74b015d59796e31d798558ffe6c846d4e5619..0000000000000000000000000000000000000000
Binary files a/audio/nathalie.opus and /dev/null differ
diff --git a/audio/nils.opus b/audio/nils.opus
deleted file mode 100644
index 9f317ca8b1aba3b9aa3dd0e86719cda67125b6d8..0000000000000000000000000000000000000000
Binary files a/audio/nils.opus and /dev/null differ
diff --git a/audio/paola.opus b/audio/paola.opus
deleted file mode 100644
index 6f936ee395156750e75bbb580eb239a62b32eb3a..0000000000000000000000000000000000000000
Binary files a/audio/paola.opus and /dev/null differ
diff --git a/audio/pim.opus b/audio/pim.opus
deleted file mode 100644
index 5d31d74acd05d2cc5a8b191d3c78f06387e1eb05..0000000000000000000000000000000000000000
Binary files a/audio/pim.opus and /dev/null differ
diff --git a/audio/refs/clara.opus b/audio/refs/clara.opus
new file mode 100644
index 0000000000000000000000000000000000000000..05b7aac2d9e1d46accfccfad364417af116e6a6a
Binary files /dev/null and b/audio/refs/clara.opus differ
diff --git a/audio/refs/emma.opus b/audio/refs/emma.opus
new file mode 100644
index 0000000000000000000000000000000000000000..e8a1072534f30cb182b86a1753df08cd4ac7118a
Binary files /dev/null and b/audio/refs/emma.opus differ
diff --git a/audio/refs/henry.opus b/audio/refs/henry.opus
new file mode 100644
index 0000000000000000000000000000000000000000..1f5c6a4b35067f6a0a4facc4b350a721a51814fa
Binary files /dev/null and b/audio/refs/henry.opus differ
diff --git a/audio/refs/lucy.opus b/audio/refs/lucy.opus
new file mode 100644
index 0000000000000000000000000000000000000000..0436e6ba4ce50ecf3a9340655e1afdb62662bb9d
Binary files /dev/null and b/audio/refs/lucy.opus differ
diff --git a/audio/refs/miles.opus b/audio/refs/miles.opus
new file mode 100644
index 0000000000000000000000000000000000000000..02fa84c1795d7989fbf657c3f8e0b8ea13341bcf
Binary files /dev/null and b/audio/refs/miles.opus differ
diff --git a/audio/refs/oliver.opus b/audio/refs/oliver.opus
new file mode 100644
index 0000000000000000000000000000000000000000..babe0eda0dc44aa03e9f29fc429f508b918ef565
Binary files /dev/null and b/audio/refs/oliver.opus differ
diff --git a/audio/refs/oscar.opus b/audio/refs/oscar.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6df38c5ead748b0f21937c10e034a373b0176d32
Binary files /dev/null and b/audio/refs/oscar.opus differ
diff --git a/audio/refs/sophie.opus b/audio/refs/sophie.opus
new file mode 100644
index 0000000000000000000000000000000000000000..7e5505834520f7e1000d483c8c227fca27f69597
Binary files /dev/null and b/audio/refs/sophie.opus differ
diff --git a/audio/selma.opus b/audio/selma.opus
deleted file mode 100644
index 635b80f10f7832625903ac39d8bf0e831df43eb8..0000000000000000000000000000000000000000
Binary files a/audio/selma.opus and /dev/null differ
diff --git a/audio/soren.opus b/audio/soren.opus
deleted file mode 100644
index 2ed33a17736947e4ed72c1b4c5fc05b93cc548a9..0000000000000000000000000000000000000000
Binary files a/audio/soren.opus and /dev/null differ
diff --git a/audio/thorsten.opus b/audio/thorsten.opus
deleted file mode 100644
index 278cbffa5785f98db6cd5fa1394f1eff47e6f5ef..0000000000000000000000000000000000000000
Binary files a/audio/thorsten.opus and /dev/null differ
diff --git a/audio/tugao.opus b/audio/tugao.opus
deleted file mode 100644
index 71f242f67742e53eecfaeb6363a4779696d3d48c..0000000000000000000000000000000000000000
Binary files a/audio/tugao.opus and /dev/null differ
diff --git a/audio/turbo/carmen.opus b/audio/turbo/carmen.opus
new file mode 100644
index 0000000000000000000000000000000000000000..1b2957a57dcff7c7cd543fe6afc47c6cfb671de9
Binary files /dev/null and b/audio/turbo/carmen.opus differ
diff --git a/audio/turbo/clara.opus b/audio/turbo/clara.opus
new file mode 100644
index 0000000000000000000000000000000000000000..90142829857bd6f95d2eaab9d51c6ff5a9874c07
--- /dev/null
+++ b/audio/turbo/clara.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eacd85010a58d5284f791f203179662e9a2193ff6faef492ec80628dba90d725
+size 131336
diff --git a/audio/turbo/colette.opus b/audio/turbo/colette.opus
new file mode 100644
index 0000000000000000000000000000000000000000..39d49d739cf0731c1c731b2bf9180dbccb4af7cb
Binary files /dev/null and b/audio/turbo/colette.opus differ
diff --git a/audio/turbo/dante.opus b/audio/turbo/dante.opus
new file mode 100644
index 0000000000000000000000000000000000000000..3a31484d41f118f74f5b57e692c80a5cba3ce360
Binary files /dev/null and b/audio/turbo/dante.opus differ
diff --git a/audio/turbo/darkman.opus b/audio/turbo/darkman.opus
new file mode 100644
index 0000000000000000000000000000000000000000..d07bef9aee96cf210ffcc56b44c18c4a5433d419
Binary files /dev/null and b/audio/turbo/darkman.opus differ
diff --git a/audio/turbo/dave.opus b/audio/turbo/dave.opus
new file mode 100644
index 0000000000000000000000000000000000000000..f3a23e9d7b45dfc81bb80225e39cf56488694966
Binary files /dev/null and b/audio/turbo/dave.opus differ
diff --git a/audio/turbo/emma.opus b/audio/turbo/emma.opus
new file mode 100644
index 0000000000000000000000000000000000000000..72009b83dcfecaa167b13c06b9093bfe90a775e8
--- /dev/null
+++ b/audio/turbo/emma.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:472a6769bc226c0eea35928380065468666e752dd194c88931526501bdb4af1b
+size 135104
diff --git a/audio/turbo/freja.opus b/audio/turbo/freja.opus
new file mode 100644
index 0000000000000000000000000000000000000000..bea35980af29dcdbe1b8e33e3fb2e9170bdc8f59
Binary files /dev/null and b/audio/turbo/freja.opus differ
diff --git a/audio/turbo/gosia.opus b/audio/turbo/gosia.opus
new file mode 100644
index 0000000000000000000000000000000000000000..886120ba7d1fccfb6d7ee4e7b24786caf1678185
Binary files /dev/null and b/audio/turbo/gosia.opus differ
diff --git a/audio/turbo/henri.opus b/audio/turbo/henri.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6262f715a1a7febe16daa23362fd0452b1d5581b
Binary files /dev/null and b/audio/turbo/henri.opus differ
diff --git a/audio/turbo/henry.opus b/audio/turbo/henry.opus
new file mode 100644
index 0000000000000000000000000000000000000000..c539baa92955fc77c6a2ee917d7c76c78a720185
--- /dev/null
+++ b/audio/turbo/henry.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:59e5911d5173e49f82b0ff73dca1aa38003caf7824b6c967e348e6c6bf199b43
+size 150977
diff --git a/audio/turbo/ines.opus b/audio/turbo/ines.opus
new file mode 100644
index 0000000000000000000000000000000000000000..4b2511af5bb01fcf04e2a22a0a169d9bccbc9332
Binary files /dev/null and b/audio/turbo/ines.opus differ
diff --git a/audio/turbo/joe.opus b/audio/turbo/joe.opus
new file mode 100644
index 0000000000000000000000000000000000000000..01230cfd62759fba682ce09344eefe11765b57cb
Binary files /dev/null and b/audio/turbo/joe.opus differ
diff --git a/audio/turbo/kathleen.opus b/audio/turbo/kathleen.opus
new file mode 100644
index 0000000000000000000000000000000000000000..44ba82ad47daf81b630a634c268d125f2edd2afb
Binary files /dev/null and b/audio/turbo/kathleen.opus differ
diff --git a/audio/turbo/kerstin.opus b/audio/turbo/kerstin.opus
new file mode 100644
index 0000000000000000000000000000000000000000..ee3d7ad43cd89e8b119fdfa95bfcfe1472fbb330
Binary files /dev/null and b/audio/turbo/kerstin.opus differ
diff --git a/audio/turbo/lucy.opus b/audio/turbo/lucy.opus
new file mode 100644
index 0000000000000000000000000000000000000000..82f66098b860724c93cd62497a9ad6c6d7cef700
--- /dev/null
+++ b/audio/turbo/lucy.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:edff4443386a2f1ae3a42d041a6ce618aabc62ca3a5bde67196ddf2c510c1cb7
+size 132487
diff --git a/audio/turbo/miles.opus b/audio/turbo/miles.opus
new file mode 100644
index 0000000000000000000000000000000000000000..2c0a69af0cfe6d128ffa9c015a89fc6dd667134c
--- /dev/null
+++ b/audio/turbo/miles.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:69d3baba24893ebc92f8f22b5f2662a2b883b8a4ddd72e809201886b96a33db0
+size 148291
diff --git a/audio/turbo/nathalie.opus b/audio/turbo/nathalie.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6ae2b9566cea8ed66fdb8ee008e216ff2a222ccb
Binary files /dev/null and b/audio/turbo/nathalie.opus differ
diff --git a/audio/turbo/nils.opus b/audio/turbo/nils.opus
new file mode 100644
index 0000000000000000000000000000000000000000..ea220071b9f83b53c1b37502a30fb5c1cd206476
Binary files /dev/null and b/audio/turbo/nils.opus differ
diff --git a/audio/turbo/oliver.opus b/audio/turbo/oliver.opus
new file mode 100644
index 0000000000000000000000000000000000000000..e49ab917536975ba2960782f0c2979741fbc1287
--- /dev/null
+++ b/audio/turbo/oliver.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2d5491f63cde1a062cbf6660ea72b5186a11024984393620d4d419dad5e19051
+size 133884
diff --git a/audio/turbo/oscar.opus b/audio/turbo/oscar.opus
new file mode 100644
index 0000000000000000000000000000000000000000..b4a48046307d2094b05eb31e060a470cbef740f2
--- /dev/null
+++ b/audio/turbo/oscar.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f41367b20ae17f5a22664d8ef6a5679277b078bceda85c40e462718a77305cbc
+size 143352
diff --git a/audio/turbo/paola.opus b/audio/turbo/paola.opus
new file mode 100644
index 0000000000000000000000000000000000000000..27ba766f68e060c1d709e5002d6efb6c15fb89aa
Binary files /dev/null and b/audio/turbo/paola.opus differ
diff --git a/audio/turbo/pim.opus b/audio/turbo/pim.opus
new file mode 100644
index 0000000000000000000000000000000000000000..9e3d6851c3f4397b03cd44c121fb6f132baa99bd
Binary files /dev/null and b/audio/turbo/pim.opus differ
diff --git a/audio/turbo/selma.opus b/audio/turbo/selma.opus
new file mode 100644
index 0000000000000000000000000000000000000000..1de64113838acaa07e6f53fea0f10d4c4793575e
Binary files /dev/null and b/audio/turbo/selma.opus differ
diff --git a/audio/turbo/sophie.opus b/audio/turbo/sophie.opus
new file mode 100644
index 0000000000000000000000000000000000000000..f13c5abb6f6bce0c8fe46c584716b5a2050b000e
--- /dev/null
+++ b/audio/turbo/sophie.opus
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2babb4fb7bb87d53258dcbb2ef1b77fa004929afa5991f7cd9e9907b0cc03091
+size 144182
diff --git a/audio/turbo/soren.opus b/audio/turbo/soren.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6bb5953435b53aa740ad7f4f5176296ec31fcf44
Binary files /dev/null and b/audio/turbo/soren.opus differ
diff --git a/audio/turbo/thorsten.opus b/audio/turbo/thorsten.opus
new file mode 100644
index 0000000000000000000000000000000000000000..1001499726298d48ef3fbfbe25a4e5e3677505a2
Binary files /dev/null and b/audio/turbo/thorsten.opus differ
diff --git a/audio/turbo/tugao.opus b/audio/turbo/tugao.opus
new file mode 100644
index 0000000000000000000000000000000000000000..6bd9090c836178b83bd5166d8a120ed97a133221
Binary files /dev/null and b/audio/turbo/tugao.opus differ
diff --git a/requirements.txt b/requirements.txt
index 60b4bdb741c3b04aa1bb164e82cbfb4bbb071a24..84c5e82d082536668f81755a086d29ebe7167cbb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,12 @@
-# The library under demo. 0.1.0 is on PyPI, so this installs from the registry
-# rather than carrying a wheel beside the app.
+# The library under demo. 0.1.1 is the release these two bundles belong to; the
+# Space cannot run on 0.1.0, whose engine computes a different fingerprint from
+# the one the published export records name.
#
# torch the cuda backend this Space runs on
# audio soundfile, for Result.save
# enroll torchaudio + librosa, for the Clone tab
-# hub huggingface_hub, to resolve loudreader/loudr-1
-loudkit[torch,audio,enroll,hub]==0.1.0
+# hub huggingface_hub, to resolve both model repositories
+loudkit[torch,audio,enroll,hub]==0.1.1
# loudkit floors torch at >=2.4 and sets no ceiling, and ZeroGPU runs a fixed
# set of builds: 2.8.0, 2.9.1, 2.10.0, 2.11.0. Pinned here so the resolver
diff --git a/voices.json b/voices.json
index ac89f1f9159d32cd3c35686f32448d57a27284b2..4a095d1f1148db14f86d2636dcc699d186a27691 100644
--- a/voices.json
+++ b/voices.json
@@ -1,4 +1,167 @@
[
+ {
+ "name": "carmen",
+ "language": "Spanish",
+ "language_id": "es",
+ "gender": "F",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "2308",
+ "source": {
+ "name": "CML-TTS (LibriVox-derived, ylacombe/cml-tts on Hugging Face)",
+ "url": "https://huggingface.co/datasets/ylacombe/cml-tts",
+ "license": "CC-BY-4.0",
+ "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "carmen.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/carmen.opus",
+ "duration_s": 14.37,
+ "construction": "single continuous clip"
+ },
+ "profile": {
+ "hf_path": "voices/carmen.safetensors",
+ "sha256": "c9387f3bc58e8e1dd41700339e886a546200597fe629e523282ba4dbd4ddc069"
+ },
+ "speaker_similarity": null,
+ "sample": {
+ "seed": 7,
+ "text": "Subió una mona a un nogal, y cogiendo una nuez verde, en la cáscara la muerde, con que le supo muy mal.",
+ "work": "La mona (Felix Maria de Samaniego) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/carmen.opus",
+ "turbo": "audio/turbo/carmen.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "clara",
+ "language": "English",
+ "language_id": "en",
+ "gender": "F",
+ "donor": "clara (product alias, not donor identity)",
+ "speaker_id": "bathri",
+ "source": {
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/bathri.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "bathri",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "3177c7f139851b85ab78886701bd957e07eb4fcb45a507c17310cbc977747d70",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
+ },
+ "reference": {
+ "source_filename": "clara.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/clara.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
+ },
+ "profile": {
+ "hf_path": "voices/clara.safetensors",
+ "sha256": "c2b5db4c210657d6b2b81602fae8e73a733ac4312f33e80536a59a874e7d865f"
+ },
+ "speaker_similarity": 0.9098672866821289,
+ "sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/clara.opus",
+ "turbo": "audio/turbo/clara.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
+ "seed": 7,
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "c2b5db4c210657d6b2b81602fae8e73a733ac4312f33e80536a59a874e7d865f",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 16.08,
+ "gain_db": 2.539999999999999,
+ "work": "Shared English comparison story — original text"
+ }
+ },
+ {
+ "name": "colette",
+ "language": "French",
+ "language_id": "fr",
+ "gender": "F",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "1406",
+ "source": {
+ "name": "Kyutai tts-voices, cml-tts french enhanced references",
+ "url": "https://huggingface.co/kyutai/tts-voices",
+ "license": "CC-BY-4.0",
+ "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "colette.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/colette.opus",
+ "duration_s": 7.24,
+ "construction": "pre-cut enhanced 10 s reference"
+ },
+ "profile": {
+ "hf_path": "voices/colette.safetensors",
+ "sha256": "bdccafdc54f700cb456e3f531d0f9da3e5cc0c9fcece8284db44773f99c162c9"
+ },
+ "speaker_similarity": null,
+ "sample": {
+ "seed": 7,
+ "text": "Maître Corbeau, sur un arbre perché, tenait en son bec un fromage. Maître Renard, par l'odeur alléché, lui tint à peu près ce langage: Hé! bonjour, Monsieur du Corbeau.",
+ "work": "Le Corbeau et le Renard (Jean de La Fontaine) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/colette.opus",
+ "turbo": "audio/turbo/colette.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "dante",
+ "language": "Italian",
+ "language_id": "it",
+ "gender": "M",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "12598",
+ "source": {
+ "name": "Multilingual LibriSpeech (facebook/multilingual_librispeech)",
+ "url": "https://huggingface.co/datasets/facebook/multilingual_librispeech",
+ "license": "CC-BY-4.0",
+ "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "dante.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/dante.opus",
+ "duration_s": 14.0,
+ "construction": "single continuous clip"
+ },
+ "profile": {
+ "hf_path": "voices/dante.safetensors",
+ "sha256": "d0ba2cf9871b7f933ff5f0dbdca9578077599c2e8209fc6246727edd79c15924"
+ },
+ "speaker_similarity": null,
+ "sample": {
+ "seed": 7,
+ "text": "C'era una volta... Un re! diranno subito i miei piccoli lettori. No, ragazzi, avete sbagliato: c'era una volta un pezzo di legno.",
+ "work": "Le avventure di Pinocchio (Carlo Collodi) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/dante.opus",
+ "turbo": "audio/turbo/dante.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
{
"name": "darkman",
"language": "Polish",
@@ -16,7 +179,6 @@
"source_filename": "darkman.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/darkman.opus",
- "sha256": "d228db9d17b1ddb4ba450f16a6b8650bb0a8550521b78a914cb9e573cd24d576",
"duration_s": 9.78,
"construction": "concatenated donation clips, 120 ms gaps"
},
@@ -29,8 +191,138 @@
"seed": 7,
"text": "Petroniusz obudził się zaledwie koło południa, a jak zwykle, zmęczony bardzo.",
"work": "Quo Vadis (Henryk Sienkiewicz) — public domain",
- "audio": "audio/darkman.opus",
- "sha256": "b30f98cf0452e9c694fcbafc27b413041c87022238f5424fc1aa452c8eb156a5"
+ "audio": {
+ "loudr-1": "audio/loudr-1/darkman.opus",
+ "turbo": "audio/turbo/darkman.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "dave",
+ "language": "Spanish",
+ "language_id": "es",
+ "gender": "M",
+ "donor": "dave (donor alias)",
+ "speaker_id": null,
+ "source": {
+ "name": "Home Assistant / Piper voice-datasets (voice donations recorded for TTS)",
+ "url": "https://github.com/NabuCasa/voice-datasets",
+ "license": "CC0-1.0",
+ "consent": "recorded and donated expressly for building TTS voices"
+ },
+ "reference": {
+ "source_filename": "dave.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/dave.opus",
+ "duration_s": 11.0,
+ "construction": "concatenated donation clips, 120 ms gaps"
+ },
+ "profile": {
+ "hf_path": "voices/dave.safetensors",
+ "sha256": "14b5e58a6e5a457b516f5a9ae02d3a739449a02a92d0791b356377b68c366cb4"
+ },
+ "speaker_similarity": null,
+ "sample": {
+ "seed": 7,
+ "text": "Subió una mona a un nogal, y cogiendo una nuez verde, en la cáscara la muerde, con que le supo muy mal.",
+ "work": "La mona (Felix Maria de Samaniego) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/dave.opus",
+ "turbo": "audio/turbo/dave.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "emma",
+ "language": "English",
+ "language_id": "en",
+ "gender": "F",
+ "donor": "emma (product alias, not donor identity)",
+ "speaker_id": "awais_shah",
+ "source": {
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/awais_shah.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "awais_shah",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "0933f6959eaff9b81a06b99ba4b4388ff069d1813f159fb9a24a6fb73bf89afb",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
+ },
+ "reference": {
+ "source_filename": "emma.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/emma.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
+ },
+ "profile": {
+ "hf_path": "voices/emma.safetensors",
+ "sha256": "0f5d8bfaceca353ca92db751c48b6a1653823f421ead3c901efe6366b8fa2dfb"
+ },
+ "speaker_similarity": 0.8317757844924927,
+ "sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/emma.opus",
+ "turbo": "audio/turbo/emma.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
+ "seed": 7,
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "0f5d8bfaceca353ca92db751c48b6a1653823f421ead3c901efe6366b8fa2dfb",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 14.88,
+ "gain_db": 4.09,
+ "work": "Shared English comparison story — original text"
+ }
+ },
+ {
+ "name": "freja",
+ "language": "Danish",
+ "language_id": "da",
+ "gender": "F",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "35",
+ "source": {
+ "name": "NST Danish speech database (alexandrainst/nst-da on Hugging Face)",
+ "url": "https://huggingface.co/datasets/alexandrainst/nst-da",
+ "license": "CC0-1.0",
+ "consent": "corpus released CC0; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "freja.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/freja.opus",
+ "duration_s": 8.78,
+ "construction": "single continuous clip, close mic"
+ },
+ "profile": {
+ "hf_path": "voices/freja.safetensors",
+ "sha256": "0a3f913b9b47c529393f843850228bd8eee6a883b4c138978fd3afa7758561e8"
+ },
+ "speaker_similarity": 0.907,
+ "sample": {
+ "seed": 7,
+ "text": "Der var så dejligt ude på landet; det var sommer, kornet stod gult, og havren grøn.",
+ "work": "Den grimme aelling (H. C. Andersen) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/freja.opus",
+ "turbo": "audio/turbo/freja.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
@@ -50,7 +342,6 @@
"source_filename": "gosia.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/gosia.opus",
- "sha256": "02c1d09db8b097c66dd8705747a6ef138596f5f91c3213b1cd430ae75ca2279a",
"duration_s": 10.86,
"construction": "concatenated long donation clips, 120 ms gaps"
},
@@ -63,10 +354,141 @@
"seed": 7,
"text": "Petroniusz obudził się zaledwie koło południa, a jak zwykle, zmęczony bardzo.",
"work": "Quo Vadis (Henryk Sienkiewicz) — public domain",
- "audio": "audio/gosia.opus",
- "sha256": "4ba1107d7f807ac2e0941167d1bc4a7cfb2039a4b0482a3bc798db5eeefe17e5"
+ "audio": {
+ "loudr-1": "audio/loudr-1/gosia.opus",
+ "turbo": "audio/turbo/gosia.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "henri",
+ "language": "French",
+ "language_id": "fr",
+ "gender": "M",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "10087",
+ "source": {
+ "name": "Kyutai tts-voices, cml-tts french enhanced references",
+ "url": "https://huggingface.co/kyutai/tts-voices",
+ "license": "CC-BY-4.0",
+ "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "henri.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/henri.opus",
+ "duration_s": 6.56,
+ "construction": "pre-cut enhanced 10 s reference"
+ },
+ "profile": {
+ "hf_path": "voices/henri.safetensors",
+ "sha256": "2be79463e8a2cfe339a7d6088e397c22be4430c6796e76362a0f33f351bf940a"
+ },
+ "speaker_similarity": null,
+ "sample": {
+ "seed": 7,
+ "text": "Maître Corbeau, sur un arbre perché, tenait en son bec un fromage. Maître Renard, par l'odeur alléché, lui tint à peu près ce langage: Hé! bonjour, Monsieur du Corbeau.",
+ "work": "Le Corbeau et le Renard (Jean de La Fontaine) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/henri.opus",
+ "turbo": "audio/turbo/henri.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "henry",
+ "language": "English",
+ "language_id": "en",
+ "gender": "M",
+ "donor": "henry (product alias, not donor identity)",
+ "speaker_id": "Dil",
+ "source": {
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/Dil.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "Dil",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "328d1e3ad60a208df41b297401df2e2e9f12b15a75b3d24f3bc1f220b24d6eb5",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
+ },
+ "reference": {
+ "source_filename": "henry.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/henry.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
+ },
+ "profile": {
+ "hf_path": "voices/henry.safetensors",
+ "sha256": "5476670162065397f01fca60a1944eb75ddef8dc7e6792dde7fb603c76c14d8c"
+ },
+ "speaker_similarity": 0.8834202885627747,
+ "sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/henry.opus",
+ "turbo": "audio/turbo/henry.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
+ "seed": 7,
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "5476670162065397f01fca60a1944eb75ddef8dc7e6792dde7fb603c76c14d8c",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 16.8,
+ "gain_db": -1.6700000000000017,
+ "work": "Shared English comparison story — original text"
}
},
+ {
+ "name": "ines",
+ "language": "Portuguese (Brazilian)",
+ "language_id": "pt",
+ "gender": "F",
+ "donor": "anonymous (invented name)",
+ "speaker_id": "7925",
+ "source": {
+ "name": "CML-TTS (LibriVox-derived, ylacombe/cml-tts on Hugging Face)",
+ "url": "https://huggingface.co/datasets/ylacombe/cml-tts",
+ "license": "CC-BY-4.0",
+ "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ },
+ "reference": {
+ "source_filename": "ines.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/ines.opus",
+ "duration_s": 10.44,
+ "construction": "single continuous clip"
+ },
+ "profile": {
+ "hf_path": "voices/ines.safetensors",
+ "sha256": "b7f76b52170dfcdcef0e8835956967bf2fbc4973883b6e99d6b2be7fd4f3a496"
+ },
+ "speaker_similarity": 0.96,
+ "sample": {
+ "seed": 7,
+ "text": "O meu amigo Jacinto nasceu num palácio, com cento e nove contos de renda em terras de semeadura, de vinhedo, de cortiça e de olival.",
+ "work": "A Cidade e as Serras (Eca de Queiros) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/ines.opus",
+ "turbo": "audio/turbo/ines.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ },
+ "notes": "CML-TTS is LibriVox-derived and its Portuguese split is Brazilian, unlike tugao (European). The language field above read 'Portuguese (European)' and contradicted this note; the note is the accurate one, and the record now agrees with itself. language_id stays pt: there is one Portuguese grammar."
+ },
{
"name": "joe",
"language": "English",
@@ -84,7 +506,6 @@
"source_filename": "joe.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/joe.opus",
- "sha256": "591c8d6a5799a4266d029762dc0f671ac9f0455382aeef1e763ca206d6fdd164",
"duration_s": 10.99,
"construction": "concatenated donation clips, 120 ms gaps"
},
@@ -94,11 +515,17 @@
},
"speaker_similarity": 0.924,
"sample": {
- "seed": 11,
+ "seed": 7,
"text": "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading.",
"work": "Alice's Adventures in Wonderland (Lewis Carroll) — public domain",
- "audio": "audio/joe.opus",
- "sha256": "83e0bf0a1f6b03e047de66871536c3ff77291041d0a3f2907b6990e580519fea"
+ "audio": {
+ "loudr-1": "audio/loudr-1/joe.opus",
+ "turbo": "audio/turbo/joe.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
@@ -118,7 +545,6 @@
"source_filename": "kathleen.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/kathleen.opus",
- "sha256": "f43a24359a333e1f723c5f10d7dc799ec5880abf2b5b9321a7d5f8c7064d6f73",
"duration_s": 11.0,
"construction": "concatenated donation clips; prompt texts from the CMU ARCTIC prompt list (public-domain Gutenberg novels), recording is kathleen's own CC0 donation"
},
@@ -131,42 +557,14 @@
"seed": 7,
"text": "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading.",
"work": "Alice's Adventures in Wonderland (Lewis Carroll) — public domain",
- "audio": "audio/kathleen.opus",
- "sha256": "48615517c1d1d2d55dbb7f74f37982918236e33f079947459d56c116cd70b7a3"
- }
- },
- {
- "name": "thorsten",
- "language": "German",
- "language_id": "de",
- "gender": "M",
- "donor": "Thorsten Mueller",
- "speaker_id": null,
- "source": {
- "name": "Thorsten-Voice TV-44kHz-Full",
- "url": "https://huggingface.co/datasets/Thorsten-Voice/TV-44kHz-Full",
- "license": "CC0-1.0",
- "consent": "voice deliberately donated by Thorsten Mueller for TTS"
- },
- "reference": {
- "source_filename": "thorsten.wav",
- "published_in_model_repo": false,
- "public_preview": "audio/refs/thorsten.opus",
- "sha256": "37805d1136f727f7530e714b772c23224ae1c6f6931ea5b78399cf286694de3e",
- "duration_s": 6.37,
- "construction": "single continuous clip"
- },
- "profile": {
- "hf_path": "voices/thorsten.safetensors",
- "sha256": "87873fec8d3dceaa643ab1ab07cf5143364e659dd6b3caec707f51408ac2154a"
- },
- "speaker_similarity": null,
- "sample": {
- "seed": 7,
- "text": "Ach, was muss man oft von bösen Kindern hören oder lesen! Wie zum Beispiel hier von diesen, welche Max und Moritz hießen.",
- "work": "Max und Moritz (Wilhelm Busch) — public domain",
- "audio": "audio/thorsten.opus",
- "sha256": "d45938440534f7fa11afe388fa41a9a56879809a65c8477605220ed53d5a938b"
+ "audio": {
+ "loudr-1": "audio/loudr-1/kathleen.opus",
+ "turbo": "audio/turbo/kathleen.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
@@ -186,7 +584,6 @@
"source_filename": "kerstin.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/kerstin.opus",
- "sha256": "34d7c0db776bcda98e56bc130ced840debe0b12a73f4b03c556b30fc356db187",
"duration_s": 9.79,
"construction": "single continuous clip"
},
@@ -199,110 +596,106 @@
"seed": 7,
"text": "Ach, was muss man oft von bösen Kindern hören oder lesen! Wie zum Beispiel hier von diesen, welche Max und Moritz hießen.",
"work": "Max und Moritz (Wilhelm Busch) — public domain",
- "audio": "audio/kerstin.opus",
- "sha256": "dc1990efd85eafee75810f45fd259505d4840579f008aba9f38ca1a7c42e839b"
+ "audio": {
+ "loudr-1": "audio/loudr-1/kerstin.opus",
+ "turbo": "audio/turbo/kerstin.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "henri",
- "language": "French",
- "language_id": "fr",
- "gender": "M",
- "donor": "anonymous (invented name)",
- "speaker_id": "10087",
- "source": {
- "name": "Kyutai tts-voices, cml-tts french enhanced references",
- "url": "https://huggingface.co/kyutai/tts-voices",
- "license": "CC-BY-4.0",
- "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
- },
- "reference": {
- "source_filename": "henri.wav",
- "published_in_model_repo": false,
- "public_preview": "audio/refs/henri.opus",
- "sha256": "9185f21daf7bcbb9a53ea06b059438ea83b7315ef4f852d69d56afc562061fc0",
- "duration_s": 6.56,
- "construction": "pre-cut enhanced 10 s reference"
- },
- "profile": {
- "hf_path": "voices/henri.safetensors",
- "sha256": "2be79463e8a2cfe339a7d6088e397c22be4430c6796e76362a0f33f351bf940a"
- },
- "speaker_similarity": null,
- "sample": {
- "seed": 7,
- "text": "Maître Corbeau, sur un arbre perché, tenait en son bec un fromage. Maître Renard, par l'odeur alléché, lui tint à peu près ce langage: Hé! bonjour, Monsieur du Corbeau.",
- "work": "Le Corbeau et le Renard (Jean de La Fontaine) — public domain",
- "audio": "audio/henri.opus",
- "sha256": "9a63ac8258c23aa750c871b4cc050da5658cd44b77448aad3cf1caef5ecb047b"
- }
- },
- {
- "name": "colette",
- "language": "French",
- "language_id": "fr",
+ "name": "lucy",
+ "language": "English",
+ "language_id": "en",
"gender": "F",
- "donor": "anonymous (invented name)",
- "speaker_id": "1406",
+ "donor": "lucy (product alias, not donor identity)",
+ "speaker_id": "Haku",
"source": {
- "name": "Kyutai tts-voices, cml-tts french enhanced references",
- "url": "https://huggingface.co/kyutai/tts-voices",
- "license": "CC-BY-4.0",
- "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/Haku.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "Haku",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "50184ec3a337a1aed0e3dd59a09eac77819694ca308f2a2a3facff6db9b10a59",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
},
"reference": {
- "source_filename": "colette.wav",
+ "source_filename": "lucy.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/colette.opus",
- "sha256": "324d657ffdc1d1651e9da4ad57258b1c54ee429b437f909ac29130e78cee21a9",
- "duration_s": 7.24,
- "construction": "pre-cut enhanced 10 s reference"
+ "public_preview": "audio/refs/lucy.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
},
"profile": {
- "hf_path": "voices/colette.safetensors",
- "sha256": "bdccafdc54f700cb456e3f531d0f9da3e5cc0c9fcece8284db44773f99c162c9"
+ "hf_path": "voices/lucy.safetensors",
+ "sha256": "009a5fe1b34a9c65b09254f41c01cfdc641ec671a83449ad8aa77dd933d5f27e"
},
- "speaker_similarity": null,
+ "speaker_similarity": 0.8895525336265564,
"sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/lucy.opus",
+ "turbo": "audio/turbo/lucy.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
"seed": 7,
- "text": "Maître Corbeau, sur un arbre perché, tenait en son bec un fromage. Maître Renard, par l'odeur alléché, lui tint à peu près ce langage: Hé! bonjour, Monsieur du Corbeau.",
- "work": "Le Corbeau et le Renard (Jean de La Fontaine) — public domain",
- "audio": "audio/colette.opus",
- "sha256": "e9f0084bb45e1b7647eec082dc03f43a110e10f915a2baf99d5776201ec664bd"
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "009a5fe1b34a9c65b09254f41c01cfdc641ec671a83449ad8aa77dd933d5f27e",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 14.36,
+ "gain_db": 4.73,
+ "work": "Shared English comparison story — original text"
}
},
{
- "name": "pim",
- "language": "Dutch",
- "language_id": "nl",
+ "name": "miles",
+ "language": "English",
+ "language_id": "en",
"gender": "M",
- "donor": "pim (donor alias)",
- "speaker_id": null,
+ "donor": "miles (product alias, not donor identity)",
+ "speaker_id": "fc96",
"source": {
- "name": "Home Assistant / Piper voice-datasets (voice donations recorded for TTS)",
- "url": "https://github.com/NabuCasa/voice-datasets",
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/fc96.wav",
"license": "CC0-1.0",
- "consent": "recorded and donated expressly for building TTS voices"
+ "speaker_id": "fc96",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "b768f4f59d9ad2ccd2c944ae4179240cfa7aebe1f38cdaacec52a3fb27e31541",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
},
"reference": {
- "source_filename": "pim.wav",
+ "source_filename": "miles.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/pim.opus",
- "sha256": "b7428579a45f688ebf6602fd94e6a92dfe34b20cf34e7aae3c73fb73b2182d29",
- "duration_s": 11.0,
- "construction": "concatenated donation clips, 120 ms gaps"
+ "public_preview": "audio/refs/miles.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
},
"profile": {
- "hf_path": "voices/pim.safetensors",
- "sha256": "05c5b3bd921240acc39cc8ffd576ab71dcbc36e6238ce468292ae74c61190130"
+ "hf_path": "voices/miles.safetensors",
+ "sha256": "184d5552881d2e6fd644f0546d9b470130664d84faf39a31979001cafe8f4ed9"
},
- "speaker_similarity": null,
+ "speaker_similarity": 0.9399194717407227,
"sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/miles.opus",
+ "turbo": "audio/turbo/miles.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
"seed": 7,
- "text": "Jantje zag eens pruimen hangen, o! als eieren zo groot. 't Scheen, dat Jantje wou gaan plukken, schoon zijn vader 't hem verbood.",
- "work": "De pruimeboom (Hieronymus van Alphen) — public domain",
- "audio": "audio/pim.opus",
- "sha256": "c00535642d18623f4d2085fa0bde17bdd08c7c8b9b38ade8a85dfee7b9974b37"
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "184d5552881d2e6fd644f0546d9b470130664d84faf39a31979001cafe8f4ed9",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 15.48,
+ "gain_db": -4.170000000000002,
+ "work": "Shared English comparison story — original text"
}
},
{
@@ -322,7 +715,6 @@
"source_filename": "nathalie.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/nathalie.opus",
- "sha256": "bc09a866b18264d555a35522e3319ff820914f59a8c3dd8687c01ee16203e5fd",
"duration_s": 10.8,
"construction": "concatenated donation clips, 120 ms gaps"
},
@@ -335,110 +727,145 @@
"seed": 7,
"text": "Jantje zag eens pruimen hangen, o! als eieren zo groot. 't Scheen, dat Jantje wou gaan plukken, schoon zijn vader 't hem verbood.",
"work": "De pruimeboom (Hieronymus van Alphen) — public domain",
- "audio": "audio/nathalie.opus",
- "sha256": "d2bf4970c1cf1d8f4437ee183e67ed5d1f67683249d26e36c6bf7cf3904490da"
+ "audio": {
+ "loudr-1": "audio/loudr-1/nathalie.opus",
+ "turbo": "audio/turbo/nathalie.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "dave",
- "language": "Spanish",
- "language_id": "es",
+ "name": "nils",
+ "language": "Swedish",
+ "language_id": "sv",
"gender": "M",
- "donor": "dave (donor alias)",
+ "donor": "anonymous (invented name)",
"speaker_id": null,
"source": {
- "name": "Home Assistant / Piper voice-datasets (voice donations recorded for TTS)",
- "url": "https://github.com/NabuCasa/voice-datasets",
+ "name": "NST Swedish speech database (Sprakbanken, National Library of Norway)",
+ "url": "https://www.nb.no/sprakbanken/en/resource-catalogue/oai-nb-no-sbr-17/",
"license": "CC0-1.0",
- "consent": "recorded and donated expressly for building TTS voices"
+ "consent": "corpus released CC0 by Sprakbanken; anonymous speaker id, invented voice name"
},
"reference": {
- "source_filename": "dave.wav",
+ "source_filename": "nils.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/dave.opus",
- "sha256": "9e30010eafeb37abb20a9976e17bfa3d313f779d5703bba9a536791916b162d6",
+ "public_preview": "audio/refs/nils.opus",
"duration_s": 11.0,
- "construction": "concatenated donation clips, 120 ms gaps"
+ "construction": "single continuous clip"
},
"profile": {
- "hf_path": "voices/dave.safetensors",
- "sha256": "14b5e58a6e5a457b516f5a9ae02d3a739449a02a92d0791b356377b68c366cb4"
+ "hf_path": "voices/nils.safetensors",
+ "sha256": "be75721c99547ab3ecdf1f8629101e9fa3ea1d569fc6e1220b8e2f259fb49f4e"
},
- "speaker_similarity": null,
+ "speaker_similarity": 0.92,
"sample": {
"seed": 7,
- "text": "Subió una mona a un nogal, y cogiendo una nuez verde, en la cáscara la muerde, con que le supo muy mal.",
- "work": "La mona (Felix Maria de Samaniego) — public domain",
- "audio": "audio/dave.opus",
- "sha256": "c1240b63c1f83b5279dccd028c18410d4051f590e695199a91bdd87af4c08d22"
+ "text": "Det var en gång en pojke, som var så där en fjorton år gammal, lång och ranglig och linhårig.",
+ "work": "Nils Holgerssons underbara resa (Selma Lagerlof) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/nils.opus",
+ "turbo": "audio/turbo/nils.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "carmen",
- "language": "Spanish",
- "language_id": "es",
- "gender": "F",
- "donor": "anonymous (invented name)",
- "speaker_id": "2308",
+ "name": "oliver",
+ "language": "English",
+ "language_id": "en",
+ "gender": "M",
+ "donor": "oliver (product alias, not donor identity)",
+ "speaker_id": "0a67",
"source": {
- "name": "CML-TTS (LibriVox-derived, ylacombe/cml-tts on Hugging Face)",
- "url": "https://huggingface.co/datasets/ylacombe/cml-tts",
- "license": "CC-BY-4.0",
- "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/0a67.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "0a67",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "4bd75d0ef0ad3f4e82ac075eab2a132651d2463f83bec210edeeccaf69294886",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
},
"reference": {
- "source_filename": "carmen.wav",
+ "source_filename": "oliver.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/carmen.opus",
- "sha256": "ec9a38e7c13420543a004c4db665af8fb1b66a952f18edeb98d0099a14f186e3",
- "duration_s": 14.37,
- "construction": "single continuous clip"
+ "public_preview": "audio/refs/oliver.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
},
"profile": {
- "hf_path": "voices/carmen.safetensors",
- "sha256": "c9387f3bc58e8e1dd41700339e886a546200597fe629e523282ba4dbd4ddc069"
+ "hf_path": "voices/oliver.safetensors",
+ "sha256": "bd2fdb4ff8fbc12b070654dc5dae82b24aee4990bda726185547ec613b9f9cb8"
},
- "speaker_similarity": null,
+ "speaker_similarity": 0.8782104849815369,
"sample": {
- "seed": 3,
- "text": "Subió una mona a un nogal, y cogiendo una nuez verde, en la cáscara la muerde, con que le supo muy mal.",
- "work": "La mona (Felix Maria de Samaniego) — public domain",
- "audio": "audio/carmen.opus",
- "sha256": "aefb626d30e906f729e8ea4c7a178f3b0b3092851fdbb1af2578fb840ae2078c"
+ "audio": {
+ "loudr-1": "audio/loudr-1/oliver.opus",
+ "turbo": "audio/turbo/oliver.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
+ "seed": 7,
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "bd2fdb4ff8fbc12b070654dc5dae82b24aee4990bda726185547ec613b9f9cb8",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 15.52,
+ "gain_db": 4.66,
+ "work": "Shared English comparison story — original text"
}
},
{
- "name": "dante",
- "language": "Italian",
- "language_id": "it",
+ "name": "oscar",
+ "language": "English",
+ "language_id": "en",
"gender": "M",
- "donor": "anonymous (invented name)",
- "speaker_id": "12598",
+ "donor": "oscar (product alias, not donor identity)",
+ "speaker_id": "ra_XOr",
"source": {
- "name": "Multilingual LibriSpeech (facebook/multilingual_librispeech)",
- "url": "https://huggingface.co/datasets/facebook/multilingual_librispeech",
- "license": "CC-BY-4.0",
- "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/ra_XOr.wav",
+ "license": "CC0-1.0",
+ "speaker_id": "ra_XOr",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "560caaa6193190b021811e1b0d9dcfddd1b96f7d3f75c71c098823531c305213",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
},
"reference": {
- "source_filename": "dante.wav",
+ "source_filename": "oscar.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/dante.opus",
- "sha256": "df142e760a870aaf53d71e945fcafbdfb2c5bcf14676c4c8b90ded229b9a48fe",
- "duration_s": 14.0,
- "construction": "single continuous clip"
+ "public_preview": "audio/refs/oscar.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
},
"profile": {
- "hf_path": "voices/dante.safetensors",
- "sha256": "d0ba2cf9871b7f933ff5f0dbdca9578077599c2e8209fc6246727edd79c15924"
+ "hf_path": "voices/oscar.safetensors",
+ "sha256": "8b8ff60604338eedddcd7317ed76ad2109fba6fa0ab79c9684a7954b64f963b2"
},
- "speaker_similarity": null,
+ "speaker_similarity": 0.9155877828598022,
"sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/oscar.opus",
+ "turbo": "audio/turbo/oscar.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
"seed": 7,
- "text": "C'era una volta... Un re! diranno subito i miei piccoli lettori. No, ragazzi, avete sbagliato: c'era una volta un pezzo di legno.",
- "work": "Le avventure di Pinocchio (Carlo Collodi) — public domain",
- "audio": "audio/dante.opus",
- "sha256": "9b05b0d44b83e208ea4c97b30a4b2e03cb323e5108adf0847f1572f18639fc04"
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "8b8ff60604338eedddcd7317ed76ad2109fba6fa0ab79c9684a7954b64f963b2",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 16.2,
+ "gain_db": 3.0100000000000016,
+ "work": "Shared English comparison story — original text"
}
},
{
@@ -458,7 +885,6 @@
"source_filename": "paola.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/paola.opus",
- "sha256": "424e0cecda21fa34c5a05fb5f6bc029949f0485ac91e7fd45afc7645ff4cdbb9",
"duration_s": 11.0,
"construction": "single continuous clip"
},
@@ -471,16 +897,22 @@
"seed": 7,
"text": "C'era una volta... Un re! diranno subito i miei piccoli lettori. No, ragazzi, avete sbagliato: c'era una volta un pezzo di legno.",
"work": "Le avventure di Pinocchio (Carlo Collodi) — public domain",
- "audio": "audio/paola.opus",
- "sha256": "452ae96e4a6195a781c1aa521d7a856300ae814541856702824ad413527dabd3"
+ "audio": {
+ "loudr-1": "audio/loudr-1/paola.opus",
+ "turbo": "audio/turbo/paola.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "tugao",
- "language": "Portuguese (European)",
- "language_id": "pt",
+ "name": "pim",
+ "language": "Dutch",
+ "language_id": "nl",
"gender": "M",
- "donor": "tugao (donor alias)",
+ "donor": "pim (donor alias)",
"speaker_id": null,
"source": {
"name": "Home Assistant / Piper voice-datasets (voice donations recorded for TTS)",
@@ -489,66 +921,36 @@
"consent": "recorded and donated expressly for building TTS voices"
},
"reference": {
- "source_filename": "tugao.wav",
+ "source_filename": "pim.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/tugao.opus",
- "sha256": "d6b40a71decdc9e9a560442f0c0e78f412b4d94365c9bddcb3e215ca4f452118",
- "duration_s": 9.78,
+ "public_preview": "audio/refs/pim.opus",
+ "duration_s": 11.0,
"construction": "concatenated donation clips, 120 ms gaps"
},
"profile": {
- "hf_path": "voices/tugao.safetensors",
- "sha256": "adcebf6fe42125bdc0aaca6ba3d23d79a30c8ad6a52aa65fd7970bed540eec43"
+ "hf_path": "voices/pim.safetensors",
+ "sha256": "05c5b3bd921240acc39cc8ffd576ab71dcbc36e6238ce468292ae74c61190130"
},
- "speaker_similarity": 0.916,
+ "speaker_similarity": null,
"sample": {
"seed": 7,
- "text": "O meu amigo Jacinto nasceu num palácio, com cento e nove contos de renda em terras de semeadura, de vinhedo, de cortiça e de olival.",
- "work": "A Cidade e as Serras (Eca de Queiros) — public domain",
- "audio": "audio/tugao.opus",
- "sha256": "ddf3be70b986247fc879f90d5dc3f9e41e28d763e08ca10de1a44ea08e3f112b"
+ "text": "Jantje zag eens pruimen hangen, o! als eieren zo groot. 't Scheen, dat Jantje wou gaan plukken, schoon zijn vader 't hem verbood.",
+ "work": "De pruimeboom (Hieronymus van Alphen) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/pim.opus",
+ "turbo": "audio/turbo/pim.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "ines",
- "language": "Portuguese (European)",
- "language_id": "pt",
- "gender": "F",
- "donor": "anonymous (invented name)",
- "speaker_id": "7925",
- "source": {
- "name": "CML-TTS (LibriVox-derived, ylacombe/cml-tts on Hugging Face)",
- "url": "https://huggingface.co/datasets/ylacombe/cml-tts",
- "license": "CC-BY-4.0",
- "consent": "LibriVox recording, redistributed under CC-BY; anonymous speaker id, invented voice name"
- },
- "reference": {
- "source_filename": "ines.wav",
- "published_in_model_repo": false,
- "public_preview": "audio/refs/ines.opus",
- "sha256": "59f2fde8e98c8183e995e2576128ac4bbb186c08f677c1ac6daf2cd359bba7f4",
- "duration_s": 10.44,
- "construction": "single continuous clip"
- },
- "profile": {
- "hf_path": "voices/ines.safetensors",
- "sha256": "b7f76b52170dfcdcef0e8835956967bf2fbc4973883b6e99d6b2be7fd4f3a496"
- },
- "speaker_similarity": 0.96,
- "sample": {
- "seed": 7,
- "text": "O meu amigo Jacinto nasceu num palácio, com cento e nove contos de renda em terras de semeadura, de vinhedo, de cortiça e de olival.",
- "work": "A Cidade e as Serras (Eca de Queiros) — public domain",
- "audio": "audio/ines.opus",
- "sha256": "55c9cb8a3716ccfce280c25b577e344363fe3978b35577ce8c20ee6d4f3869ea"
- },
- "notes": "CML-TTS is LibriVox-derived; accent is Brazilian Portuguese, unlike tugao (European)."
- },
- {
- "name": "nils",
+ "name": "selma",
"language": "Swedish",
"language_id": "sv",
- "gender": "M",
+ "gender": "F",
"donor": "anonymous (invented name)",
"speaker_id": null,
"source": {
@@ -558,58 +960,75 @@
"consent": "corpus released CC0 by Sprakbanken; anonymous speaker id, invented voice name"
},
"reference": {
- "source_filename": "nils.wav",
+ "source_filename": "selma.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/nils.opus",
- "sha256": "26680c82a976fe2d6f3202a97b50499274f1f0c36d329cbe6cdd6c3ebac1f0f0",
- "duration_s": 11.0,
+ "public_preview": "audio/refs/selma.opus",
+ "duration_s": 8.53,
"construction": "single continuous clip"
},
"profile": {
- "hf_path": "voices/nils.safetensors",
- "sha256": "be75721c99547ab3ecdf1f8629101e9fa3ea1d569fc6e1220b8e2f259fb49f4e"
+ "hf_path": "voices/selma.safetensors",
+ "sha256": "d3ba9ab18c676db23028c9561ad79a183b35adae377d20d46f1d8f253ce6eeec"
},
- "speaker_similarity": 0.92,
+ "speaker_similarity": 0.925,
"sample": {
"seed": 7,
"text": "Det var en gång en pojke, som var så där en fjorton år gammal, lång och ranglig och linhårig.",
"work": "Nils Holgerssons underbara resa (Selma Lagerlof) — public domain",
- "audio": "audio/nils.opus",
- "sha256": "61b704118c82878a218d0db2b0fd3da20a70d0d442e2a36cc064ccc1a7f0679b"
+ "audio": {
+ "loudr-1": "audio/loudr-1/selma.opus",
+ "turbo": "audio/turbo/selma.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "selma",
- "language": "Swedish",
- "language_id": "sv",
+ "name": "sophie",
+ "language": "English",
+ "language_id": "en",
"gender": "F",
- "donor": "anonymous (invented name)",
- "speaker_id": null,
+ "donor": "sophie (product alias, not donor identity)",
+ "speaker_id": "Hannah",
"source": {
- "name": "NST Swedish speech database (Sprakbanken, National Library of Norway)",
- "url": "https://www.nb.no/sprakbanken/en/resource-catalogue/oai-nb-no-sbr-17/",
+ "name": "Kyutai Voice Donations",
+ "url": "https://huggingface.co/kyutai/tts-voices/resolve/323332d33f997de8394f24a193e1a76df720e01a/voice-donations/Hannah.wav",
"license": "CC0-1.0",
- "consent": "corpus released CC0 by Sprakbanken; anonymous speaker id, invented voice name"
+ "speaker_id": "Hannah",
+ "revision": "323332d33f997de8394f24a193e1a76df720e01a",
+ "sha256": "439585cc5c981882a87f1b32f95dbc2c1225d145a4cf861ca36483decbc4c2a8",
+ "terms": "https://kyutai.org/legal/Terms%20of%20Use%20-%20Unmute%20Voice%20Donation%20Project%20v1.pdf",
+ "consent": "Donation terms expressly cover speech synthesis, voice embeddings and commercial use; individual signed forms were not independently inspected."
},
"reference": {
- "source_filename": "selma.wav",
+ "source_filename": "sophie.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/selma.opus",
- "sha256": "775d4db5a95ac9fea95b1f9b8d6a5b1917a3aefd466e153962ad195d83ed51d0",
- "duration_s": 8.53,
- "construction": "single continuous clip"
+ "public_preview": "audio/refs/sophie.opus",
+ "construction": "Pinned source recording; prompt cut at a pause before ten seconds, followed by 0.4 s silence."
},
"profile": {
- "hf_path": "voices/selma.safetensors",
- "sha256": "d3ba9ab18c676db23028c9561ad79a183b35adae377d20d46f1d8f253ce6eeec"
+ "hf_path": "voices/sophie.safetensors",
+ "sha256": "efb8047f93eda2a8e7cedaaa254b51957a845d55287298868a409662f8f75e1a"
},
- "speaker_similarity": 0.925,
+ "speaker_similarity": 0.8967336416244507,
"sample": {
+ "audio": {
+ "loudr-1": "audio/loudr-1/sophie.opus",
+ "turbo": "audio/turbo/sophie.opus"
+ },
+ "text": "The room was quiet when she opened the letter. Outside, the rain had finally stopped. She read the first line slowly, then looked up and smiled. There was still time to change her plans, but for once, she decided to stay exactly where she was.",
"seed": 7,
- "text": "Det var en gång en pojke, som var så där en fjorton år gammal, lång och ranglig och linhårig.",
- "work": "Nils Holgerssons underbara resa (Selma Lagerlof) — public domain",
- "audio": "audio/selma.opus",
- "sha256": "70f186995d8b6aac965662cdff346ec5211bef98276c7ef94a69c096dccd0782"
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54",
+ "profile_sha256": "efb8047f93eda2a8e7cedaaa254b51957a845d55287298868a409662f8f75e1a",
+ "backend": "ONNX CPU, 1 thread",
+ "duration_seconds": 15.36,
+ "gain_db": 0.14999999999999858,
+ "work": "Shared English comparison story — original text"
}
},
{
@@ -629,7 +1048,6 @@
"source_filename": "soren.wav",
"published_in_model_repo": false,
"public_preview": "audio/refs/soren.opus",
- "sha256": "a0d7510fa2de66b8bf656c5f2ff93ddf462878ce31799860ca242bcad64487fb",
"duration_s": 7.38,
"construction": "single continuous clip, close mic"
},
@@ -642,42 +1060,92 @@
"seed": 7,
"text": "Der var så dejligt ude på landet; det var sommer, kornet stod gult, og havren grøn.",
"work": "Den grimme aelling (H. C. Andersen) — public domain",
- "audio": "audio/soren.opus",
- "sha256": "f9841dd5162d30df3e67aee92128bd3708f4eff6c3d1c5c177091765cf04af2c"
+ "audio": {
+ "loudr-1": "audio/loudr-1/soren.opus",
+ "turbo": "audio/turbo/soren.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
},
{
- "name": "freja",
- "language": "Danish",
- "language_id": "da",
- "gender": "F",
- "donor": "anonymous (invented name)",
- "speaker_id": "35",
+ "name": "thorsten",
+ "language": "German",
+ "language_id": "de",
+ "gender": "M",
+ "donor": "Thorsten Mueller",
+ "speaker_id": null,
"source": {
- "name": "NST Danish speech database (alexandrainst/nst-da on Hugging Face)",
- "url": "https://huggingface.co/datasets/alexandrainst/nst-da",
+ "name": "Thorsten-Voice TV-44kHz-Full",
+ "url": "https://huggingface.co/datasets/Thorsten-Voice/TV-44kHz-Full",
"license": "CC0-1.0",
- "consent": "corpus released CC0; anonymous speaker id, invented voice name"
+ "consent": "voice deliberately donated by Thorsten Mueller for TTS"
},
"reference": {
- "source_filename": "freja.wav",
+ "source_filename": "thorsten.wav",
"published_in_model_repo": false,
- "public_preview": "audio/refs/freja.opus",
- "sha256": "078baf737c9acc6f567dd87a8b3eca897becb0e83d9209279bf8314830d2678a",
- "duration_s": 8.78,
- "construction": "single continuous clip, close mic"
+ "public_preview": "audio/refs/thorsten.opus",
+ "duration_s": 6.37,
+ "construction": "single continuous clip"
},
"profile": {
- "hf_path": "voices/freja.safetensors",
- "sha256": "0a3f913b9b47c529393f843850228bd8eee6a883b4c138978fd3afa7758561e8"
+ "hf_path": "voices/thorsten.safetensors",
+ "sha256": "87873fec8d3dceaa643ab1ab07cf5143364e659dd6b3caec707f51408ac2154a"
},
- "speaker_similarity": 0.907,
+ "speaker_similarity": null,
"sample": {
"seed": 7,
- "text": "Der var så dejligt ude på landet; det var sommer, kornet stod gult, og havren grøn.",
- "work": "Den grimme aelling (H. C. Andersen) — public domain",
- "audio": "audio/freja.opus",
- "sha256": "cd785cc844250a5ae97010e2a3b0ee9260c5a24d016350d931aa7ec776958812"
+ "text": "Ach, was muss man oft von bösen Kindern hören oder lesen! Wie zum Beispiel hier von diesen, welche Max und Moritz hießen.",
+ "work": "Max und Moritz (Wilhelm Busch) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/thorsten.opus",
+ "turbo": "audio/turbo/thorsten.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
+ }
+ },
+ {
+ "name": "tugao",
+ "language": "Portuguese (European)",
+ "language_id": "pt",
+ "gender": "M",
+ "donor": "tugao (donor alias)",
+ "speaker_id": null,
+ "source": {
+ "name": "Home Assistant / Piper voice-datasets (voice donations recorded for TTS)",
+ "url": "https://github.com/NabuCasa/voice-datasets",
+ "license": "CC0-1.0",
+ "consent": "recorded and donated expressly for building TTS voices"
+ },
+ "reference": {
+ "source_filename": "tugao.wav",
+ "published_in_model_repo": false,
+ "public_preview": "audio/refs/tugao.opus",
+ "duration_s": 9.78,
+ "construction": "concatenated donation clips, 120 ms gaps"
+ },
+ "profile": {
+ "hf_path": "voices/tugao.safetensors",
+ "sha256": "adcebf6fe42125bdc0aaca6ba3d23d79a30c8ad6a52aa65fd7970bed540eec43"
+ },
+ "speaker_similarity": 0.916,
+ "sample": {
+ "seed": 7,
+ "text": "O meu amigo Jacinto nasceu num palácio, com cento e nove contos de renda em terras de semeadura, de vinhedo, de cortiça e de olival.",
+ "work": "A Cidade e as Serras (Eca de Queiros) — public domain",
+ "audio": {
+ "loudr-1": "audio/loudr-1/tugao.opus",
+ "turbo": "audio/turbo/tugao.opus"
+ },
+ "model": "loudr-1",
+ "checkpoint_sha256": "73e69a78d58176a3e4b39ca992c7b37a9c51f7251d08e4334c27d9994faac44e",
+ "edge_fade_seconds": 0.02,
+ "algorithm_fingerprint": "e352f5d090776b54"
}
}
]