/* * 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: . */ #include "config.h" #include #include #include #include #include #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; }