@@ -219,24 +219,20 @@ static keywtab_t k_intonation[] = { | |||
}; | |||
static keywtab_t keywords[] = { | |||
{ "vowel", tPHONEME_TYPE, phVOWEL }, | |||
{ "vowel", tPHONEME_TYPE, phVOWEL }, // TODO (deprecated): use 'vwl' instead | |||
{ "liquid", tPHONEME_TYPE, phLIQUID }, | |||
{ "pause", tPHONEME_TYPE, phPAUSE }, | |||
{ "stress", tPHONEME_TYPE, phSTRESS }, | |||
{ "virtual", tPHONEME_TYPE, phVIRTUAL }, | |||
{ "fricative", tPHONEME_TYPE, phFRICATIVE }, | |||
{ "fricative", tPHONEME_TYPE, phFRICATIVE }, // TODO (deprecated): use 'frc' instead | |||
{ "vstop", tPHONEME_TYPE, phVSTOP }, | |||
{ "vfricative", tPHONEME_TYPE, phVFRICATIVE }, | |||
{ "delete_phoneme", tPHONEME_TYPE, phDELETED }, | |||
// type of consonant | |||
{ "stop", tPHONEME_TYPE, phSTOP }, | |||
{ "frc", tPHONEME_TYPE, phFRICATIVE }, | |||
{ "nasal", tPHONEME_TYPE, phNASAL }, | |||
{ "flp", tPHONEME_TYPE, phVSTOP }, | |||
{ "afr", tPHONEME_TYPE, phSTOP }, // treat as stop | |||
{ "apr", tPHONEME_TYPE, phFRICATIVE }, // [h] voiceless approximant | |||
{ "stop", tPHONEME_TYPE, phSTOP }, // TODO (deprecated): use 'stp' instead | |||
{ "nasal", tPHONEME_TYPE, phNASAL }, // TODO (deprecated): use 'nas' instead | |||
// keywords | |||
{ "phonemenumber", tSTATEMENT, kPHONEMENUMBER }, | |||
@@ -304,7 +300,7 @@ static keywtab_t keywords[] = { | |||
{ "fortis", tPHONEME_FLAG, phFORTIS }, | |||
{ "sibilant", tPHONEME_FLAG, phSIBILANT }, | |||
{ "nolink", tPHONEME_FLAG, phNOLINK }, | |||
{ "trill", tPHONEME_FLAG, phTRILL }, | |||
{ "trill", tPHONEME_FLAG, phTRILL }, // TODO (deprecated): use 'trl' instead | |||
{ "vowel2", tPHONEME_FLAG, phVOWEL2 }, | |||
{ "palatal", tPHONEME_FLAG, phPALATAL }, | |||
{ "long", tPHONEME_FLAG, phLONG }, |
@@ -26,11 +26,38 @@ | |||
#include "speech.h" | |||
#include "error.h" | |||
// See docs/phonemes.md for the list of supported features. | |||
enum feature_t { | |||
inv, // invalid phoneme feature name | |||
// invalid phoneme feature name | |||
inv, // Not in docs/phonemes.md. This is used to signal an unknown feature name. | |||
// manner of articulation | |||
nas, | |||
stp, | |||
afr, | |||
frc, | |||
flp, | |||
trl, | |||
apr, | |||
clk, | |||
ejc, | |||
imp, | |||
vwl, | |||
}; | |||
static MNEM_TAB features[] = { | |||
// manner of articulation | |||
{ "nas", nas }, | |||
{ "stp", stp }, | |||
{ "frc", frc }, | |||
{ "afr", afr }, | |||
{ "flp", flp }, | |||
{ "trl", trl }, | |||
{ "apr", apr }, | |||
{ "clk", clk }, | |||
{ "ejc", ejc }, | |||
{ "imp", imp }, | |||
{ "vwl", vwl }, | |||
// invalid phoneme feature | |||
{ NULL, inv }, | |||
}; | |||
@@ -43,6 +70,33 @@ phoneme_add_feature(PHONEME_TAB *phoneme, | |||
switch (LookupMnem(features, feature)) | |||
{ | |||
// manner of articulation | |||
case nas: | |||
phoneme->type = phNASAL; | |||
break; | |||
case stp: | |||
case afr: // FIXME: eSpeak treats 'afr' as 'stp'. | |||
phoneme->type = phSTOP; | |||
break; | |||
case frc: | |||
case apr: // FIXME: eSpeak is using this for [h], with 'liquid' used for [l] and [r]. | |||
phoneme->type = phFRICATIVE; | |||
break; | |||
case flp: // FIXME: Why is eSpeak using a vstop (vcd + stp) for this? | |||
phoneme->type = phVSTOP; | |||
break; | |||
case trl: // FIXME: 'trill' should be the type; 'liquid' should be a flag (phoneme files specify both). | |||
phoneme->phflags |= phTRILL; | |||
break; | |||
case clk: | |||
case ejc: | |||
case imp: | |||
// Not supported by eSpeak. | |||
break; | |||
case vwl: | |||
phoneme->type = phVOWEL; | |||
break; | |||
// invalid phoneme feature | |||
default: | |||
return create_name_error_context(context, ENS_UNKNOWN_PHONEME_FEATURE, feature); | |||
} |