tPHONEME_TYPE = 1, | tPHONEME_TYPE = 1, | ||||
tPHONEME_FLAG, | tPHONEME_FLAG, | ||||
tTRANSITION, | tTRANSITION, | ||||
tPLACE, | |||||
tSTATEMENT, | tSTATEMENT, | ||||
tINSTRN1, | tINSTRN1, | ||||
tWHICH_PHONEME, | tWHICH_PHONEME, | ||||
{ "vcd", tPHONEME_FLAG, phVOICED }, | { "vcd", tPHONEME_FLAG, phVOICED }, | ||||
{ "vls", tPHONEME_FLAG, phFORTIS }, | { "vls", tPHONEME_FLAG, phFORTIS }, | ||||
// place of articulation, set bits 16-19 of phflags | |||||
{ "blb", tPLACE, 1 }, | |||||
{ "lbd", tPLACE, 2 }, | |||||
{ "dnt", tPLACE, 3 }, | |||||
{ "alv", tPLACE, 4 }, | |||||
{ "rfx", tPLACE, 5 }, | |||||
{ "pla", tPLACE, 6 }, | |||||
{ "pal", tPLACE, 7 }, | |||||
{ "vel", tPLACE, 8 }, | |||||
{ "lbv", tPLACE, 9 }, | |||||
{ "uvl", tPLACE, 10 }, | |||||
{ "phr", tPLACE, 11 }, | |||||
{ "glt", tPLACE, 12 }, | |||||
// vowel transition attributes | // vowel transition attributes | ||||
{ "len=", tTRANSITION, 1 }, | { "len=", tTRANSITION, 1 }, | ||||
{ "rms=", tTRANSITION, 2 }, | { "rms=", tTRANSITION, 2 }, | ||||
if_stack[0].returned = 0; | if_stack[0].returned = 0; | ||||
after_if = 0; | after_if = 0; | ||||
int phoneme_flags = 0; | int phoneme_flags = 0; | ||||
int place_articulation = 0; | |||||
NextItem(tSTRING); | NextItem(tSTRING); | ||||
if (compile_phoneme) { | if (compile_phoneme) { | ||||
phoneme_out->start_type = 0; | phoneme_out->start_type = 0; | ||||
phoneme_out->end_type = 0; | phoneme_out->end_type = 0; | ||||
phoneme_out->length_mod = 0; | phoneme_out->length_mod = 0; | ||||
phoneme_out->phflags = 0; | |||||
while (!endphoneme && !feof(f_in)) { | while (!endphoneme && !feof(f_in)) { | ||||
if ((keyword = NextItem(tKEYWORD)) < 0) { | if ((keyword = NextItem(tKEYWORD)) < 0) { | ||||
error("More than one phoneme type: %s", item_string); | error("More than one phoneme type: %s", item_string); | ||||
phoneme_out->type = keyword; | phoneme_out->type = keyword; | ||||
break; | break; | ||||
case tPLACE: | |||||
if (place_articulation > 0) | |||||
error("Place of articulation has already been given: %s", item_string); | |||||
place_articulation = keyword; | |||||
break; | |||||
case tPHONEME_FLAG: | case tPHONEME_FLAG: | ||||
phoneme_flags |= keyword; | phoneme_flags |= keyword; | ||||
break; | break; | ||||
error("Phoneme type is missing"); | error("Phoneme type is missing"); | ||||
phoneme_out->type = 0; | phoneme_out->type = 0; | ||||
} | } | ||||
phoneme_out->phflags = place_articulation << 16; | |||||
phoneme_out->phflags |= phoneme_flags; | phoneme_out->phflags |= phoneme_flags; | ||||
if (phoneme_out->phflags & phVOICED) { | if (phoneme_out->phflags & phVOICED) { |
vwl = FEATURE('v', 'w', 'l'), | vwl = FEATURE('v', 'w', 'l'), | ||||
lat = FEATURE('l', 'a', 't'), | lat = FEATURE('l', 'a', 't'), | ||||
sib = FEATURE('s', 'i', 'b'), | sib = FEATURE('s', 'i', 'b'), | ||||
// place of articulation | |||||
blb = FEATURE('b', 'l', 'b'), | |||||
lbd = FEATURE('l', 'b', 'd'), | |||||
bld = FEATURE('b', 'l', 'd'), | |||||
dnt = FEATURE('d', 'n', 't'), | |||||
alv = FEATURE('a', 'l', 'v'), | |||||
pla = FEATURE('p', 'l', 'a'), | |||||
rfx = FEATURE('r', 'f', 'x'), | |||||
alp = FEATURE('a', 'l', 'p'), | |||||
pal = FEATURE('p', 'a', 'l'), | |||||
vel = FEATURE('v', 'e', 'l'), | |||||
lbv = FEATURE('l', 'b', 'v'), | |||||
uvl = FEATURE('u', 'v', 'l'), | |||||
phr = FEATURE('p', 'h', 'r'), | |||||
glt = FEATURE('g', 'l', 't'), | |||||
}; | }; | ||||
uint32_t lookup_feature(const char *feature) { | uint32_t lookup_feature(const char *feature) { | ||||
case sib: | case sib: | ||||
phoneme->phflags |= phSIBILANT; | phoneme->phflags |= phSIBILANT; | ||||
break; | break; | ||||
// place of articulation | |||||
case blb: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 1 << 16; | |||||
break; | |||||
case lbd: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 2 << 16; | |||||
break; | |||||
case dnt: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 3 << 16; | |||||
break; | |||||
case alv: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 4 << 16; | |||||
break; | |||||
case rfx: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 5 << 16; | |||||
break; | |||||
case pla: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 6 << 16; | |||||
break; | |||||
case pal: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 7 << 16; | |||||
break; | |||||
case vel: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 8 << 16; | |||||
break; | |||||
case lbv: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 9 << 16; | |||||
break; | |||||
case uvl: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 10 << 16; | |||||
break; | |||||
case phr: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 11 << 16; | |||||
break; | |||||
case glt: | |||||
phoneme->phflags &= ~phARTICULATION; | |||||
phoneme->phflags |= 12 << 16; | |||||
break; | |||||
case bld: | |||||
// FIXME: Not supported by eSpeak. Used in German p͡f. | |||||
break; | |||||
case alp: | |||||
// FIXME: Not supported by eSpeak. Used in Chinese/Japanese ɕ and ʑ. | |||||
break; | |||||
// invalid phoneme feature | // invalid phoneme feature | ||||
default: | default: | ||||
return create_name_error_context(context, ENS_UNKNOWN_PHONEME_FEATURE, feature); | return create_name_error_context(context, ENS_UNKNOWN_PHONEME_FEATURE, feature); |