phonemize
Version:
Fast phonemizer with rule-based G2P prediction. Pure JavaScript implementation.
2 lines (1 loc) • 7.24 kB
JavaScript
import*as kanjiDict from"./ja/kanji.json";import*as kanjiWords from"./ja/words.json";import{r as resolveJson}from"./utils-Bo_ZN3X7.mjs";var JA_DIGITS=[`ぜろ`,`いち`,`に`,`さん`,`よん`,`ご`,`ろく`,`なな`,`はち`,`きゅう`],JA_TEN=`じゅう`,JA_HUNDRED=`ひゃく`,JA_THOUSAND=`せん`,JA_TEN_THOUSAND=`まん`,JA_HUNDRED_MILLION=`おく`;function readSection(e){if(e===0)return``;var f=``,p=Math.floor(e/1e3),v=Math.floor(e%1e3/100),y=Math.floor(e%100/10),b=e%10;return p>0&&(f+=(p===1?``:JA_DIGITS[p])+JA_THOUSAND),v>0&&(f+=(v===1?``:JA_DIGITS[v])+JA_HUNDRED),y>0&&(f+=(y===1?``:JA_DIGITS[y])+JA_TEN),b>0&&(f+=JA_DIGITS[b]),f}function numberToWords(e){if(e===0)return JA_DIGITS[0];if(e<0)return`マイナス`+numberToWords(-e);var f=Math.floor(e/1e8),p=Math.floor(e%1e8/1e4),h=e%1e4,g=``;return f>0&&(g+=readSection(f)+JA_HUNDRED_MILLION),p>0&&(g+=readSection(p)+JA_TEN_THOUSAND),h>0&&(g+=readSection(h)),g}function digitByDigit(e){return e.split(``).map(function(e){return e>=`0`&&e<=`9`?JA_DIGITS[e.charCodeAt(0)-48]:e}).join(``)}function expandJapaneseText(e){return e=e.replace(/(\d{4})年/g,function(e,f){return numberToWords(parseInt(f,10))+`ねん`}),e=e.replace(/[¥¥]\s*(\d+(?:\.\d+)?)/g,function(e,f){var p=parseFloat(f),m=Math.floor(p);return numberToWords(m)+`えん`}),e=e.replace(/\$\s*(\d+(?:\.\d+)?)/g,function(e,f){var p=parseFloat(f),m=Math.floor(p);return numberToWords(m)+`どる`}),e=e.replace(/(\d+(?:\.\d+)?)%/g,function(e,f){var p=f.indexOf(`.`);return p===-1?numberToWords(parseInt(f,10))+`ぱーせんと`:numberToWords(parseInt(f.slice(0,p),10))+`てん`+digitByDigit(f.slice(p+1))+`ぱーせんと`}),e=e.replace(/(\d+)\.(\d+)/g,function(e,f,p){return numberToWords(parseInt(f,10))+`てん`+digitByDigit(p)}),e=e.replace(/\d+/g,function(e){return numberToWords(parseInt(e,10))}),e}var KANJI_READINGS=resolveJson(kanjiDict),KANJI_WORDS=resolveJson(kanjiWords),KANJI_WORD_KEYS=Object.keys(KANJI_WORDS).sort(function(e,f){return f.length-e.length}),KANJI_RE=/[一-龥㐀-䶿豈-]/,HIRA_RE=/[ぁ-ゟ]/,KANA_DIGRAPH={きゃ:`kya`,きゅ:`kyu`,きょ:`kyo`,ぎゃ:`gya`,ぎゅ:`gyu`,ぎょ:`gyo`,しゃ:`sha`,しゅ:`shu`,しょ:`sho`,じゃ:`ja`,じゅ:`ju`,じょ:`jo`,ちゃ:`cha`,ちゅ:`chu`,ちょ:`cho`,ぢゃ:`ja`,ぢゅ:`ju`,ぢょ:`jo`,にゃ:`nya`,にゅ:`nyu`,にょ:`nyo`,ひゃ:`hya`,ひゅ:`hyu`,ひょ:`hyo`,びゃ:`bya`,びゅ:`byu`,びょ:`byo`,ぴゃ:`pya`,ぴゅ:`pyu`,ぴょ:`pyo`,みゃ:`mya`,みゅ:`myu`,みょ:`myo`,りゃ:`rya`,りゅ:`ryu`,りょ:`ryo`,キャ:`kya`,キュ:`kyu`,キョ:`kyo`,ギャ:`gya`,ギュ:`gyu`,ギョ:`gyo`,シャ:`sha`,シュ:`shu`,ショ:`sho`,ジャ:`ja`,ジュ:`ju`,ジョ:`jo`,チャ:`cha`,チュ:`chu`,チョ:`cho`,ニャ:`nya`,ニュ:`nyu`,ニョ:`nyo`,ヒャ:`hya`,ヒュ:`hyu`,ヒョ:`hyo`,ビャ:`bya`,ビュ:`byu`,ビョ:`byo`,ピャ:`pya`,ピュ:`pyu`,ピョ:`pyo`,ミャ:`mya`,ミュ:`myu`,ミョ:`myo`,リャ:`rya`,リュ:`ryu`,リョ:`ryo`},KANA_SINGLE={あ:`a`,い:`i`,う:`u`,え:`e`,お:`o`,ア:`a`,イ:`i`,ウ:`u`,エ:`e`,オ:`o`,か:`ka`,き:`ki`,く:`ku`,け:`ke`,こ:`ko`,カ:`ka`,キ:`ki`,ク:`ku`,ケ:`ke`,コ:`ko`,が:`ga`,ぎ:`gi`,ぐ:`gu`,げ:`ge`,ご:`go`,ガ:`ga`,ギ:`gi`,グ:`gu`,ゲ:`ge`,ゴ:`go`,さ:`sa`,し:`shi`,す:`su`,せ:`se`,そ:`so`,サ:`sa`,シ:`shi`,ス:`su`,セ:`se`,ソ:`so`,ざ:`za`,じ:`ji`,ず:`zu`,ぜ:`ze`,ぞ:`zo`,ザ:`za`,ジ:`ji`,ズ:`zu`,ゼ:`ze`,ゾ:`zo`,た:`ta`,ち:`chi`,つ:`tsu`,て:`te`,と:`to`,タ:`ta`,チ:`chi`,ツ:`tsu`,テ:`te`,ト:`to`,だ:`da`,ぢ:`ji`,づ:`zu`,で:`de`,ど:`do`,ダ:`da`,ヂ:`ji`,ヅ:`zu`,デ:`de`,ド:`do`,な:`na`,に:`ni`,ぬ:`nu`,ね:`ne`,の:`no`,ナ:`na`,ニ:`ni`,ヌ:`nu`,ネ:`ne`,ノ:`no`,は:`ha`,ひ:`hi`,ふ:`fu`,へ:`he`,ほ:`ho`,ハ:`ha`,ヒ:`hi`,フ:`fu`,ヘ:`he`,ホ:`ho`,ば:`ba`,び:`bi`,ぶ:`bu`,べ:`be`,ぼ:`bo`,バ:`ba`,ビ:`bi`,ブ:`bu`,ベ:`be`,ボ:`bo`,ぱ:`pa`,ぴ:`pi`,ぷ:`pu`,ぺ:`pe`,ぽ:`po`,パ:`pa`,ピ:`pi`,プ:`pu`,ペ:`pe`,ポ:`po`,ま:`ma`,み:`mi`,む:`mu`,め:`me`,も:`mo`,マ:`ma`,ミ:`mi`,ム:`mu`,メ:`me`,モ:`mo`,や:`ya`,ゆ:`yu`,よ:`yo`,ヤ:`ya`,ユ:`yu`,ヨ:`yo`,ら:`ra`,り:`ri`,る:`ru`,れ:`re`,ろ:`ro`,ラ:`ra`,リ:`ri`,ル:`ru`,レ:`re`,ロ:`ro`,わ:`wa`,ゐ:`wi`,ゑ:`we`,を:`o`,ワ:`wa`,ヰ:`wi`,ヱ:`we`,ヲ:`o`,ん:`n`,ン:`n`,ぁ:`a`,ぃ:`i`,ぅ:`u`,ぇ:`e`,ぉ:`o`,ァ:`a`,ィ:`i`,ゥ:`u`,ェ:`e`,ォ:`o`,ゃ:`ya`,ゅ:`yu`,ょ:`yo`,ャ:`ya`,ュ:`yu`,ョ:`yo`};function kanaToRomaji(e){for(var f,p,m,h=``,g=0;g<e.length;g++){var _=e[g];if(_===`っ`||_===`ッ`){var v=g+2<e.length+1?e.slice(g+1,g+3):``,y=(f=e[g+1])??``,b=(m=(p=KANA_DIGRAPH[v])??KANA_SINGLE[y])??``;b&&/^[bcdfghjklmpqrstvwxyz]/.test(b)&&(h+=b[0]);continue}if(_===`ー`){var x=h[h.length-1];x&&/[aeiou]/.test(x)&&(h+=x);continue}var S=e.slice(g,g+2);if(KANA_DIGRAPH[S]){h+=KANA_DIGRAPH[S],g++;continue}if(KANA_SINGLE[_]){h+=KANA_SINGLE[_];continue}h+=_}return h}var JAPANESE_SYLLABLE_MAP={a:`a`,i:`i`,u:`ɯ`,e:`e`,o:`o`,ka:`ka`,ki:`ki`,ku:`kɯ`,ke:`ke`,ko:`ko`,ga:`ɡa`,gi:`ɡi`,gu:`ɡɯ`,ge:`ɡe`,go:`ɡo`,sa:`sa`,shi:`ɕi`,su:`sɯ`,se:`se`,so:`so`,za:`za`,ji:`dʑi`,zu:`zɯ`,ze:`ze`,zo:`zo`,ta:`ta`,chi:`tɕi`,tsu:`tsɯ`,te:`te`,to:`to`,da:`da`,de:`de`,do:`do`,na:`na`,ni:`ni`,nu:`nɯ`,ne:`nɛ`,no:`no`,ha:`ha`,hi:`çi`,fu:`ɸɯ`,he:`hɛ`,ho:`ho`,ba:`ba`,bi:`bi`,bu:`bɯ`,be:`be`,bo:`bo`,pa:`pa`,pi:`pi`,pu:`pɯ`,pe:`pe`,po:`po`,ma:`ma`,mi:`mi`,mu:`mɯ`,me:`mɛ`,mo:`mo`,ya:`ja`,yu:`jɯ`,yo:`jo`,ra:`ɾa`,ri:`ɾi`,ru:`ɾɯ`,wa:`wa`,wo:`o`,n:`n`,kya:`kja`,kyu:`kjɯ`,kyo:`kjo`,gya:`ɡja`,gyu:`ɡjɯ`,gyo:`ɡjo`,sha:`ɕa`,shu:`ɕɯ`,sho:`ɕo`,ja:`dʑa`,ju:`dʑɯ`,jo:`dʑo`,cha:`tɕa`,chu:`tɕɯ`,cho:`tɕo`,nya:`ɲa`,nyu:`ɲɯ`,nyo:`ɲo`,hya:`ça`,hyu:`çɯ`,hyo:`ço`,rya:`ɾʲa`,ryu:`ɾʲɯ`,ryo:`ɾʲo`},JAPANESE_LONG_VOWEL_RULES={aa:`aː`,ii:`iː`,uu:`uː`,ee:`eː`,oo:`oː`,ou:`oː`},JapaneseG2P=function(){function e(){this.id=`ja-g2p`,this.name=`Japanese G2P Processor`,this.supportedLanguages=[`ja`]}return e.prototype.preProcess=function(e){var f,p,m,h;e=expandJapaneseText(e),e=e.replace(/([一-龥ァ-ヶa-zA-Z0-9にでとやも])は/g,`$1わ`);for(var g=0,_=KANJI_WORD_KEYS;g<_.length;g++){var v=_[g];e.includes(v)&&(e=e.split(v).join(KANJI_WORDS[v]))}for(var y=``,b=0;b<e.length;b++){var x=e[b];if(!KANJI_RE.test(x)){y+=x;continue}var S=KANJI_READINGS[x];if(!S){y+=x;continue}var C=b+1<e.length&&HIRA_RE.test(e[b+1]);y+=C?(p=(f=S.k)??S.o)??x:(h=(m=S.o)??S.k)??x}return kanaToRomaji(y)},e.prototype.predict=function(e,f,p){return this.processJapanese(e)},e.prototype.addPronunciation=function(e,f){},e.prototype.processJapanese=function(e){e=e.toLowerCase(),e===`ha`?e=`wa`:e===`he`?e=`e`:e===`wo`?e=`o`:e===`konnichiha`?e=`konnichiwa`:e===`konbanha`&&(e=`konbanwa`),e=e.replace(/([bcdfghjklmpqrstvwxyz])\1/g,`っ$1`),e=e.replace(/n(?=[bcdfghjklmpqrstvwxyz])/g,`ん`);for(var f=0,p=Object.entries(JAPANESE_LONG_VOWEL_RULES);f<p.length;f++){var m=p[f],h=m[0],g=m[1];e=e.replace(new RegExp(h,`g`),g)}for(var _=``,v=0;v<e.length;){for(var y=!1,b=3;b>0;b--)if(v+b<=e.length){var x=e.substring(v,v+b);if(JAPANESE_SYLLABLE_MAP[x]){_+=JAPANESE_SYLLABLE_MAP[x],v+=b,y=!0;break}}y||(e[v]===`っ`?_+=`っ`:e[v]===`ん`?_+=`n`:_+=e[v],v++)}return _.replace(/っ(.)/g,`$1$1`).replace(/っ/g,``)},e}();export{JapaneseG2P as default};