arpabet-and-ipa-convertor-ts
Version:
Typescript code to convert between Arpabet and IPA phonetic transcriptions
177 lines (176 loc) • 5.83 kB
JavaScript
;
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;