2 Commits

Author SHA1 Message Date
Michael Hansen 6f4992e310 First pass at Dutch IPA 2019-05-19 20:52:43 -04:00
Michael Hansen 8245155fab Working for English 2019-05-19 15:12:15 -04:00
9 changed files with 173 additions and 51 deletions
+1 -1
View File
@@ -363,7 +363,7 @@ def api_pronounce() -> Union[Response, str]:
if pronounce_type == "phonemes":
# Convert from Sphinx to espeak phonemes
espeak_str = core.get_word_phonemes(pronounce_str).phonemes
espeak_str = core.get_word_phonemes(pronounce_str).phonemes["espeak"]
else:
# Speak word directly
espeak_str = pronounce_str
+2 -1
View File
@@ -159,7 +159,8 @@
"program": ""
},
"espeak": {
"phoneme_map": "espeak_phonemes.txt"
"phoneme_map": "espeak_phonemes.txt",
"ipa_map": "ipa_phonemes.txt"
},
"flite": {
"voice": "kal16"
+25
View File
@@ -0,0 +1,25 @@
a abre əbɹˈɛ
b baja bˈɑhɑ
ch ocho ˈɒtʃəʊ
d anda ˈændə
e aire ˈɛə
f café kæfˈeɪ
g agua ˈæɡjʉːə
gn años sˈænsəːn
i allí ˈælɪ
j bajo bˈɑdʒəʊ
k acto ˈæktəʊ
l alex ˈælɪks
ll allá əlˈɑ
m alma ˈɒlmə
n andy ˈændɪ
o algo ˈælɡəʊ
p copa kˈəʊpə
r amor ˈæmɚ
rr raro ɹˈæɹəʊ
s base bˈeɪs
t alta ˈɔːltə
u auto ˈɔːtəʊ
x sexo sˈiksəʊ
y ayer ˈaɪɚ
z azul æzˈʉːl
+25
View File
@@ -0,0 +1,25 @@
a abre a
b baja b
ch ocho tʃ
d anda d
e aire e
f café f
g agua g
gn años ɲ
i allí i
j bajo j
k acto k
l alex l
ll allá ʎ
m alma m
n andy n
o algo o
p copa p
r amor r
rr raro ɾ
s base s
t alta t
u auto u
x sexo x
y ayer ʝ
z azul z
+25 -22
View File
@@ -1,22 +1,25 @@
A A A
B VEZ B E Z
CH MUCHO M U CH O
D DE D E
E EL E L
F FUE F U E
G ALGO A L G O
GN AñOS A GN O S
I Y I
K CON K O N
L AL A L
LL ELLA E LL A
M ME M E
N EN E N
O O O
P POR P O R
R ERA E R A
S ES E S
T TE T E
U SU S U
Y YA Y A
Z HACE A Z E
a abre a b r e
b baja b a j a
ch ocho o ch o
d anda a n d a
e aire a i r e
f café k a f e
g agua a g u a
gn años a gn o s
i allí a ll i
j bajo b a j o
k acto a k t o
l alex a l e x
ll allá a ll a
m alma a l m a
n andy a n d i
o algo a l g o
p copa k o p a
r amor a m o r
rr raro rr a r o
s base b a s e
t alta a l t a
u auto a u t o
x sexo s e x o
y ayer a y e r
z azul a z u l
+38
View File
@@ -0,0 +1,38 @@
@ adem ə
a adam aː
aa acht ɑ
b baan b
d andy d
e baby eː
ee alex ɛ
ei blij ɛi
er albert ɛː
eu deur øː
f cafÉ f
g chicago g
gg hoge ɟ
h haag ɦ
i bier i
ii bill ɪ
j doei j
k bank k
l alle l
m amen m
n anna n
nn bang ŋ
o auto oː
oo bond ɔ
ou bouw ʌu
p club p
r arme r
s arts s
ss chef ʃ
t band t
u boek u
ui buik œy
v dave v
w eeuw ʋ
x berg x
y duur y
yy brug ʒ
z deze z
+2 -1
View File
@@ -1035,7 +1035,8 @@ def word2wav(core: RhasspyCore, profile: Profile, args: Any) -> None:
word_pronunciations = all_pronunciations[args.word]["pronunciations"]
# Convert from CMU phonemes to eSpeak phonemes
espeak_str = core.get_word_phonemes(word_pronunciations[0]).phonemes
sphinx = word_pronunciations[0]
espeak_str = all_pronunciations[args.word]["phonemes"][sphinx]["espeak"]
# Pronounce as WAV
wav_data = core.speak_word(espeak_str).wav_data
+53 -24
View File
@@ -5,6 +5,7 @@ import logging
import subprocess
import tempfile
from typing import Dict, Tuple, List, Optional, Any
from collections import defaultdict
from .actor import RhasspyActor
from .utils import read_dict, load_phoneme_map
@@ -35,7 +36,7 @@ class GetWordPhonemes:
class WordPhonemes:
def __init__(self, word: str, phonemes: str) -> None:
def __init__(self, word: str, phonemes: Dict[str, str]) -> None:
self.word = word
self.phonemes = phonemes
@@ -98,8 +99,11 @@ class PhonetisaurusPronounce(RhasspyActor):
self._logger.exception("pronounce")
self.send(message.receiver or sender, PronunciationFailed(repr(e)))
elif isinstance(message, GetWordPhonemes):
phonemes = self.translate_phonemes(message.word)
self.send(message.receiver or sender, WordPhonemes(message.word, phonemes))
phonemes = self.translate_phonemes([message.word])
self.send(
message.receiver or sender,
WordPhonemes(message.word, phonemes[message.word]),
)
# -------------------------------------------------------------------------
@@ -129,20 +133,49 @@ class PhonetisaurusPronounce(RhasspyActor):
# -------------------------------------------------------------------------
def translate_phonemes(self, phonemes: str) -> str:
# Load map from Sphinx to eSpeak phonemes
def translate_phonemes(self, sphinxes: List[str]) -> Dict[str, Dict[str, str]]:
from .lexconvert import convert
# Load map from Sphinx to IPA
map_path = self.profile.read_path(
self.profile.get("text_to_speech.espeak.phoneme_map")
self.profile.get(
"text_to_speech.espeak.ipa.phoneme_map", "ipa_phonemes.txt"
)
)
phoneme_map = load_phoneme_map(map_path)
if os.path.exists(map_path):
# Compute Sphinx <-> eSpeak map using IPA
ipa_map = load_phoneme_map(map_path)
phoneme_map = {
sphinx: convert(ipa, "unicode-ipa", "espeak")
for sphinx, ipa in ipa_map.items()
}
else:
# Fall back to Sphinx <-> eSpeak map
map_path = self.profile.read_path(
self.profile.get(
"text_to_speech.espeak.phoneme_map", "espeak_phonemes.txt"
)
)
# Convert from Sphinx to espeak phonemes
espeak_str = "[['%s]]" % "".join(
phoneme_map.get(p, p) for p in phonemes.split()
)
phoneme_map = load_phoneme_map(map_path)
ipa_map = {
sphinx: convert(espeak, "espeak", "unicode-ipa")
for sphinx, espeak in phoneme_map.items()
}
return espeak_str
phonemes = defaultdict(dict)
for sphinx in sphinxes:
sphinx_parts = sphinx.split()
# Convert from Sphinx to espeak phonemes
phonemes[sphinx]["espeak"] = "[['%s]]" % "".join(
phoneme_map.get(p, p) for p in sphinx_parts
)
phonemes[sphinx]["ipa"] = "".join(ipa_map.get(p, p) for p in sphinx_parts)
return phonemes
# -------------------------------------------------------------------------
@@ -168,20 +201,16 @@ class PhonetisaurusPronounce(RhasspyActor):
read_dict(dictionary_file, word_dict)
pronunciations = self._lookup_words(words, word_dict, n)
all_pronunciations = []
for pron in pronunciations.values():
all_pronunciations.extend(pron["pronunciations"])
# Get phonemes from eSpeak
for word in words:
espeak_command = ["espeak", "-q", "-x"]
phonemes = self.translate_phonemes(all_pronunciations)
voice = self._get_voice()
if voice is not None:
espeak_command.extend(["-v", voice])
espeak_command.append(word)
self._logger.debug(repr(espeak_command))
espeak_str = subprocess.check_output(espeak_command).decode().strip()
pronunciations[word]["phonemes"] = espeak_str
for word in pronunciations.keys():
pronunciations[word]["phonemes"] = {}
for pron in pronunciations[word]["pronunciations"]:
pronunciations[word]["phonemes"][pron] = phonemes[pron]
return pronunciations
+2 -2
View File
@@ -40,7 +40,7 @@
<button type="button" class="btn btn-success" title="Add this pronunciation to your custom words" @click="addToCustomWords">Add</button>
</div>
<div class="col-xs-auto">
<input id="espeak-phonemes" title="eSpeak Phonemes" class="form-control" type="text" v-model="espeakPhonemes" readonly>
<input id="espeak-phonemes" title="IPA/eSpeak Phonemes" class="form-control" type="text" v-model="espeakPhonemes" readonly>
</div>
<div class="col-xs-auto">
<button type="button" class="btn btn-secondary" @click="pronouncePhonemesOrWord(phonemes)"
@@ -176,7 +176,7 @@
this.phonemes = this.pronunciations[0];
}
this.espeakPhonemes = request.data.phonemes
this.espeakPhonemes = request.data.phonemes[this.phonemes]['ipa']
})
.then(() => this.$parent.endAsync())
.catch(err => this.$parent.error(err))