python-voiceio 0.3.1__tar.gz → 0.3.2__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.
- {python_voiceio-0.3.1/python_voiceio.egg-info → python_voiceio-0.3.2}/PKG-INFO +10 -3
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/README.md +9 -2
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/pyproject.toml +1 -1
- {python_voiceio-0.3.1 → python_voiceio-0.3.2/python_voiceio.egg-info}/PKG-INFO +10 -3
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_tts.py +2 -2
- python_voiceio-0.3.2/voiceio/__init__.py +1 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/config.py +1 -1
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/numbers.py +9 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/service.py +1 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/edge_engine.py +14 -1
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/piper_engine.py +3 -2
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/wizard.py +310 -167
- python_voiceio-0.3.1/voiceio/__init__.py +0 -1
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/LICENSE +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/python_voiceio.egg-info/SOURCES.txt +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/python_voiceio.egg-info/dependency_links.txt +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/python_voiceio.egg-info/entry_points.txt +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/python_voiceio.egg-info/requires.txt +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/python_voiceio.egg-info/top_level.txt +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/setup.cfg +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_app_wiring.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_autocorrect.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_backend_probes.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_clipboard_read.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_commands.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_config.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_corrections.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_fallback.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_health.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_hints.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_history.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_ibus_typer.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_llm.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_llm_api.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_numbers.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_platform.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_postprocess.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_prebuffer.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_prompt.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_recorder_integration.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_streaming.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_transcriber.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_vad.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_vocabulary.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/tests/test_wordfreq.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/__main__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/app.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/autocorrect.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/backends.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/cli.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/clipboard_read.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/commands.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/corrections.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/demo.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/feedback.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/health.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hints.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/history.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/base.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/chain.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/evdev.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/pynput_backend.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/hotkeys/socket_backend.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/ibus/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/ibus/engine.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/llm.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/llm_api.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/models/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/models/silero_vad.onnx +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/pidlock.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/platform.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/postprocess.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/prompt.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/recorder.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/sounds/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/sounds/commit.wav +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/sounds/start.wav +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/sounds/stop.wav +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/streaming.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/transcriber.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tray/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tray/_icons.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tray/_indicator.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tray/_pystray.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/base.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/chain.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/espeak.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/tts/player.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/__init__.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/base.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/chain.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/clipboard.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/ibus.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/pynput_type.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/wtype.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/xdotool.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/typers/ydotool.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/vad.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/vocabulary.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/wordfreq.py +0 -0
- {python_voiceio-0.3.1 → python_voiceio-0.3.2}/voiceio/worker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-voiceio
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Speak → text, locally, instantly.
|
|
5
5
|
Author: Hugo Montenegro
|
|
6
6
|
License-Expression: MIT
|
|
@@ -56,6 +56,7 @@ Dynamic: license-file
|
|
|
56
56
|
[](https://pypi.org/project/python-voiceio/)
|
|
57
57
|
[](https://pypi.org/project/python-voiceio/)
|
|
58
58
|
[](LICENSE)
|
|
59
|
+
[](https://pepy.tech/projects/python-voiceio)
|
|
59
60
|
|
|
60
61
|
Speak → text, locally, instantly.
|
|
61
62
|
|
|
@@ -153,6 +154,10 @@ Press your hotkey to start recording (1s pre-buffer catches the first syllable).
|
|
|
153
154
|
- **Works everywhere**: IBus input method for GUI apps, clipboard for terminals
|
|
154
155
|
- **Wayland + X11**: evdev hotkeys work on both, no root required
|
|
155
156
|
- **Pre-buffer**: never miss the first syllable
|
|
157
|
+
- **Voice commands**: "new line", "comma", "scratch that", punctuation by name
|
|
158
|
+
- **Autocorrect**: LLM-powered review of recurring Whisper mistakes (`voiceio correct`)
|
|
159
|
+
- **Text-to-speech**: hear selected text spoken back (Piper, eSpeak, Edge TTS)
|
|
160
|
+
- **Smart post-processing**: numbers ("twenty five" → "25"), punctuation, capitalization
|
|
156
161
|
- **Auto-healing**: falls back to the next working backend if one fails
|
|
157
162
|
- **Autostart**: optional systemd service, restarts on crash
|
|
158
163
|
- **Self-diagnosing**: `voiceio doctor` checks everything, `--fix` repairs it
|
|
@@ -176,7 +181,10 @@ voiceio Start the daemon
|
|
|
176
181
|
voiceio setup Interactive setup wizard
|
|
177
182
|
voiceio doctor Health check (--fix to auto-repair)
|
|
178
183
|
voiceio test Test microphone + live transcription
|
|
184
|
+
voiceio demo Interactive guided tour of all features
|
|
179
185
|
voiceio toggle Toggle recording on a running daemon
|
|
186
|
+
voiceio correct Review and fix recurring transcription errors
|
|
187
|
+
voiceio history View transcription history
|
|
180
188
|
voiceio update Update to latest version
|
|
181
189
|
voiceio service install Autostart on login (systemd / Windows Startup)
|
|
182
190
|
voiceio logs View recent logs
|
|
@@ -250,9 +258,8 @@ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) and [open issues](
|
|
|
250
258
|
- [ ] Multiple engine backends (whisper.cpp for Vulkan/AMD, VOSK for low-end hardware)
|
|
251
259
|
- [ ] Echo cancellation (filter system audio for meeting use)
|
|
252
260
|
- [ ] Wake word activation ("Hey voiceio")
|
|
253
|
-
- [ ] Text-to-speech output (Piper/espeak-ng — completes the "io")
|
|
254
|
-
|
|
255
261
|
**Done**
|
|
262
|
+
- [x] Text-to-speech output (Piper/eSpeak/Edge TTS — completes the "io")
|
|
256
263
|
- [x] LLM auto-audit dictionary (`voiceio correct --auto` — scan history with LLM, interactive correction)
|
|
257
264
|
- [x] LLM post-processing via Ollama (grammar cleanup, spelling fixes on final pass)
|
|
258
265
|
- [x] Corrections dictionary — auto-replace misheard words, "correct that" voice command
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://pypi.org/project/python-voiceio/)
|
|
5
5
|
[](https://pypi.org/project/python-voiceio/)
|
|
6
6
|
[](LICENSE)
|
|
7
|
+
[](https://pepy.tech/projects/python-voiceio)
|
|
7
8
|
|
|
8
9
|
Speak → text, locally, instantly.
|
|
9
10
|
|
|
@@ -101,6 +102,10 @@ Press your hotkey to start recording (1s pre-buffer catches the first syllable).
|
|
|
101
102
|
- **Works everywhere**: IBus input method for GUI apps, clipboard for terminals
|
|
102
103
|
- **Wayland + X11**: evdev hotkeys work on both, no root required
|
|
103
104
|
- **Pre-buffer**: never miss the first syllable
|
|
105
|
+
- **Voice commands**: "new line", "comma", "scratch that", punctuation by name
|
|
106
|
+
- **Autocorrect**: LLM-powered review of recurring Whisper mistakes (`voiceio correct`)
|
|
107
|
+
- **Text-to-speech**: hear selected text spoken back (Piper, eSpeak, Edge TTS)
|
|
108
|
+
- **Smart post-processing**: numbers ("twenty five" → "25"), punctuation, capitalization
|
|
104
109
|
- **Auto-healing**: falls back to the next working backend if one fails
|
|
105
110
|
- **Autostart**: optional systemd service, restarts on crash
|
|
106
111
|
- **Self-diagnosing**: `voiceio doctor` checks everything, `--fix` repairs it
|
|
@@ -124,7 +129,10 @@ voiceio Start the daemon
|
|
|
124
129
|
voiceio setup Interactive setup wizard
|
|
125
130
|
voiceio doctor Health check (--fix to auto-repair)
|
|
126
131
|
voiceio test Test microphone + live transcription
|
|
132
|
+
voiceio demo Interactive guided tour of all features
|
|
127
133
|
voiceio toggle Toggle recording on a running daemon
|
|
134
|
+
voiceio correct Review and fix recurring transcription errors
|
|
135
|
+
voiceio history View transcription history
|
|
128
136
|
voiceio update Update to latest version
|
|
129
137
|
voiceio service install Autostart on login (systemd / Windows Startup)
|
|
130
138
|
voiceio logs View recent logs
|
|
@@ -198,9 +206,8 @@ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) and [open issues](
|
|
|
198
206
|
- [ ] Multiple engine backends (whisper.cpp for Vulkan/AMD, VOSK for low-end hardware)
|
|
199
207
|
- [ ] Echo cancellation (filter system audio for meeting use)
|
|
200
208
|
- [ ] Wake word activation ("Hey voiceio")
|
|
201
|
-
- [ ] Text-to-speech output (Piper/espeak-ng — completes the "io")
|
|
202
|
-
|
|
203
209
|
**Done**
|
|
210
|
+
- [x] Text-to-speech output (Piper/eSpeak/Edge TTS — completes the "io")
|
|
204
211
|
- [x] LLM auto-audit dictionary (`voiceio correct --auto` — scan history with LLM, interactive correction)
|
|
205
212
|
- [x] LLM post-processing via Ollama (grammar cleanup, spelling fixes on final pass)
|
|
206
213
|
- [x] Corrections dictionary — auto-replace misheard words, "correct that" voice command
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-voiceio
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Speak → text, locally, instantly.
|
|
5
5
|
Author: Hugo Montenegro
|
|
6
6
|
License-Expression: MIT
|
|
@@ -56,6 +56,7 @@ Dynamic: license-file
|
|
|
56
56
|
[](https://pypi.org/project/python-voiceio/)
|
|
57
57
|
[](https://pypi.org/project/python-voiceio/)
|
|
58
58
|
[](LICENSE)
|
|
59
|
+
[](https://pepy.tech/projects/python-voiceio)
|
|
59
60
|
|
|
60
61
|
Speak → text, locally, instantly.
|
|
61
62
|
|
|
@@ -153,6 +154,10 @@ Press your hotkey to start recording (1s pre-buffer catches the first syllable).
|
|
|
153
154
|
- **Works everywhere**: IBus input method for GUI apps, clipboard for terminals
|
|
154
155
|
- **Wayland + X11**: evdev hotkeys work on both, no root required
|
|
155
156
|
- **Pre-buffer**: never miss the first syllable
|
|
157
|
+
- **Voice commands**: "new line", "comma", "scratch that", punctuation by name
|
|
158
|
+
- **Autocorrect**: LLM-powered review of recurring Whisper mistakes (`voiceio correct`)
|
|
159
|
+
- **Text-to-speech**: hear selected text spoken back (Piper, eSpeak, Edge TTS)
|
|
160
|
+
- **Smart post-processing**: numbers ("twenty five" → "25"), punctuation, capitalization
|
|
156
161
|
- **Auto-healing**: falls back to the next working backend if one fails
|
|
157
162
|
- **Autostart**: optional systemd service, restarts on crash
|
|
158
163
|
- **Self-diagnosing**: `voiceio doctor` checks everything, `--fix` repairs it
|
|
@@ -176,7 +181,10 @@ voiceio Start the daemon
|
|
|
176
181
|
voiceio setup Interactive setup wizard
|
|
177
182
|
voiceio doctor Health check (--fix to auto-repair)
|
|
178
183
|
voiceio test Test microphone + live transcription
|
|
184
|
+
voiceio demo Interactive guided tour of all features
|
|
179
185
|
voiceio toggle Toggle recording on a running daemon
|
|
186
|
+
voiceio correct Review and fix recurring transcription errors
|
|
187
|
+
voiceio history View transcription history
|
|
180
188
|
voiceio update Update to latest version
|
|
181
189
|
voiceio service install Autostart on login (systemd / Windows Startup)
|
|
182
190
|
voiceio logs View recent logs
|
|
@@ -250,9 +258,8 @@ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) and [open issues](
|
|
|
250
258
|
- [ ] Multiple engine backends (whisper.cpp for Vulkan/AMD, VOSK for low-end hardware)
|
|
251
259
|
- [ ] Echo cancellation (filter system audio for meeting use)
|
|
252
260
|
- [ ] Wake word activation ("Hey voiceio")
|
|
253
|
-
- [ ] Text-to-speech output (Piper/espeak-ng — completes the "io")
|
|
254
|
-
|
|
255
261
|
**Done**
|
|
262
|
+
- [x] Text-to-speech output (Piper/eSpeak/Edge TTS — completes the "io")
|
|
256
263
|
- [x] LLM auto-audit dictionary (`voiceio correct --auto` — scan history with LLM, interactive correction)
|
|
257
264
|
- [x] LLM post-processing via Ollama (grammar cleanup, spelling fixes on final pass)
|
|
258
265
|
- [x] Corrections dictionary — auto-replace misheard words, "correct that" voice command
|
|
@@ -142,7 +142,7 @@ def test_player_empty_audio():
|
|
|
142
142
|
|
|
143
143
|
def test_tts_config_defaults():
|
|
144
144
|
cfg = TTSConfig()
|
|
145
|
-
assert cfg.enabled is
|
|
145
|
+
assert cfg.enabled is True
|
|
146
146
|
assert cfg.engine == "auto"
|
|
147
147
|
assert cfg.hotkey == "ctrl+alt+s"
|
|
148
148
|
assert cfg.voice == ""
|
|
@@ -155,4 +155,4 @@ def test_tts_config_in_main_config():
|
|
|
155
155
|
cfg = Config()
|
|
156
156
|
assert hasattr(cfg, "tts")
|
|
157
157
|
assert isinstance(cfg.tts, TTSConfig)
|
|
158
|
-
assert cfg.tts.enabled is
|
|
158
|
+
assert cfg.tts.enabled is True
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.2"
|
|
@@ -105,7 +105,7 @@ class AutocorrectConfig:
|
|
|
105
105
|
|
|
106
106
|
@dataclass
|
|
107
107
|
class TTSConfig:
|
|
108
|
-
enabled: bool =
|
|
108
|
+
enabled: bool = True
|
|
109
109
|
engine: str = "auto" # "auto" | "piper" | "espeak" | "edge-tts"
|
|
110
110
|
hotkey: str = "ctrl+alt+s" # "s" for speak
|
|
111
111
|
voice: str = "" # empty = engine default
|
|
@@ -142,6 +142,7 @@ def convert_numbers(text: str, language: str = "en") -> str:
|
|
|
142
142
|
# Collect consecutive number words
|
|
143
143
|
if _is_number_word(low) and low != "a" and low != "and":
|
|
144
144
|
num_words = []
|
|
145
|
+
last_category = None # "ones", "tens", "scale"
|
|
145
146
|
j = i
|
|
146
147
|
while j < len(words):
|
|
147
148
|
w = words[j].lower().rstrip(".,;:?!")
|
|
@@ -153,6 +154,7 @@ def convert_numbers(text: str, language: str = "en") -> str:
|
|
|
153
154
|
# "a" at start: only if followed by scale word
|
|
154
155
|
if j + 1 < len(words) and words[j + 1].lower().rstrip(".,;:?!") in _SCALES:
|
|
155
156
|
num_words.append(w)
|
|
157
|
+
last_category = "ones"
|
|
156
158
|
j += 1
|
|
157
159
|
continue
|
|
158
160
|
break
|
|
@@ -163,7 +165,14 @@ def convert_numbers(text: str, language: str = "en") -> str:
|
|
|
163
165
|
j += 1
|
|
164
166
|
continue
|
|
165
167
|
break
|
|
168
|
+
# Two consecutive ones-words = separate numbers
|
|
169
|
+
# e.g. "one two three" should NOT become 6
|
|
170
|
+
# But "twenty three", "one hundred", "thirteen thousand" are valid
|
|
171
|
+
cat = "scale" if w in _SCALES else ("tens" if w in _TENS else "ones")
|
|
172
|
+
if cat == "ones" and last_category == "ones":
|
|
173
|
+
break
|
|
166
174
|
num_words.append(w)
|
|
175
|
+
last_category = cat
|
|
167
176
|
j += 1
|
|
168
177
|
else:
|
|
169
178
|
break
|
|
@@ -19,12 +19,25 @@ class EdgeEngine:
|
|
|
19
19
|
def probe(self) -> ProbeResult:
|
|
20
20
|
try:
|
|
21
21
|
import edge_tts # noqa: F401
|
|
22
|
-
return ProbeResult(ok=True)
|
|
23
22
|
except ImportError:
|
|
24
23
|
return ProbeResult(
|
|
25
24
|
ok=False, reason="edge-tts not installed",
|
|
26
25
|
fix_hint="pip install edge-tts",
|
|
27
26
|
)
|
|
27
|
+
try:
|
|
28
|
+
import soundfile # noqa: F401
|
|
29
|
+
return ProbeResult(ok=True)
|
|
30
|
+
except ImportError:
|
|
31
|
+
pass
|
|
32
|
+
try:
|
|
33
|
+
import pydub # noqa: F401
|
|
34
|
+
return ProbeResult(ok=True)
|
|
35
|
+
except ImportError:
|
|
36
|
+
return ProbeResult(
|
|
37
|
+
ok=False,
|
|
38
|
+
reason="edge-tts needs soundfile or pydub to decode audio",
|
|
39
|
+
fix_hint="pip install soundfile",
|
|
40
|
+
)
|
|
28
41
|
|
|
29
42
|
def synthesize(self, text: str, voice: str, speed: float) -> tuple[np.ndarray, int]:
|
|
30
43
|
import asyncio
|
|
@@ -22,10 +22,11 @@ class PiperEngine:
|
|
|
22
22
|
def probe(self) -> ProbeResult:
|
|
23
23
|
try:
|
|
24
24
|
import piper # noqa: F401
|
|
25
|
+
from piper.download import ensure_voice_exists, get_voices # noqa: F401
|
|
25
26
|
return ProbeResult(ok=True)
|
|
26
|
-
except ImportError:
|
|
27
|
+
except ImportError as e:
|
|
27
28
|
return ProbeResult(
|
|
28
|
-
ok=False, reason="piper-tts not installed",
|
|
29
|
+
ok=False, reason=f"piper-tts not fully installed: {e}",
|
|
29
30
|
fix_hint="pip install piper-tts",
|
|
30
31
|
)
|
|
31
32
|
|