Compare commits

...

2 Commits

Author SHA1 Message Date
Fabio Manganiello 7e9b19d328
[tts.picovoice] Added text pre-processing workaround.
continuous-integration/drone/push Build is passing Details
This workaround is required until
https://github.com/Picovoice/orca/issues/10 is fixed.
2024-04-13 21:40:05 +02:00
Fabio Manganiello c86e3be0d1
[assistant.picovoice] Leverage upstream `_on_mute_changed`.
The plugin should leverage `AssistantPlugin._on_mute_changed` to handle
the boilerplate state managent on mute/unmute actions instead of
re-implementing the same logic.
2024-04-13 21:00:30 +02:00
3 changed files with 58 additions and 3 deletions

View File

@ -2,7 +2,6 @@ import os
from typing import Optional, Sequence from typing import Optional, Sequence
from platypush.context import get_plugin from platypush.context import get_plugin
from platypush.message.event.assistant import MicMutedEvent, MicUnmutedEvent
from platypush.plugins import RunnablePlugin, action from platypush.plugins import RunnablePlugin, action
from platypush.plugins.assistant import AssistantPlugin from platypush.plugins.assistant import AssistantPlugin
from platypush.plugins.tts.picovoice import TtsPicovoicePlugin from platypush.plugins.tts.picovoice import TtsPicovoicePlugin
@ -239,11 +238,10 @@ class AssistantPicovoicePlugin(AssistantPlugin, RunnablePlugin):
:param muted: Set to True or False. :param muted: Set to True or False.
""" """
self._is_muted = muted
if self._assistant: if self._assistant:
self._assistant.set_mic_mute(muted) self._assistant.set_mic_mute(muted)
self._send_event(MicMutedEvent if muted else MicUnmutedEvent) super()._on_mute_changed(muted)
@action @action
def toggle_mute(self, *_, **__): def toggle_mute(self, *_, **__):

View File

@ -19,6 +19,7 @@ manifest:
- python-numpy - python-numpy
- python-sounddevice - python-sounddevice
pip: pip:
- num2words
- numpy - numpy
- sounddevice - sounddevice
package: platypush.plugins.tts package: platypush.plugins.tts

View File

@ -1,4 +1,6 @@
import logging
import os import os
import re
from threading import RLock from threading import RLock
from typing import Optional from typing import Optional
@ -11,6 +13,56 @@ from platypush.plugins import action
from platypush.plugins.tts import TtsPlugin from platypush.plugins.tts import TtsPlugin
class TextConversionUtils:
"""
Utility class to convert text to a format that is supported by the Orca TTS
engine.
This pre-processing step is necessary until the issue is fixed:
https://github.com/Picovoice/orca/issues/10.
"""
_logger = logging.getLogger(__name__)
_number_re = re.compile(r'(([0-9]+)|([0-9]+\.[0-9]+)|([0-9]+\,[0-9]+))')
_conversions_map = {
(re.compile(r'[(){}\[\]<>]'), ','),
(re.compile(r'[:;]'), '.'),
(re.compile(r'[@#]'), ' at '),
(re.compile(r'[$]'), ' dollar '),
(re.compile(r'[%]'), ' percent '),
(re.compile(r'[&]'), ', and'),
(re.compile(r'[+]'), ' plus '),
(re.compile(r'[=]'), ' equals '),
(re.compile(r'[|]'), ' or '),
(re.compile(r'[~]'), ' tilde '),
(re.compile(r'[`\'"]'), ': quote:'),
(re.compile(r'[*]'), ' star '),
(re.compile(r'[\\/]'), ' slash '),
(re.compile(r'[_]'), ' underscore '),
}
@classmethod
def _convert_digits(cls, text: str) -> str:
try:
from num2words import num2words
except ImportError:
cls._logger.warning('num2words is not installed, skipping digit conversion')
return text
while match := cls._number_re.search(text):
number = match.group(1).replace(',', '')
text = text.replace(number, num2words(int(number)))
return text
@classmethod
def convert(cls, text: str) -> str:
for pattern, replacement in TextConversionUtils._conversions_map:
text = pattern.sub(replacement, text)
return cls._convert_digits(text)
class TtsPicovoicePlugin(TtsPlugin): class TtsPicovoicePlugin(TtsPlugin):
""" """
This TTS plugin enables you to render text as audio using `Picovoice This TTS plugin enables you to render text as audio using `Picovoice
@ -108,7 +160,11 @@ class TtsPicovoicePlugin(TtsPlugin):
:param model_path: Path of the TTS model file (default: use the default :param model_path: Path of the TTS model file (default: use the default
configured model). configured model).
""" """
# This is a temporary workaround until this issue is fixed:
# https://github.com/Picovoice/orca/issues/10.
text = TextConversionUtils.convert(text)
orca = self.get_orca(model_path=model_path) orca = self.get_orca(model_path=model_path)
if output_file: if output_file:
orca.synthesize_to_file( orca.synthesize_to_file(
text, os.path.expanduser(output_file), speech_rate=speech_rate text, os.path.expanduser(output_file), speech_rate=speech_rate