UNPKG

arpabet-and-ipa-convertor-ts

Version:

Typescript code to convert between Arpabet and IPA phonetic transcriptions

177 lines (176 loc) 5.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toArpabet = void 0; var phonemes_1 = require("./phonemes"); var phoneme_error_1 = require("./phoneme-error"); var stress_1 = require("./model/stress"); var syllable_1 = require("./model/syllable"); var word_1 = require("./model/word"); /* Stress and auxiliary symbols[3] AB Description 0 No stress 1 Primary stress 2 Secondary stress 3... Tertiary and futher stress - Silence ! Non-speech segment + Morpheme boundary / Word boundary # Utterance boundary : Tone group boundary :1 or . Falling or declining juncture :2 or ? Rising or internal juncture :3 or . Fall-rise or non-term juncture*/ var ConvertPriority; (function (ConvertPriority) { ConvertPriority[ConvertPriority["American"] = 0] = "American"; ConvertPriority[ConvertPriority["English"] = 1] = "English"; ConvertPriority[ConvertPriority["IPA"] = 2] = "IPA"; })(ConvertPriority || (ConvertPriority = {})); var ipaTree = {}; var kkTree = {}; var djTree = {}; phonemes_1.vowels.forEach(function (o) { ipaTree[o.ipa] = o; kkTree[o.american] = o; djTree[o.english] = o; }); phonemes_1.consonants.forEach(function (o) { ipaTree[o.ipa] = o; kkTree[o.american] = o; djTree[o.english] = o; }); var skip = [ ["(", ")"], ["\uff08", "\uff09"], ]; var skipDict = {}; skip.forEach(function (skip) { skipDict[skip[0]] = skip[1]; }); var stressDict = {}; var primaryStressIpa = ["'", "\u02c8"]; primaryStressIpa.forEach(function (str) { stressDict[str] = stress_1.Stress.Primary; }); var secondaryStressIpa = ["\u02cc"]; secondaryStressIpa.forEach(function (str) { stressDict[str] = stress_1.Stress.Secondary; }); var ipaStops = [",", "-"]; function isStop(c) { return ipaStops.includes(c); } function findPhonemeInPhonemeTrees(phonemeString, phonemeTrees) { for (var _i = 0, phonemeTrees_1 = phonemeTrees; _i < phonemeTrees_1.length; _i++) { var phonemeTree = phonemeTrees_1[_i]; var phoneme = phonemeTree[phonemeString]; if (phoneme) { return phoneme; } } return null; } function createPhonemeTreesList(priority) { if ((ConvertPriority.American === priority)) { return [kkTree, ipaTree, djTree]; } if ((ConvertPriority.English === priority)) { return [djTree, ipaTree, kkTree]; } if ((ConvertPriority.IPA === priority)) { return [ipaTree, kkTree, djTree]; } throw new Error('Priority not recognised'); } function toArpabet(input, priority) { if (priority === void 0) { priority = ConvertPriority.American; } if ((!input)) { return null; } var tempCh = ""; var skipStack = []; var phonemeTrees = createPhonemeTreesList(priority); var lastPhoneme = null; var word = new word_1.Word(); var syllable = new syllable_1.Syllable(); var tempSyllableStr = ""; var chars = input.split(''); chars.forEach(function (ch, index) { if (isStop(ch)) { return; } tempSyllableStr += ch; if (skipStack.length) { if ((ch === skipDict[skipStack.slice((-1))[0]])) { skipStack.pop(); } return; } else { if (skipDict[ch]) { skipStack.push(ch); return; } } var stress = stressDict[ch]; if (stress) { if (((!lastPhoneme) && (index > 0))) { // 存在不能识别的音标 ${temp_ch} throw new phoneme_error_1.PhonemeError("There is an unrecognized phonetic transcription " + tempCh); } else { /* 遇到重音标识,说明前面是是一个音节,添加到word中,并清空last_phoneme及temp_ch */ if (lastPhoneme) { syllable.addPhoneme(lastPhoneme); if ((!syllable.haveVowel)) { // ${tempSyllableStr} 重音标识不合适,${ch}前一个音节没有元音! throw new phoneme_error_1.PhonemeError(tempSyllableStr + " The accent mark is inappropriate, and the previous syllable of " + ch + " has no vowels!"); } word.addSyllable(syllable); syllable = new syllable_1.Syllable(); } lastPhoneme = null; tempCh = ""; tempSyllableStr = ch; syllable.stress = stress; return; } } tempCh += ch; var tempPhoneme = findPhonemeInPhonemeTrees(tempCh, phonemeTrees); if ((lastPhoneme && (!tempPhoneme))) { /* 说明前面是是一个完整音标 */ syllable.addPhoneme(lastPhoneme); if (lastPhoneme.isVowel) { word.addSyllable(syllable); syllable = new syllable_1.Syllable(); tempSyllableStr = ch; } tempCh = ch; lastPhoneme = findPhonemeInPhonemeTrees(tempCh, phonemeTrees); } else { lastPhoneme = tempPhoneme; } }); if (lastPhoneme) { syllable.addPhoneme(lastPhoneme); if ((syllable.stress && (!syllable.haveVowel))) { // ${tempSyllableStr} 有重音标识但并没有元音! throw new phoneme_error_1.PhonemeError(tempSyllableStr + " has accent marks but no vowels!"); } word.addSyllable(syllable); } else { // 存在不能识别的音标 ${temp_ch} throw new phoneme_error_1.PhonemeError("There is an unrecognized phonetic transcription " + tempCh); } return word.toArpabet(); } exports.toArpabet = toArpabet;