Skip to content

Commit

Permalink
backport MycroftAI#2888 (#34)
Browse files Browse the repository at this point in the history
adds XDG support

Co-authored-by: jarbasal <jarbasai@mailfence.com>
  • Loading branch information
JarbasAl and JarbasAl authored May 14, 2021
1 parent 0f336c4 commit 7e22ce2
Showing 1 changed file with 45 additions and 22 deletions.
67 changes: 45 additions & 22 deletions mycroft/tts/mimic_tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import subprocess
from threading import Thread
from time import sleep
from xdg import BaseDirectory as XDG

from mycroft import MYCROFT_ROOT_PATH
from mycroft.api import DeviceApi
Expand All @@ -32,26 +33,43 @@

from mycroft.tts.tts import TTS, TTSValidator

CONFIG = Configuration.get().get("tts").get("mimic")
DATA_DIR = expanduser(Configuration.get()['data_dir'])

BIN = CONFIG.get("path",
os.path.join(MYCROFT_ROOT_PATH, 'mimic', 'bin', 'mimic'))
def get_mimic_binary():
"""Find the mimic binary, either from config or from PATH.
if not os.path.isfile(BIN):
# Search for mimic on the path
import distutils.spawn
Returns:
(str) path of mimic executable
"""
config = Configuration.get(remote=False).get("tts", {}).get("mimic")

bin_ = config.get("path",
os.path.join(MYCROFT_ROOT_PATH, 'mimic', 'bin', 'mimic'))

if not os.path.isfile(bin_):
# Search for mimic on the path
import distutils.spawn

bin_ = distutils.spawn.find_executable("mimic")

BIN = distutils.spawn.find_executable("mimic")
return bin_

SUBSCRIBER_VOICES = {'trinity': join(DATA_DIR, 'voices/mimic_tn')}

def get_subscriber_voices():
"""Get dict of mimic voices exclusive to subscribers.
Returns:
(dict) map of voices to custom Mimic executables.
"""
path = join(XDG.xdg_config_home, 'mycroft', 'voices', 'mimic_tn')
return {'trinity': path}


def download_subscriber_voices(selected_voice):
"""Function to download all premium voices.
The function starts with the currently selected if applicable
"""
subscriber_voices = get_subscriber_voices()

def make_executable(dest):
"""Call back function to make the downloaded file executable."""
Expand All @@ -61,7 +79,7 @@ def make_executable(dest):
os.chmod(dest, file_stat.st_mode | stat.S_IEXEC)

# First download the selected voice if needed
voice_file = SUBSCRIBER_VOICES.get(selected_voice)
voice_file = subscriber_voices.get(selected_voice)
if voice_file is not None and not exists(voice_file):
LOG.info('Voice doesn\'t exist, downloading')
url = DeviceApi().get_subscriber_voice_url(selected_voice)
Expand All @@ -76,8 +94,8 @@ def make_executable(dest):
.format(selected_voice))

# Download the rest of the subsciber voices as needed
for voice in SUBSCRIBER_VOICES:
voice_file = SUBSCRIBER_VOICES[voice]
for voice in subscriber_voices:
voice_file = subscriber_voices[voice]
if not exists(voice_file):
url = DeviceApi().get_subscriber_voice_url(voice)
# Check we got an url
Expand Down Expand Up @@ -111,9 +129,12 @@ def __init__(self, lang, config):
lang, config, MimicValidator(self), 'wav',
ssml_tags=["speak", "ssml", "phoneme", "voice", "audio", "prosody"]
)
self.default_binary = get_mimic_binary()

self.clear_cache()

# Download subscriber voices if needed
self.subscriber_voices = get_subscriber_voices()
self.is_subscriber = DeviceApi().is_subscriber
if self.is_subscriber:
trd = Thread(target=download_subscriber_voices, args=[self.voice])
Expand All @@ -137,18 +158,19 @@ def modify_tag(self, tag):
@property
def args(self):
"""Build mimic arguments."""
if (self.voice in SUBSCRIBER_VOICES and
exists(SUBSCRIBER_VOICES[self.voice]) and self.is_subscriber):
subscriber_voices = self.subscriber_voices
if (self.voice in subscriber_voices and
exists(subscriber_voices[self.voice]) and self.is_subscriber):
# Use subscriber voice
mimic_bin = SUBSCRIBER_VOICES[self.voice]
mimic_bin = subscriber_voices[self.voice]
voice = self.voice
elif self.voice in SUBSCRIBER_VOICES:
elif self.voice in subscriber_voices:
# Premium voice but bin doesn't exist, use ap while downloading
mimic_bin = BIN
mimic_bin = self.default_binary
voice = 'ap'
else:
# Normal case use normal binary and selected voice
mimic_bin = BIN
mimic_bin = self.default_binary
voice = self.voice

args = [mimic_bin, '-voice', voice, '-psdur', '-ssml']
Expand Down Expand Up @@ -195,11 +217,12 @@ def validate_lang(self):

def validate_connection(self):
"""Check that Mimic executable is found and works."""
mimic_bin = get_mimic_binary()
try:
subprocess.call([BIN, '--version'])
subprocess.call([mimic_bin, '--version'])
except Exception as err:
if BIN:
LOG.error('Failed to find mimic at: {}'.format(BIN))
if mimic_bin:
LOG.error('Failed to find mimic at: {}'.format(mimic_bin))
else:
LOG.error('Mimic executable not found')
raise Exception(
Expand Down Expand Up @@ -274,4 +297,4 @@ def get_tts_class(self):
'k': '3',
# blank mouth
'pau': '4',
}
}

0 comments on commit 7e22ce2

Please sign in to comment.