diff --git a/src/scenes/EndScene.tsx b/src/scenes/EndScene.tsx index 760ccf8..3c92e82 100644 --- a/src/scenes/EndScene.tsx +++ b/src/scenes/EndScene.tsx @@ -11,6 +11,7 @@ import LainSpeak from "../components/LainSpeak"; import EndSphere from "../components/EndScene/EndSphere"; import EndCylinder from "../components/EndScene/EndCylinder"; import sleep from "../utils/sleep"; +import getVoiceFilenames from "../utils/getVoiceFilenames"; const EndScene = () => { const mainCylinderRef = useRef(); @@ -48,7 +49,7 @@ const EndScene = () => { const playedMediaCountRef = useRef(0); const playerName = useStore((state) => state.playerName); - const playerNameVoices = useMemo(() => playerName.split(""), [playerName]); + const playerNameVoices = useMemo(() => getVoiceFilenames(playerName), [playerName]); const setInputCooldown = useStore((state) => state.setInputCooldown); diff --git a/src/utils/getVoiceFilenames.ts b/src/utils/getVoiceFilenames.ts new file mode 100644 index 0000000..113dcb7 --- /dev/null +++ b/src/utils/getVoiceFilenames.ts @@ -0,0 +1,824 @@ +const translationTable: any = { + BYA: "ビャ", + BYO: "ビョ", + BYU: "ビュ", + GYA: "ギャ", + GYO: "ギョ", + GYU: "ギュ", + HYA: "ヒャ", + HYO: "ヒョ", + HYU: "ヒュ", + KYA: "キャ", + KYO: "キョ", + KYU: "キュ", + MYA: "ミャ", + MYO: "ミョ", + MYU: "ミュ", + NYA: "ニャ", + NYO: "ニョ", + NYU: "ニュ", + PYA: "ピャ", + PYO: "ピョ", + PYU: "ピュ", + RYA: "リャ", + RYO: "リョ", + RYU: "リュ", + SYA: "シャ", + SYO: "ショ", + SYU: "シュ", + TYA: "チャ", + TYO: "チョ", + TYU: "チュ", + JYA: "ジャ", + JYO: "ジョ", + JYU: "ジュ", + DYA: "ヂャ", + DYO: "ヂョ", + DYU: "ヂュ", + FA: "ファ", + FE: "フェ", + FI: "フィ", + FO: "フォ", + FU: "フゥ", + A: "ア", + BA: "バ", + BE: "ベ", + BI: "ビ", + BO: "ボ", + BU: "ブ", + DA: "ダ", + DE: "デ", + DI: "ヂ", + DO: "ド", + DU: "ヅ", + E: "エ", + GA: "ガ", + GE: "ゲ", + GI: "ギ", + GO: "ゴ", + GU: "グ", + HA: "ハ", + HE: "ヘ", + HI: "ヒ", + HO: "ホ", + HU: "フ", + I: "イ", + KA: "カ", + KE: "ケ", + KI: "キ", + KO: "コ", + KU: "ク", + MA: "マ", + ME: "メ", + MI: "ミ", + MO: "モ", + MU: "ム", + NA: "ナ", + NE: "ネ", + NI: "ニ", + NN: "ンン", + N: "ン", + NO: "ノ", + NU: "ヌ", + O: "オ", + PA: "パ", + PE: "ペ", + PI: "ピ", + PO: "ポ", + PU: "プ", + RA: "ラ", + RE: "レ", + RI: "リ", + RO: "ロ", + RU: "ル", + SA: "サ", + SE: "セ", + SI: "シ", + SO: "ソ", + SU: "ス", + TA: "タ", + TE: "テ", + TI: "チ", + TO: "ト", + TU: "ツ", + U: "ウ", + WA: "ワ", + YA: "ヤ", + YO: "ヨ", + YU: "ユ", + ZA: "ザ", + ZE: "ゼ", + ZI: "ジ", + ZO: "ゾ", + ZU: "ズ", + "-": "ー", +}; + +const FILE_LIST = [ + "A", + "#", + "A_CAVE", + "A_END", + "BA", + "BE", + "BI", + "BO", + "BU", + "BYA", + "BYO", + "BYU", + "DA", + "DE", + "DI", + "DO", + "DU", + "E", + "E_CAVE", + "E_END", + "FA", + "FE", + "FI", + "FO", + "FU", + "GA", + "GE", + "GI", + "GO", + "GU", + "GYA", + "GYO", + "GYU", + "HA", + "HE", + "HI", + "HO", + "HU", + "HYA", + "HYO", + "HYU", + "I", + "I_CAVE", + "I_END", + "KA", + "KE", + "KI", + "KO", + "KU", + "KYA", + "KYO", + "KYU", + "MA", + "ME", + "MI", + "MO", + "MU", + "MYA", + "MYO", + "MYU", + "NA", + "NE", + "NI", + "NN", + "NO", + "NU", + "NYA", + "NYO", + "NYU", + "N_CAVE", + "N_END", + "O", + "O_CAVE", + "O_END", + "PA", + "PE", + "PI", + "PO", + "PU", + "PYA", + "PYO", + "PYU", + "RA", + "RE", + "RI", + "RO", + "RU", + "RYA", + "RYO", + "RYU", + "SA", + "SE", + "SI", + "SO", + "SU", + "SYA", + "SYO", + "SYU", + "TA", + "TE", + "TI", + "TO", + "TU", + "TYA", + "TYO", + "TYU", + "U", + "U_CAVE", + "U_END", + "WA", + "YA", + "YO", + "YU", + "ZA", + "ZE", + "ZI", + "ZO", + "ZU", + "ZYA", + "ZYO", + "ZYU", + "A_A", + "A_BA", + "A_BE", + "A_BI", + "A_BO", + "A_BU", + "A_BYA", + "A_BYO", + "A_BYU", + "A_DA", + "A_DE", + "A_DI", + "A_DO", + "A_DU", + "A_DYA", + "A_DYO", + "A_DYU", + "A_E", + "A_FA", + "A_FE", + "A_FI", + "A_FO", + "A_FU", + "A_GA", + "A_GE", + "A_GI", + "A_GO", + "A_GU", + "A_GYA", + "A_GYO", + "A_GYU", + "A_HA", + "A_HE", + "A_HI", + "A_HO", + "A_HU", + "A_HYA", + "A_HYO", + "A_HYU", + "A_I", + "A_JYA", + "A_JYO", + "A_JYU", + "A_MA", + "A_ME", + "A_MI", + "A_MO", + "A_MU", + "A_MYA", + "A_MYO", + "A_MYU", + "A_NA", + "A_NE", + "A_NI", + "A_NO", + "A_NU", + "A_NYA", + "A_NYO", + "A_NYU", + "A_O", + "A_RA", + "A_RE", + "A_RI", + "A_RO", + "A_RU", + "A_RYA", + "A_RYO", + "A_RYU", + "A_SA", + "A_SE", + "A_SI", + "A_SO", + "A_SU", + "A_SYA", + "A_SYO", + "A_SYU", + "A_U", + "A_WA", + "A_YA", + "A_YO", + "A_YU", + "A_ZA", + "A_ZE", + "A_ZI", + "A_ZO", + "A_ZU", + "E_A", + "E_BA", + "E_BE", + "E_BI", + "E_BO", + "E_BU", + "E_BYA", + "E_BYO", + "E_BYU", + "E_DA", + "E_DE", + "E_DI", + "E_DO", + "E_DU", + "E_DYA", + "E_DYO", + "E_DYU", + "E_E", + "E_FA", + "E_FE", + "E_FI", + "E_FO", + "E_FU", + "E_GA", + "E_GE", + "E_GI", + "E_GO", + "E_GU", + "E_GYA", + "E_GYO", + "E_GYU", + "E_HA", + "E_HE", + "E_HI", + "E_HO", + "E_HU", + "E_HYA", + "E_HYO", + "E_HYU", + "E_I", + "E_JYA", + "E_JYO", + "E_JYU", + "E_MA", + "E_ME", + "E_MI", + "E_MO", + "E_MU", + "E_MYA", + "E_MYO", + "E_MYU", + "E_NA", + "E_NE", + "E_NI", + "E_NO", + "E_NU", + "E_NYA", + "E_NYO", + "E_NYU", + "E_O", + "E_RA", + "E_RE", + "E_RI", + "E_RO", + "E_RU", + "E_RYA", + "E_RYO", + "E_RYU", + "E_SA", + "E_SE", + "E_SI", + "E_SO", + "E_SU", + "E_SYA", + "E_SYO", + "E_SYU", + "E_U", + "E_WA", + "E_YA", + "E_YO", + "E_YU", + "E_ZA", + "E_ZE", + "E_ZI", + "E_ZO", + "E_ZU", + "I_A", + "I_BA", + "I_BE", + "I_BI", + "I_BO", + "I_BU", + "I_BYA", + "I_BYO", + "I_BYU", + "I_DA", + "I_DE", + "I_DI", + "I_DO", + "I_DU", + "I_DYA", + "I_DYO", + "I_DYU", + "I_E", + "I_FA", + "I_FE", + "I_FI", + "I_FO", + "I_FU", + "I_GA", + "I_GE", + "I_GI", + "I_GO", + "I_GU", + "I_GYA", + "I_GYO", + "I_GYU", + "I_HA", + "I_HE", + "I_HI", + "I_HO", + "I_HU", + "I_HYA", + "I_HYO", + "I_HYU", + "I_I", + "I_JYA", + "I_JYO", + "I_JYU", + "I_MA", + "I_ME", + "I_MI", + "I_MO", + "I_MU", + "I_MYA", + "I_MYO", + "I_MYU", + "I_NA", + "I_NE", + "I_NI", + "I_NO", + "I_NU", + "I_NYA", + "I_NYO", + "I_NYU", + "I_O", + "I_RA", + "I_RE", + "I_RI", + "I_RO", + "I_RU", + "I_RYA", + "I_RYO", + "I_RYU", + "I_SA", + "I_SE", + "I_SI", + "I_SO", + "I_SU", + "I_SYA", + "I_SYO", + "I_SYU", + "I_U", + "I_WA", + "I_YA", + "I_YO", + "I_YU", + "I_ZA", + "I_ZE", + "I_ZI", + "I_ZO", + "I_ZU", + "N_A", + "N_BA", + "N_BE", + "N_BI", + "N_BO", + "N_BU", + "N_BYA", + "N_BYO", + "N_BYU", + "N_DA", + "N_DE", + "N_DI", + "N_DO", + "N_DU", + "N_DYA", + "N_DYO", + "N_DYU", + "N_E", + "N_FA", + "N_FE", + "N_FI", + "N_FO", + "N_FU", + "N_GA", + "N_GE", + "N_GI", + "N_GO", + "N_GU", + "N_GYA", + "N_GYO", + "N_GYU", + "N_HA", + "N_HE", + "N_HI", + "N_HO", + "N_HU", + "N_HYA", + "N_HYO", + "N_HYU", + "N_I", + "N_JYA", + "N_JYO", + "N_JYU", + "N_MA", + "N_ME", + "N_MI", + "N_MO", + "N_MU", + "N_MYA", + "N_MYO", + "N_MYU", + "N_NA", + "N_NE", + "N_NI", + "N_NO", + "N_NU", + "N_NYA", + "N_NYO", + "N_NYU", + "N_O", + "N_RA", + "N_RE", + "N_RI", + "N_RO", + "N_RU", + "N_RYA", + "N_RYO", + "N_RYU", + "N_SA", + "N_SE", + "N_SI", + "N_SO", + "N_SU", + "N_SYA", + "N_SYO", + "N_SYU", + "N_U", + "N_WA", + "N_YA", + "N_YO", + "N_YU", + "N_ZA", + "N_ZE", + "N_ZI", + "N_ZO", + "N_ZU", + "O_A", + "O_BA", + "O_BE", + "O_BI", + "O_BO", + "O_BU", + "O_BYA", + "O_BYO", + "O_BYU", + "O_DA", + "O_DE", + "O_DI", + "O_DO", + "O_DU", + "O_DYA", + "O_DYO", + "O_DYU", + "O_E", + "O_FA", + "O_FE", + "O_FI", + "O_FO", + "O_FU", + "O_GA", + "O_GE", + "O_GI", + "O_GO", + "O_GU", + "O_GYA", + "O_GYO", + "O_GYU", + "O_HA", + "O_HE", + "O_HI", + "O_HO", + "O_HU", + "O_HYA", + "O_HYO", + "O_HYU", + "O_I", + "O_JYA", + "O_JYO", + "O_JYU", + "O_KO", + "O_MA", + "O_ME", + "O_MI", + "O_MO", + "O_MU", + "O_MYA", + "O_MYO", + "O_MYU", + "O_NA", + "O_NE", + "O_NI", + "O_NO", + "O_NU", + "O_NYA", + "O_NYO", + "O_NYU", + "O_O", + "O_RA", + "O_RE", + "O_RI", + "O_RO", + "O_RU", + "O_RYA", + "O_RYO", + "O_RYU", + "O_SA", + "O_SE", + "O_SI", + "O_SO", + "O_SU", + "O_SYA", + "O_SYO", + "O_SYU", + "O_U", + "O_WA", + "O_YA", + "O_YO", + "O_YU", + "O_ZA", + "O_ZE", + "O_ZI", + "O_ZO", + "O_ZU", + "U_A", + "U_BA", + "U_BE", + "U_BI", + "U_BO", + "U_BU", + "U_BYA", + "U_BYO", + "U_BYU", + "U_DA", + "U_DE", + "U_DI", + "U_DO", + "U_DU", + "U_DYA", + "U_DYO", + "U_DYU", + "U_E", + "U_FA", + "U_FE", + "U_FI", + "U_FO", + "U_FU", + "U_GA", + "U_GE", + "U_GI", + "U_GO", + "U_GU", + "U_GYA", + "U_GYO", + "U_GYU", + "U_HA", + "U_HE", + "U_HI", + "U_HO", + "U_HU", + "U_HYA", + "U_HYO", + "U_HYU", + "U_I", + "U_JYA", + "U_JYO", + "U_JYU", + "U_KO", + "U_MA", + "U_ME", + "U_MI", + "U_MO", + "U_MU", + "U_MYA", + "U_MYO", + "U_MYU", + "U_NA", + "U_NE", + "U_NI", + "U_NO", + "U_NU", + "U_NYA", + "U_NYO", + "U_NYU", + "U_O", + "U_RA", + "U_RE", + "U_RI", + "U_RO", + "U_RU", + "U_RYA", + "U_RYO", + "U_RYU", + "U_SA", + "U_SE", + "U_SI", + "U_SO", + "U_SU", + "U_SYA", + "U_SYO", + "U_SYU", + "U_U", + "U_WA", + "U_YA", + "U_YO", + "U_YU", + "U_ZA", + "U_ZE", + "U_ZI", + "U_ZO", + "U_ZU", +]; + +const VOWELS = "AIUEO#-"; + +const getVoiceFilenames = (name: String) => { + // convert name from katakana to romaji + Object.keys(translationTable).forEach((translated: string) => { + name = name.replaceAll(translationTable[translated], translated); + }); + + let currentVowel = ""; + let filesToPlay = []; + let currentSyllable = ""; + + for (let i = 0; i < name.length; ) { + let filename = ""; + // current character is a vowel + if (VOWELS.includes(name[i])) { + // long vowel + if (name[i] === "-") { + filename = `${currentVowel}_${currentVowel}`; + } + // two vowels in a row + else if (currentVowel !== "") { + filename = `${currentVowel}_${name[i]}`; + // if double vowel sound does not exist fall back to single vowel + if (!FILE_LIST.includes(filename)) filename = `${name[i]}`; + } + // single vowel + else filename = `${name[i]}`; + currentVowel = name[i]; + i += 1; + } else { + // 2 character long syllable by default + currentSyllable = name.slice(i, i + 2); + + if (currentSyllable[1] === "Y" || currentSyllable[1] === "H") { + // 3 character long syllable + currentSyllable = name.slice(i, i + 3); + i += 1; + } + + i += 2; + + if (currentVowel === "") filename = `${currentSyllable}`; + else { + filename = `${currentVowel}_${currentSyllable}`; + + if (!FILE_LIST.includes(filename)) filename = `${currentSyllable}`; + } + + if (currentSyllable[1] === "Y" || currentSyllable[1] === "H") + currentVowel = currentSyllable[2]; + else currentVowel = currentSyllable[1]; + } + + // convert filename to katakana + filesToPlay.push( + filename + .split("_") + .map((c) => translationTable[c]) + .join("_") + ); + } + return filesToPlay; +}; + +export default getVoiceFilenames;