speaker-helper 0.7.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- speaker_helper-0.7.4/LICENSE +29 -0
- speaker_helper-0.7.4/PKG-INFO +365 -0
- speaker_helper-0.7.4/README.md +312 -0
- speaker_helper-0.7.4/pyproject.toml +136 -0
- speaker_helper-0.7.4/setup.cfg +4 -0
- speaker_helper-0.7.4/speaker_helper/__init__.py +98 -0
- speaker_helper-0.7.4/speaker_helper/api.py +294 -0
- speaker_helper-0.7.4/speaker_helper/cli.py +561 -0
- speaker_helper-0.7.4/speaker_helper/client.py +597 -0
- speaker_helper-0.7.4/speaker_helper/cloning.py +213 -0
- speaker_helper-0.7.4/speaker_helper/config.py +246 -0
- speaker_helper-0.7.4/speaker_helper/engine.py +330 -0
- speaker_helper-0.7.4/speaker_helper/eval/__init__.py +90 -0
- speaker_helper-0.7.4/speaker_helper/eval/data/en_reference.jsonl +10 -0
- speaker_helper-0.7.4/speaker_helper/eval/data/es_reference.jsonl +10 -0
- speaker_helper-0.7.4/speaker_helper/eval/data/fr_reference.jsonl +12 -0
- speaker_helper-0.7.4/speaker_helper/eval/dataset.py +146 -0
- speaker_helper-0.7.4/speaker_helper/eval/deepeval_metrics.py +141 -0
- speaker_helper-0.7.4/speaker_helper/eval/metrics.py +313 -0
- speaker_helper-0.7.4/speaker_helper/eval/multilang.py +127 -0
- speaker_helper-0.7.4/speaker_helper/eval/priors.py +119 -0
- speaker_helper-0.7.4/speaker_helper/eval/runner.py +344 -0
- speaker_helper-0.7.4/speaker_helper/eval/thresholds.py +92 -0
- speaker_helper-0.7.4/speaker_helper/eval/thresholds.yaml +17 -0
- speaker_helper-0.7.4/speaker_helper/profiles.py +189 -0
- speaker_helper-0.7.4/speaker_helper/sources.py +306 -0
- speaker_helper-0.7.4/speaker_helper/speaker.py +410 -0
- speaker_helper-0.7.4/speaker_helper/text.py +106 -0
- speaker_helper-0.7.4/speaker_helper/transcription.py +189 -0
- speaker_helper-0.7.4/speaker_helper/types.py +189 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/PKG-INFO +365 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/SOURCES.txt +45 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/dependency_links.txt +1 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/entry_points.txt +2 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/requires.txt +35 -0
- speaker_helper-0.7.4/speaker_helper.egg-info/top_level.txt +1 -0
- speaker_helper-0.7.4/tests/test_api.py +107 -0
- speaker_helper-0.7.4/tests/test_cli.py +48 -0
- speaker_helper-0.7.4/tests/test_client.py +102 -0
- speaker_helper-0.7.4/tests/test_cloning.py +166 -0
- speaker_helper-0.7.4/tests/test_config.py +52 -0
- speaker_helper-0.7.4/tests/test_engine.py +100 -0
- speaker_helper-0.7.4/tests/test_eval.py +321 -0
- speaker_helper-0.7.4/tests/test_eval_deepeval.py +85 -0
- speaker_helper-0.7.4/tests/test_profiles.py +97 -0
- speaker_helper-0.7.4/tests/test_sources.py +121 -0
- speaker_helper-0.7.4/tests/test_text.py +48 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Warith HARCHAOUI
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: speaker-helper
|
|
3
|
+
Version: 0.7.4
|
|
4
|
+
Summary: Speaker Helper — professional Speech Synthesis (offline + streaming) over a local engine (Voicebox by default). The inverse of vocal-helper: text in, speech out. Library + CLI + REST API, with voice cloning and a built-in AI evaluation gate; runnable locally (conda + pip) or as a Docker server.
|
|
5
|
+
Author-email: Warith HARCHAOUI <warith@deraison.ai>
|
|
6
|
+
License: BSD-3-Clause
|
|
7
|
+
Project-URL: Homepage, https://github.com/warith-harchaoui/speaker-helper
|
|
8
|
+
Project-URL: Issues, https://github.com/warith-harchaoui/speaker-helper/issues
|
|
9
|
+
Keywords: tts,text-to-speech,speech,voicebox,kokoro,streaming,offline,asyncio,real-time,french,multilingual
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: <3.14,>=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: os-helper>=1.5.0
|
|
25
|
+
Requires-Dist: audio-helper>=1.5.5
|
|
26
|
+
Requires-Dist: httpx>=0.27
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Requires-Dist: numpy>=1.24
|
|
29
|
+
Requires-Dist: soundfile>=0.12
|
|
30
|
+
Provides-Extra: server
|
|
31
|
+
Requires-Dist: fastapi>=0.110; extra == "server"
|
|
32
|
+
Requires-Dist: uvicorn>=0.29; extra == "server"
|
|
33
|
+
Requires-Dist: pydantic>=2.6; extra == "server"
|
|
34
|
+
Requires-Dist: python-multipart>=0.0.9; extra == "server"
|
|
35
|
+
Requires-Dist: fastapi-mcp>=0.4; extra == "server"
|
|
36
|
+
Provides-Extra: stt
|
|
37
|
+
Requires-Dist: vocal-helper>=0.3.7; extra == "stt"
|
|
38
|
+
Provides-Extra: youtube
|
|
39
|
+
Requires-Dist: youtube-helper>=1.3.3; extra == "youtube"
|
|
40
|
+
Provides-Extra: podcast
|
|
41
|
+
Requires-Dist: podcast-helper>=0.3.3; extra == "podcast"
|
|
42
|
+
Provides-Extra: mic
|
|
43
|
+
Requires-Dist: capture-helper>=0.2.2; extra == "mic"
|
|
44
|
+
Provides-Extra: eval
|
|
45
|
+
Requires-Dist: deepeval>=3; extra == "eval"
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
49
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
50
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
51
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
52
|
+
Dynamic: license-file
|
|
53
|
+
|
|
54
|
+
# Speaker Helper
|
|
55
|
+
|
|
56
|
+
[🇫🇷](https://github.com/warith-harchaoui/speaker-helper/blob/main/LISEZMOI.md) · [🇬🇧](https://github.com/warith-harchaoui/speaker-helper/blob/main/README.md)
|
|
57
|
+
|
|
58
|
+
[](https://github.com/warith-harchaoui/speaker-helper/actions/workflows/ci.yml) [](LICENSE) [](#)
|
|
59
|
+
|
|
60
|
+
`Speaker Helper` belongs to a collection of libraries called `AI Helpers` developed for building Artificial Intelligence.
|
|
61
|
+
|
|
62
|
+
[🌍 AI Helpers](https://harchaoui.org/warith/ai-helpers)
|
|
63
|
+
|
|
64
|
+
[](https://harchaoui.org/warith/ai-helpers)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
**Professional text-to-speech — offline and streaming, with voice cloning and a
|
|
68
|
+
built-in evaluation gate — over a local Speech Synthesis engine
|
|
69
|
+
([Voicebox](https://github.com/jamiepine/voicebox) by default).**
|
|
70
|
+
|
|
71
|
+
speaker-helper is the counterpart of
|
|
72
|
+
[`vocal-helper`](https://github.com/warith-harchaoui): where vocal-helper turns
|
|
73
|
+
*speech into text*, speaker-helper turns **text into speech**. It gives you a
|
|
74
|
+
small, typed Python API, a CLI, and a REST API — runnable locally (conda + pip)
|
|
75
|
+
or as a Docker server.
|
|
76
|
+
|
|
77
|
+
- **Two modes.** *Offline* (whole text → one audio) and *streaming*
|
|
78
|
+
(sentence-split, low time-to-first-audio).
|
|
79
|
+
- **Real-time on CPU.** The default `kokoro` engine synthesises faster than
|
|
80
|
+
real time (real-time factor well below 1.0) — no GPU required.
|
|
81
|
+
- **Backend-agnostic.** The engine is an implementation detail behind a
|
|
82
|
+
`TTSEngine` protocol. Voicebox is the default; a deterministic `mock` backend
|
|
83
|
+
ships for tests and CI, and new backends are a small, local change.
|
|
84
|
+
- **Voice cloning, everywhere.** Point at a recording and speaker-helper clones
|
|
85
|
+
the voice — in the library, CLI, and REST API. Missing transcripts are
|
|
86
|
+
derived automatically with [`vocal-helper`](https://github.com/warith-harchaoui).
|
|
87
|
+
- **Built-in AI evaluation.** A committed dataset, versioned thresholds, and
|
|
88
|
+
speed/anomaly/fidelity metrics gate quality in CI — no vibe checks.
|
|
89
|
+
- **Batteries included.** Library, CLI, REST API, Docker.
|
|
90
|
+
|
|
91
|
+
See [`EXAMPLES.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/EXAMPLES.md) for a runnable cookbook,
|
|
92
|
+
[`docs/tech-report.en.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/docs/tech-report.en.md) for the technical report
|
|
93
|
+
([FR](https://github.com/warith-harchaoui/speaker-helper/blob/main/docs/tech-report.fr.md)), and [`LISEZMOI.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/LISEZMOI.md) for the French
|
|
94
|
+
readme.
|
|
95
|
+
|
|
96
|
+
## Documentation
|
|
97
|
+
|
|
98
|
+
[💻 Documentation](https://harchaoui.org/warith/ai-helpers/docs/speaker-helper-doc/)
|
|
99
|
+
|
|
100
|
+
[📋 Examples](https://github.com/warith-harchaoui/speaker-helper/blob/main/EXAMPLES.md)
|
|
101
|
+
|
|
102
|
+
## How it fits together
|
|
103
|
+
|
|
104
|
+
```mermaid
|
|
105
|
+
flowchart LR
|
|
106
|
+
text["your text"]:::input
|
|
107
|
+
subgraph SH["speaker-helper (library · CLI · REST API)"]
|
|
108
|
+
speaker["Speaker<br/>offline · streaming · clone"]:::core
|
|
109
|
+
eval["evaluation<br/>RTF · anomalies · WER/chrF"]:::eval
|
|
110
|
+
end
|
|
111
|
+
engine["Speech Synthesis engine<br/>voicebox · mock · …"]:::engine
|
|
112
|
+
audio["WAV audio"]:::output
|
|
113
|
+
|
|
114
|
+
text --> speaker
|
|
115
|
+
speaker -- "TTSEngine protocol" --> engine
|
|
116
|
+
engine --> audio
|
|
117
|
+
speaker -.->|measured by| eval
|
|
118
|
+
|
|
119
|
+
classDef input fill:#FFF5CC,stroke:#FFCC00,color:#000000
|
|
120
|
+
classDef core fill:#CCE4FF,stroke:#007AFF,color:#000000
|
|
121
|
+
classDef eval fill:#D4F5D9,stroke:#28CD41,color:#000000
|
|
122
|
+
classDef engine fill:#EFDCF8,stroke:#AF52DE,color:#000000
|
|
123
|
+
classDef output fill:#FFEACC,stroke:#FF9500,color:#000000
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
speaker-helper talks only to the `TTSEngine` protocol, so the concrete engine
|
|
127
|
+
(Voicebox by default) is swappable. Start an engine once, then point
|
|
128
|
+
speaker-helper at it.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Installation
|
|
133
|
+
|
|
134
|
+
**Prerequisites** — **Python 3.10–3.13** and **git**, **libsndfile**, **ffmpeg**, cross-platform. `soundfile` needs the native `libsndfile` library, and `audio-helper` (voice-clone trimming / concatenation) uses `ffmpeg`:
|
|
135
|
+
|
|
136
|
+
- 🍎 **macOS** ([Homebrew](https://brew.sh)): `brew install python git libsndfile ffmpeg`
|
|
137
|
+
- 🐧 **Ubuntu/Debian**: `sudo apt update && sudo apt install -y python3 python3-pip git libsndfile1 ffmpeg`
|
|
138
|
+
- 🪟 **Windows** (PowerShell): `winget install Python.Python.3.12 Git.Git ffmpeg` (`libsndfile` is bundled with the `soundfile` wheel — no separate install).
|
|
139
|
+
|
|
140
|
+
We recommend using Python environments. Check this link if you're unfamiliar with setting one up: [🥸 Tech tips](https://harchaoui.org/warith/4ml/#install).
|
|
141
|
+
|
|
142
|
+
### From source
|
|
143
|
+
|
|
144
|
+
speaker-helper is **not on PyPI yet** (PyPI release coming soon). Like the other
|
|
145
|
+
`*-helper` projects, it installs from git, pinned to a release tag:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# core
|
|
149
|
+
pip install "git+https://github.com/warith-harchaoui/speaker-helper.git@v0.7.4"
|
|
150
|
+
# with extras (server + MCP, and STT for cloning/eval round-trip):
|
|
151
|
+
pip install "speaker-helper[server,stt] @ git+https://github.com/warith-harchaoui/speaker-helper.git@v0.7.4"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Available extras: `server` (REST API + MCP), `stt` (vocal-helper), `youtube`,
|
|
155
|
+
`podcast`, `mic` (speech-to-speech sources), `eval` (DeepEval), `dev`.
|
|
156
|
+
|
|
157
|
+
Or, for local development (conda + pip):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
conda create -n speaker-helper python=3.11 -y
|
|
161
|
+
conda activate speaker-helper
|
|
162
|
+
pip install -e ".[server]" # add ",dev" for the test/lint toolchain
|
|
163
|
+
pip install -e ".[server,stt]" # add ",stt" to auto-transcribe clone references
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
speaker-helper is part of the **AI Helpers** ecosystem: it installs
|
|
167
|
+
[`os-helper`](https://github.com/warith-harchaoui/os-helper) (logging) and
|
|
168
|
+
[`audio-helper`](https://github.com/warith-harchaoui/audio-helper) (audio
|
|
169
|
+
slicing/concatenation) automatically. The optional `stt` extra adds
|
|
170
|
+
[`vocal-helper`](https://github.com/warith-harchaoui/vocal-helper) for
|
|
171
|
+
transcribing voice-clone references and the evaluation round-trip.
|
|
172
|
+
|
|
173
|
+
### A Voicebox engine
|
|
174
|
+
|
|
175
|
+
speaker-helper needs a running Voicebox.
|
|
176
|
+
|
|
177
|
+
- **Apple Silicon (recommended): native MLX Voicebox on `:17493`.** It uses the
|
|
178
|
+
Apple **GPU** and is markedly faster (well under real time). This is
|
|
179
|
+
speaker-helper's default port, so no override is needed. Note: Docker on macOS
|
|
180
|
+
has **no GPU/Metal passthrough**, so only the native build gets the GPU.
|
|
181
|
+
- **CPU / Docker on `:17600`** (portable, no GPU): fine for functionality;
|
|
182
|
+
real-time factor is borderline and load-sensitive on CPU (see
|
|
183
|
+
[`BENCHMARKS.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/BENCHMARKS.md)).
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
git clone https://github.com/jamiepine/voicebox && cd voicebox
|
|
187
|
+
docker compose up --build # serves on 127.0.0.1:17600
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Then tell speaker-helper where it is (`--port`, `settings.yaml`, or
|
|
191
|
+
`SPEAKER_HELPER_VOICEBOX_PORT`).
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Quickstart
|
|
196
|
+
|
|
197
|
+
### Python
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from speaker_helper import Speaker, Settings
|
|
201
|
+
|
|
202
|
+
spk = Speaker(Settings.from_mapping({
|
|
203
|
+
"engine": "kokoro", "language": "fr", "voicebox": {"port": 17600},
|
|
204
|
+
}))
|
|
205
|
+
result = spk.save("Bonjour le monde.", "hello.wav")
|
|
206
|
+
print(f"{result.duration_s:.2f}s audio, RTF {result.rtf:.2f}")
|
|
207
|
+
# 2.80s audio, RTF 0.43
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### CLI
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
speaker-helper --port 17600 voices --engine kokoro
|
|
214
|
+
speaker-helper --port 17600 synth "Bonjour le monde." -o hello.wav
|
|
215
|
+
speaker-helper --port 17600 synth "Une. Deux. Trois." -o out.wav --stream
|
|
216
|
+
speaker-helper --backend mock eval # gate quality (no engine needed)
|
|
217
|
+
speaker-helper --port 17600 --clone synth "Bonjour." -o cloned.wav
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### REST API server
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
speaker-helper --port 17600 serve --host 0.0.0.0 --port 8080
|
|
224
|
+
curl -s -X POST localhost:8080/synth -H 'content-type: application/json' \
|
|
225
|
+
-d '{"text": "Bonjour."}' -o out.wav
|
|
226
|
+
# streaming (Server-Sent Events, one JSON chunk per sentence):
|
|
227
|
+
curl -N -X POST localhost:8080/synth/stream -H 'content-type: application/json' \
|
|
228
|
+
-d '{"text": "Une. Deux. Trois."}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The server also mounts a **Model Context Protocol** endpoint at `/mcp` (via
|
|
232
|
+
[`fastapi-mcp`](https://github.com/tadata-org/fastapi-mcp), bundled with the
|
|
233
|
+
`server` extra), exposing `synth`, `synth_stream`, `clone_voice`, `list_voices`,
|
|
234
|
+
and `health` as MCP tools an assistant can call directly.
|
|
235
|
+
|
|
236
|
+
Or with Docker (server points at a Voicebox on the host):
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
docker compose up --build # speaker-helper API on :8080
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Voice cloning
|
|
245
|
+
|
|
246
|
+
Point at a recording and speaker-helper clones the voice — in the library, CLI,
|
|
247
|
+
and REST API. If you do not supply a transcript of the reference, it is derived
|
|
248
|
+
automatically with [`vocal-helper`](https://github.com/warith-harchaoui) (install
|
|
249
|
+
the `stt` extra). A ready-to-use reference (`assets/ref-malo.wav`) ships as the
|
|
250
|
+
default.
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
from speaker_helper import Speaker, Settings, VoiceSample
|
|
254
|
+
|
|
255
|
+
spk = Speaker(Settings.from_mapping({"engine": "chatterbox", "voicebox": {"port": 17600}}))
|
|
256
|
+
# give only the audio — the transcript is transcribed and aligned for you:
|
|
257
|
+
await spk.clone_voice("malo", [VoiceSample("my_voice.wav", "")])
|
|
258
|
+
result = await spk.say("Maintenant je parle avec la voix clonée.")
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
speaker-helper --port 17600 clone # clone the bundled ref-malo, print id
|
|
263
|
+
speaker-helper --port 17600 --clone-audio my_voice.wav synth "Bonjour." -o out.wav
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Reference audio longer than the engine's limit (Voicebox: 30 s) is trimmed
|
|
267
|
+
automatically (via [`audio-helper`](https://github.com/warith-harchaoui)) and
|
|
268
|
+
re-transcribed so audio and text stay aligned.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Speech-to-speech (re-voicing)
|
|
273
|
+
|
|
274
|
+
Bring audio in from the AI Helpers source packages and re-voice it — transcribed
|
|
275
|
+
with [`vocal-helper`](https://github.com/warith-harchaoui) and spoken back
|
|
276
|
+
(optionally in a cloned voice or another language):
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
import asyncio
|
|
280
|
+
from speaker_helper import Speaker, Settings
|
|
281
|
+
from speaker_helper.sources import from_youtube, revoice
|
|
282
|
+
|
|
283
|
+
async def main() -> None:
|
|
284
|
+
src = from_youtube("https://youtu.be/…") # extra: youtube
|
|
285
|
+
async with Speaker(Settings.from_mapping({"voicebox": {"port": 17600}})) as spk:
|
|
286
|
+
out = await revoice(src, spk) # transcribe + re-speak
|
|
287
|
+
open("revoiced.wav", "wb").write(out.wav_bytes)
|
|
288
|
+
|
|
289
|
+
asyncio.run(main())
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
speaker-helper --port 17600 speak-from --source youtube --url https://youtu.be/… -o out.wav
|
|
294
|
+
speaker-helper --port 17600 speak-from --source podcast --url https://feed/rss -o out.wav
|
|
295
|
+
speaker-helper --port 17600 --clone speak-from --source mic --seconds 5 -o out.wav
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Sources are optional extras: `youtube` (`youtube-helper`), `podcast`
|
|
299
|
+
(`podcast-helper`), `mic` (`capture-helper`).
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Evaluation (no vibe checks)
|
|
304
|
+
|
|
305
|
+
Quality is gated, not guessed. `speaker-helper eval` runs the engine over a
|
|
306
|
+
committed dataset and checks versioned thresholds — **synthesis faster than real
|
|
307
|
+
time**, **zero audio anomalies** (empty / clipped / aberrant duration), and,
|
|
308
|
+
with an STT transcriber wired in, a WER/chrF **round-trip**. It exits non-zero
|
|
309
|
+
when the bar is missed, so it gates CI.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
speaker-helper --backend mock eval # deterministic, no engine
|
|
313
|
+
speaker-helper --port 17600 --engine kokoro eval --json report.json
|
|
314
|
+
# backend=voicebox engine=kokoro cases=12
|
|
315
|
+
# mean_rtf=0.3534 p95_rtf=0.3989 anomaly_rate=0.0 quality=0.75 (prior)
|
|
316
|
+
# PASS
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The evaluation targets the engine-agnostic `Speaker`, so the same gate grades
|
|
320
|
+
the `mock` backend in CI or a real engine locally — only `--backend` differs.
|
|
321
|
+
|
|
322
|
+
For teams standardising on a framework, the `eval` extra adds a
|
|
323
|
+
[DeepEval](https://github.com/confident-ai/deepeval) binding
|
|
324
|
+
(`RealTimeFactorMetric`, `AudioIntegrityMetric`) that reports the same
|
|
325
|
+
measurements as DeepEval custom metrics — deterministic and offline.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Configuration
|
|
330
|
+
|
|
331
|
+
Copy [`settings.yaml.example`](https://github.com/warith-harchaoui/speaker-helper/blob/main/settings.yaml.example) to `settings.yaml` (it is
|
|
332
|
+
gitignored) or use [`speaker_config.json.example`](https://github.com/warith-harchaoui/speaker-helper/blob/main/speaker_config.json.example)
|
|
333
|
+
as a reference. Every key can be overridden by a `SPEAKER_HELPER_*` environment
|
|
334
|
+
variable; `${VAR}` references inside the YAML are expanded from the environment.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Development
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
pip install -e ".[dev,server]"
|
|
342
|
+
pytest -q -m "not slow" # fast, deterministic suite (no engine needed)
|
|
343
|
+
pytest -q # also runs @slow live tests (needs Voicebox)
|
|
344
|
+
ruff check speaker_helper tests
|
|
345
|
+
speaker-helper --backend mock eval # run the evaluation gate locally
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
CI runs ruff + the fast suite on Python 3.10–3.13; a failing test blocks merges.
|
|
349
|
+
The fast suite drives the deterministic `mock` backend, so it needs no engine.
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Author
|
|
354
|
+
|
|
355
|
+
- [Warith HARCHAOUI](https://linkedin.com/in/warith-harchaoui)
|
|
356
|
+
|
|
357
|
+
## Acknowledgements
|
|
358
|
+
|
|
359
|
+
Special thanks to the contributors, reviewers, and users who helped improve
|
|
360
|
+
this project — and to the [Voicebox](https://github.com/jamiepine/voicebox)
|
|
361
|
+
authors for the engine speaker-helper builds on.
|
|
362
|
+
|
|
363
|
+
## License
|
|
364
|
+
|
|
365
|
+
BSD-3-Clause © Warith HARCHAOUI.
|