UNPKG

phonemize

Version:

Fast phonemizer with rule-based G2P prediction. Pure JavaScript implementation.

2 lines (1 loc) 7.66 kB
"use strict";var kanjiDict=require(`./ja/kanji.json`),kanjiWords=require(`./ja/words.json`),utils=require(`./utils-Dq_eIfdp.cjs`);function _interopNamespaceDefault(e){var h=Object.create(null);return e&&Object.keys(e).forEach(function(g){if(g!==`default`){var _=Object.getOwnPropertyDescriptor(e,g);Object.defineProperty(h,g,_.get?_:{enumerable:!0,get:function(){return e[g]}})}}),h.default=e,Object.freeze(h)}var kanjiDict__namespace=_interopNamespaceDefault(kanjiDict),kanjiWords__namespace=_interopNamespaceDefault(kanjiWords),JA_DIGITS=[`ぜろ`,`いち`,`に`,`さん`,`よん`,`ご`,`ろく`,`なな`,`はち`,`きゅう`],JA_TEN=`じゅう`,JA_HUNDRED=`ひゃく`,JA_THOUSAND=`せん`,JA_TEN_THOUSAND=`まん`,JA_HUNDRED_MILLION=`おく`;function readSection(e){if(e===0)return``;var h=``,g=Math.floor(e/1e3),_=Math.floor(e%1e3/100),v=Math.floor(e%100/10),y=e%10;return g>0&&(h+=(g===1?``:JA_DIGITS[g])+JA_THOUSAND),_>0&&(h+=(_===1?``:JA_DIGITS[_])+JA_HUNDRED),v>0&&(h+=(v===1?``:JA_DIGITS[v])+JA_TEN),y>0&&(h+=JA_DIGITS[y]),h}function numberToWords(e){if(e===0)return JA_DIGITS[0];if(e<0)return`マイナス`+numberToWords(-e);var h=Math.floor(e/1e8),g=Math.floor(e%1e8/1e4),_=e%1e4,v=``;return h>0&&(v+=readSection(h)+JA_HUNDRED_MILLION),g>0&&(v+=readSection(g)+JA_TEN_THOUSAND),_>0&&(v+=readSection(_)),v}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,h){return numberToWords(parseInt(h,10))+`ねん`}),e=e.replace(/[¥¥]\s*(\d+(?:\.\d+)?)/g,function(e,h){var g=parseFloat(h),_=Math.floor(g);return numberToWords(_)+`えん`}),e=e.replace(/\$\s*(\d+(?:\.\d+)?)/g,function(e,h){var g=parseFloat(h),_=Math.floor(g);return numberToWords(_)+`どる`}),e=e.replace(/(\d+(?:\.\d+)?)%/g,function(e,h){var g=h.indexOf(`.`);return g===-1?numberToWords(parseInt(h,10))+`ぱーせんと`:numberToWords(parseInt(h.slice(0,g),10))+`てん`+digitByDigit(h.slice(g+1))+`ぱーせんと`}),e=e.replace(/(\d+)\.(\d+)/g,function(e,h,g){return numberToWords(parseInt(h,10))+`てん`+digitByDigit(g)}),e=e.replace(/\d+/g,function(e){return numberToWords(parseInt(e,10))}),e}var KANJI_READINGS=utils.resolveJson(kanjiDict__namespace),KANJI_WORDS=utils.resolveJson(kanjiWords__namespace),KANJI_WORD_KEYS=Object.keys(KANJI_WORDS).sort(function(e,h){return h.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 h,g,_,v=``,y=0;y<e.length;y++){var b=e[y];if(b===`っ`||b===`ッ`){var x=y+2<e.length+1?e.slice(y+1,y+3):``,S=(h=e[y+1])??``,C=(_=(g=KANA_DIGRAPH[x])??KANA_SINGLE[S])??``;C&&/^[bcdfghjklmpqrstvwxyz]/.test(C)&&(v+=C[0]);continue}if(b===`ー`){var w=v[v.length-1];w&&/[aeiou]/.test(w)&&(v+=w);continue}var T=e.slice(y,y+2);if(KANA_DIGRAPH[T]){v+=KANA_DIGRAPH[T],y++;continue}if(KANA_SINGLE[b]){v+=KANA_SINGLE[b];continue}v+=b}return v}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 h,g,_,v;e=expandJapaneseText(e),e=e.replace(/([一-龥ァ-ヶa-zA-Z0-9にでとやも])は/g,`$1わ`);for(var y=0,b=KANJI_WORD_KEYS;y<b.length;y++){var x=b[y];e.includes(x)&&(e=e.split(x).join(KANJI_WORDS[x]))}for(var S=``,C=0;C<e.length;C++){var w=e[C];if(!KANJI_RE.test(w)){S+=w;continue}var T=KANJI_READINGS[w];if(!T){S+=w;continue}var E=C+1<e.length&&HIRA_RE.test(e[C+1]);S+=E?(g=(h=T.k)??T.o)??w:(v=(_=T.o)??T.k)??w}return kanaToRomaji(S)},e.prototype.predict=function(e,h,g){return this.processJapanese(e)},e.prototype.addPronunciation=function(e,h){},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 h=0,g=Object.entries(JAPANESE_LONG_VOWEL_RULES);h<g.length;h++){var _=g[h],v=_[0],y=_[1];e=e.replace(new RegExp(v,`g`),y)}for(var b=``,x=0;x<e.length;){for(var S=!1,C=3;C>0;C--)if(x+C<=e.length){var w=e.substring(x,x+C);if(JAPANESE_SYLLABLE_MAP[w]){b+=JAPANESE_SYLLABLE_MAP[w],x+=C,S=!0;break}}S||(e[x]===`っ`?b+=`っ`:e[x]===`ん`?b+=`n`:b+=e[x],x++)}return b.replace(/っ(.)/g,`$1$1`).replace(/っ/g,``)},e}();module.exports=JapaneseG2P;