abstractvoice 0.6.1__py3-none-any.whl → 0.6.2__py3-none-any.whl
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.
- abstractvoice/__init__.py +1 -1
- abstractvoice/examples/cli_repl.py +6 -1
- abstractvoice/text_sanitize.py +33 -0
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/METADATA +1 -1
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/RECORD +9 -8
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/WHEEL +0 -0
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/entry_points.txt +0 -0
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/licenses/LICENSE +0 -0
- {abstractvoice-0.6.1.dist-info → abstractvoice-0.6.2.dist-info}/top_level.txt +0 -0
abstractvoice/__init__.py
CHANGED
|
@@ -19,6 +19,7 @@ import threading
|
|
|
19
19
|
import time
|
|
20
20
|
import requests
|
|
21
21
|
from abstractvoice import VoiceManager
|
|
22
|
+
from abstractvoice.text_sanitize import sanitize_markdown_for_speech
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
# ANSI color codes
|
|
@@ -1563,6 +1564,10 @@ class VoiceREPL(cmd.Cmd):
|
|
|
1563
1564
|
if not self.voice_manager:
|
|
1564
1565
|
return
|
|
1565
1566
|
|
|
1567
|
+
# LLM output often contains Markdown. Strip the most common formatting
|
|
1568
|
+
# tokens so TTS stays natural (do not change what is printed).
|
|
1569
|
+
speak_text = sanitize_markdown_for_speech(text)
|
|
1570
|
+
|
|
1566
1571
|
is_clone = bool(self.current_tts_voice)
|
|
1567
1572
|
if not is_clone:
|
|
1568
1573
|
# Offline-first: Piper voices must be explicitly cached. Provide a clear
|
|
@@ -1583,7 +1588,7 @@ class VoiceREPL(cmd.Cmd):
|
|
|
1583
1588
|
try:
|
|
1584
1589
|
if is_clone:
|
|
1585
1590
|
ind.start()
|
|
1586
|
-
self.voice_manager.speak(
|
|
1591
|
+
self.voice_manager.speak(speak_text, voice=self.current_tts_voice)
|
|
1587
1592
|
|
|
1588
1593
|
if not is_clone:
|
|
1589
1594
|
return
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Lightweight text sanitizers for better speech UX.
|
|
2
|
+
|
|
3
|
+
Design goals:
|
|
4
|
+
- No heavy dependencies (regex only).
|
|
5
|
+
- Deterministic and conservative (only strip the most common Markdown syntax).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_MD_HEADER_RE = re.compile(r"(?m)^[ \t]*#{1,5}(?!#)[ \t]*(\S.*)$")
|
|
14
|
+
_MD_BOLD_RE = re.compile(r"\*\*([^*\n]+?)\*\*")
|
|
15
|
+
# Avoid matching "**bold**" as italic. The bold pass runs first, but keep this safe.
|
|
16
|
+
_MD_ITALIC_RE = re.compile(r"(?<!\*)\*([^*\n]+?)\*(?!\*)")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def sanitize_markdown_for_speech(text: str) -> str:
|
|
20
|
+
"""Remove common Markdown syntax that sounds bad in TTS.
|
|
21
|
+
|
|
22
|
+
Intentionally minimal:
|
|
23
|
+
- Strip ATX headers at the start of a line: "#", "##", ... "#####"
|
|
24
|
+
- Strip emphasis markers: "**bold**" and "*italic*"
|
|
25
|
+
"""
|
|
26
|
+
if not text:
|
|
27
|
+
return ""
|
|
28
|
+
|
|
29
|
+
out = str(text)
|
|
30
|
+
out = _MD_HEADER_RE.sub(r"\1", out)
|
|
31
|
+
out = _MD_BOLD_RE.sub(r"\1", out)
|
|
32
|
+
out = _MD_ITALIC_RE.sub(r"\1", out)
|
|
33
|
+
return out
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
abstractvoice/__init__.py,sha256=
|
|
1
|
+
abstractvoice/__init__.py,sha256=lR9Enlcyz-n1wcDq3vO2WpeujVAMOP3LzVAtZFr9wA8,817
|
|
2
2
|
abstractvoice/__main__.py,sha256=EVhZgFwWHBaeRcz1cVoILCzibCyxpD9V9nCOQiO1yUU,8357
|
|
3
3
|
abstractvoice/artifacts.py,sha256=jHcOK6q4barEh92og1oy52b5p4IqC9AwyKbZzFIitww,5750
|
|
4
4
|
abstractvoice/dependency_check.py,sha256=3iz5-bwCQOJvh1jeC9NO8mmlKjuN5LKZ7ZKVy7zcjQw,10002
|
|
5
5
|
abstractvoice/prefetch.py,sha256=XciaG-OPuOLbAbVauyWJdcVh2oDHuyBMJ9a9bht0kwA,2939
|
|
6
6
|
abstractvoice/recognition.py,sha256=xkCjKGKIfHKLuvM-rcdVVfVzZqhcVUv1sqABnZokgJU,27623
|
|
7
7
|
abstractvoice/stop_phrase.py,sha256=PLUkL2uM6n0J--uFs_O_VeIWN6k2-jNhVlmKBol02ys,3382
|
|
8
|
+
abstractvoice/text_sanitize.py,sha256=9dt_NiwTYWjUOSaVK19Pr9a_HDWOovURQLpevQjgF1A,964
|
|
8
9
|
abstractvoice/voice_manager.py,sha256=6M1yT9etb6TQWoAmgqhfGWSex7Blg2bzlLTJZTytL7s,234
|
|
9
10
|
abstractvoice/adapters/__init__.py,sha256=PRhDqLA6cj_fEYMkp54PJ5xrAiEt2oEvE5yVK1MKbP4,452
|
|
10
11
|
abstractvoice/adapters/base.py,sha256=GXmBcwvrVpCCIsNcnClMdvn--ngxMZxp0zjfFvVHYd4,6212
|
|
@@ -25,7 +26,7 @@ abstractvoice/compute/device.py,sha256=IM4hf45RRs8u-ZJI81PSX5i_vI9YJosvuy-XqCImn
|
|
|
25
26
|
abstractvoice/config/__init__.py,sha256=VK2uK7bMbFDL6-WlZV-FXmKO1Ii-ezbwYN-rHo2lUTQ,54
|
|
26
27
|
abstractvoice/config/voice_catalog.py,sha256=py5D2qO4tL_PezEtDRyS48BzkA6MiX_l06BsE-Xa5NA,496
|
|
27
28
|
abstractvoice/examples/__init__.py,sha256=94vpKJDlfOrEBIUETg-57Q5Z7fYDidg6v4UzV7V_lZA,60
|
|
28
|
-
abstractvoice/examples/cli_repl.py,sha256=
|
|
29
|
+
abstractvoice/examples/cli_repl.py,sha256=VEyJvaqGdithxpjwqM8gOS2DuwPp28oIKMuzEPKTSq4,128751
|
|
29
30
|
abstractvoice/examples/voice_cli.py,sha256=jJ27H7VtwFTktEixxt4Ne_u5vwcZoTiL7oninqCmjio,11068
|
|
30
31
|
abstractvoice/examples/web_api.py,sha256=0g5LKJpl7fZepPQJL25AcdaevV-xv34VqqyWGYYchPk,6376
|
|
31
32
|
abstractvoice/integrations/__init__.py,sha256=NsLg9ewvcXwBP118n0BDg4ye5KMWdcsHxikhkfaIs5s,61
|
|
@@ -44,9 +45,9 @@ abstractvoice/vm/core.py,sha256=UL4dFxnggn7ueEmECGS1vRpW7qZMB2FcZjrn3OWXwgU,5305
|
|
|
44
45
|
abstractvoice/vm/manager.py,sha256=4yZI-LdBUP3LriEyY3kV3dKF25AO8r-JAR3YV-YLmWY,4158
|
|
45
46
|
abstractvoice/vm/stt_mixin.py,sha256=5VZ7lVwsy1yGt0UVA4Ixfvyp-1pHqAQJjv0QmQXAedo,5932
|
|
46
47
|
abstractvoice/vm/tts_mixin.py,sha256=GvPC73YjfkkoA6rYrHYqf_FhbzRMuZVbzQ88QubjDQs,22525
|
|
47
|
-
abstractvoice-0.6.
|
|
48
|
-
abstractvoice-0.6.
|
|
49
|
-
abstractvoice-0.6.
|
|
50
|
-
abstractvoice-0.6.
|
|
51
|
-
abstractvoice-0.6.
|
|
52
|
-
abstractvoice-0.6.
|
|
48
|
+
abstractvoice-0.6.2.dist-info/licenses/LICENSE,sha256=TiDPM5WcFRQPoC5e46jGMeMppZ-eu0eFx_HytjE49bk,1105
|
|
49
|
+
abstractvoice-0.6.2.dist-info/METADATA,sha256=mDZobk4G5Bd9FzINxFmxHU9ciCu0Os8vMaLJ06bUOZc,7213
|
|
50
|
+
abstractvoice-0.6.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
51
|
+
abstractvoice-0.6.2.dist-info/entry_points.txt,sha256=PT4IchtBfcgcjlhbX_84WKyCpe-HWzjpNgJ24Kordco,234
|
|
52
|
+
abstractvoice-0.6.2.dist-info/top_level.txt,sha256=a1qyxqgF1O8cJtPKpcJuImGZ_uXqPNghbLZ9gp-UiOo,14
|
|
53
|
+
abstractvoice-0.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|