123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- * Copyright (C) 2017 Reece H. Dunn
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see: <http://www.gnu.org/licenses/>.
- */
-
- #include "config.h"
-
- #include <errno.h>
- #include <stdint.h>
- #include <string.h>
-
- #include <espeak-ng/espeak_ng.h>
- #include <espeak-ng/speak_lib.h>
-
- #include "phoneme.h"
-
- phoneme_feature_t phoneme_feature_from_string(const char *feature)
- {
- if (!feature || strlen(feature) != 3)
- return inv;
- return (feature[0] << 16) | (feature[1] << 8) | feature[2];
- }
-
- espeak_ng_STATUS
- phoneme_add_feature(PHONEME_TAB *phoneme,
- phoneme_feature_t feature)
- {
- if (!phoneme) return EINVAL;
- switch (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:
- case lat:
- // Not supported by eSpeak.
- break;
- case vwl:
- phoneme->type = phVOWEL;
- break;
- case sib:
- phoneme->phflags |= phSIBILANT;
- break;
- // place of articulation
- case blb:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_BILABIAL << 16;
- break;
- case lbd:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_LABIODENTAL << 16;
- break;
- case dnt:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_DENTAL << 16;
- break;
- case alv:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_ALVEOLAR << 16;
- break;
- case rfx:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_RETROFLEX << 16;
- break;
- case pla:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_PALATO_ALVEOLAR << 16;
- break;
- case pal:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_PALATAL << 16;
- phoneme->phflags |= phPALATAL;
- break;
- case vel:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_VELAR << 16;
- break;
- case lbv:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_LABIO_VELAR << 16;
- break;
- case uvl:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_UVULAR << 16;
- break;
- case phr:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_PHARYNGEAL << 16;
- break;
- case glt:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_GLOTTAL << 16;
- break;
- case bld:
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_BILABIAL << 16;
- break;
- case alp: // pla pzd
- phoneme->phflags &= ~phARTICULATION;
- phoneme->phflags |= phPLACE_PALATO_ALVEOLAR << 16;
- phoneme->phflags |= phPALATAL;
- break;
- // voice
- case vcd:
- phoneme->phflags |= phVOICED;
- break;
- case vls:
- phoneme->phflags |= phVOICELESS;
- break;
- // vowel height
- case hgh:
- case smh:
- case umd:
- case mid:
- case lmd:
- case sml:
- case low:
- // Not supported by eSpeak.
- break;
- // vowel backness
- case fnt:
- case cnt:
- case bck:
- // Not supported by eSpeak.
- break;
- // rounding
- case unr:
- case rnd:
- // Not supported by eSpeak.
- break;
- // articulation
- case lgl:
- case idt:
- case apc:
- case lmn:
- // Not supported by eSpeak.
- break;
- // air flow
- case egs:
- case igs:
- // Not supported by eSpeak.
- break;
- // phonation
- case brv:
- case slv:
- case stv:
- case crv:
- case glc:
- // Not supported by eSpeak.
- break;
- // rounding and labialization
- case ptr:
- case cmp:
- case mrd:
- case lrd:
- // Not supported by eSpeak.
- break;
- // syllabicity
- case syl:
- // Not supported by eSpeak.
- break;
- case nsy:
- phoneme->phflags |= phNONSYLLABIC;
- break;
- // consonant release
- case asp:
- case nrs:
- case lrs:
- case unx:
- // Not supported by eSpeak.
- break;
- // coarticulation
- case pzd:
- phoneme->phflags |= phPALATAL;
- break;
- case vzd:
- case fzd:
- case nzd:
- case rzd:
- // Not supported by eSpeak.
- break;
- // tongue root
- case atr:
- case rtr:
- // Not supported by eSpeak.
- break;
- // fortis and lenis
- case fts:
- case lns:
- // Not supported by eSpeak.
- break;
- // length
- case est:
- case hlg:
- // Not supported by eSpeak.
- break;
- case elg: // FIXME: Should be longer than 'lng'.
- case lng:
- phoneme->phflags |= phLONG;
- break;
- // invalid phoneme feature
- default:
- return ENS_UNKNOWN_PHONEME_FEATURE;
- }
- return ENS_OK;
- }
|