UNPKG

echogarden

Version:

An easy-to-use speech toolset. Includes tools for synthesis, recognition, alignment, speech translation, language detection, source separation and more.

177 lines 6.92 kB
import { getShortLanguageCode } from '../utilities/Locale.js'; import { substituteCharactersUsingLookup } from '../utilities/StringUtilities.js'; export function getNormalizedFragmentsForSpeech(words, language) { language = getShortLanguageCode(language); if (language != 'en') { return { normalizedFragments: [...words], referenceFragments: [...words] }; } const numberPattern = /^[0-9][0-9\,\.]*$/; const fourDigitYearPattern = /^[0-9][0-9][0-9][0-9]$/; const fourDigitDecadePattern = /^[0-9][0-9][0-9]0s$/; const fourDigitYearRangePattern = /^[0-9][0-9][0-9][0-9][\-\–][0-9][0-9][0-9][0-9]$/; const wordsPrecedingAYear = [ 'in', 'the', 'a', 'to', 'of', 'since', 'from', 'between', 'by', 'until', 'around', 'before', 'after', 'his', 'her', 'year', 'years', 'during', 'copyright', '©', 'early', 'mid', 'late', 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december', 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ]; const wordsPrecedingADecade = [ 'the', 'in', 'early', 'mid', 'late', 'a' ]; const symbolsPrecedingACurrency = [ '$', '€', '£', '¥' ]; const symbolsPrecedingACurrencyAsWords = [ 'dollars', 'euros', 'pounds', 'yen' ]; const wordsSucceedingACurrency = [ 'million', 'billion', 'trillion' ]; const normalizedFragments = []; const referenceFragments = []; for (let wordIndex = 0; wordIndex < words.length; wordIndex++) { const word = words[wordIndex]; const lowerCaseWord = word.toLowerCase(); const nextWords = words.slice(wordIndex + 1); const nextWord = nextWords[0]; if ( // Normalize a four digit year pattern, e.g. 'in 1995'. wordsPrecedingAYear.includes(lowerCaseWord) && fourDigitYearPattern.test(nextWord)) { const normalizedString = normalizeFourDigitYearString(nextWord); normalizedFragments.push(word); referenceFragments.push(word); normalizedFragments.push(normalizedString); referenceFragments.push(nextWord); wordIndex += 1; } else if ( // Normalize a four digit decade pattern, e.g. 'the 1980s'. wordsPrecedingADecade.includes(lowerCaseWord) && fourDigitDecadePattern.test(nextWord)) { const normalizedString = normalizeFourDigitDecadeString(nextWord); normalizedFragments.push(word); referenceFragments.push(word); normalizedFragments.push(normalizedString); referenceFragments.push(nextWord); wordIndex += 1; } else if ( // Normalize a year range pattern, e.g. '1835-1896' fourDigitYearRangePattern.test(words.slice(wordIndex, wordIndex + 3).join(''))) { normalizedFragments.push(normalizeFourDigitYearString(words[wordIndex])); referenceFragments.push(words[wordIndex]); normalizedFragments.push('to'); referenceFragments.push(words[wordIndex + 1]); normalizedFragments.push(normalizeFourDigitYearString(words[wordIndex + 2])); referenceFragments.push(words[wordIndex + 2]); wordIndex += 2; } else if ( // Normalize a currency pattern, e.g. '$53.1 million', '€3.53' symbolsPrecedingACurrency.includes(lowerCaseWord) && numberPattern.test(nextWord)) { let currencyWord = symbolsPrecedingACurrencyAsWords[symbolsPrecedingACurrency.indexOf(lowerCaseWord)]; if (wordsSucceedingACurrency.includes(nextWords[1].toLowerCase())) { const normalizedString = `${nextWord} ${nextWords[1]} ${currencyWord}`; normalizedFragments.push(normalizedString); const referenceString = `${word}${nextWord} ${nextWords[1]}`; referenceFragments.push(referenceString); wordIndex += 2; } else { const normalizedString = `${nextWord} ${currencyWord}`; normalizedFragments.push(normalizedString); const referenceString = `${word}${nextWord}`; referenceFragments.push(referenceString); wordIndex += 1; } } else { normalizedFragments.push(word); referenceFragments.push(word); } } return { normalizedFragments, referenceFragments }; } export function normalizeFourDigitYearString(yearString) { const firstTwoDigitsValue = parseFloat(yearString.substring(0, 2)); const secondTwoDigitsValue = parseFloat(yearString.substring(2, 4)); let normalizedString; if (firstTwoDigitsValue >= 10 && secondTwoDigitsValue >= 10) { normalizedString = `${firstTwoDigitsValue} ${secondTwoDigitsValue}`; } else if (firstTwoDigitsValue >= 10 && firstTwoDigitsValue % 10 != 0 && secondTwoDigitsValue < 10) { normalizedString = `${firstTwoDigitsValue} oh ${secondTwoDigitsValue}`; } else { normalizedString = yearString; } return normalizedString; } export function normalizeFourDigitDecadeString(decadeString) { const firstTwoDigitsValue = parseInt(decadeString.substring(0, 2)); const secondTwoDigitsValue = parseInt(decadeString.substring(2, 4)); let normalizedString; const isBeforeSecondMillenium = firstTwoDigitsValue < 10; const isMilleniumDecade = firstTwoDigitsValue % 10 == 0 && secondTwoDigitsValue == 0; if (!isBeforeSecondMillenium && !isMilleniumDecade) { if (secondTwoDigitsValue != 0) { normalizedString = `${firstTwoDigitsValue} ${secondTwoDigitsValue}s`; } else { normalizedString = `${firstTwoDigitsValue} hundreds`; } } else { normalizedString = decadeString; } return normalizedString; } export function simplifyPunctuationCharacters(text) { return substituteCharactersUsingLookup(text, punctuationSubstitutionLookup); } export const punctuationSubstitutionLookup = { '“': `"`, '”': `"`, '‟': `"`, 'ˮ': `"`, '„': `"`, '‹': `"`, '›': `"`, '❮': `"`, '❯': '"', '«': `"`, '»': `"`, '״': `"`, '❝': `"`, '❞': `"`, '🙶': `"`, '🙷': `"`, '⹂': `"`, '〝': `"`, '〞': `"`, '〟': `"`, '"': `"`, '❠': `"`, '🙸': `"`, 'ߵ': `'`, 'ߴ': `'`, '’': `'`, '‘': `'`, 'ʹ': `'`, 'ʼ': `'`, ''': `'`, 'ʻ': `'`, '՚': `'`, '՛': `'`, '❛': `'`, '❜': `'`, '❟': `'`, ',': `,`, '、': `,`, ':': `:`, ';': `;`, '。': `.`, '?': `?`, '؟': `?`, '!': `!`, '¡': `!`, }; //# sourceMappingURL=TextNormalizer.js.map