├── readme
├── 1.png
├── 2.png
├── 3.png
├── 4.png
├── 5.png
├── 6.png
├── 7.png
├── 8.png
├── 9.png
├── 10.png
├── 11.png
├── 12.png
├── 13.png
├── token.png
└── cyberchat.png
├── ChatWithGPT
└── game
│ ├── gui
│ ├── nvl.png
│ ├── skip.png
│ ├── bar
│ │ ├── top.png
│ │ ├── left.png
│ │ ├── right.png
│ │ └── bottom.png
│ ├── frame.png
│ ├── namebox.png
│ ├── notify.png
│ ├── textbox.png
│ ├── game_menu.png
│ ├── main_menu.png
│ ├── phone
│ │ ├── nvl.png
│ │ ├── bar
│ │ │ ├── left.png
│ │ │ ├── top.png
│ │ │ ├── bottom.png
│ │ │ └── right.png
│ │ ├── textbox.png
│ │ ├── overlay
│ │ │ ├── game_menu.png
│ │ │ └── main_menu.png
│ │ ├── button
│ │ │ ├── check_foreground.png
│ │ │ ├── hover_background.png
│ │ │ ├── idle_background.png
│ │ │ ├── radio_foreground.png
│ │ │ ├── slot_hover_background.png
│ │ │ ├── slot_idle_background.png
│ │ │ ├── choice_hover_background.png
│ │ │ ├── choice_idle_background.png
│ │ │ ├── check_selected_foreground.png
│ │ │ └── radio_selected_foreground.png
│ │ ├── slider
│ │ │ ├── horizontal_idle_bar.png
│ │ │ ├── vertical_hover_bar.png
│ │ │ ├── vertical_idle_bar.png
│ │ │ ├── vertical_idle_thumb.png
│ │ │ ├── horizontal_hover_bar.png
│ │ │ ├── horizontal_idle_thumb.png
│ │ │ ├── vertical_hover_thumb.png
│ │ │ └── horizontal_hover_thumb.png
│ │ └── scrollbar
│ │ │ ├── vertical_hover_bar.png
│ │ │ ├── vertical_idle_bar.png
│ │ │ ├── horizontal_hover_bar.png
│ │ │ ├── horizontal_idle_bar.png
│ │ │ ├── horizontal_idle_thumb.png
│ │ │ ├── vertical_hover_thumb.png
│ │ │ ├── vertical_idle_thumb.png
│ │ │ └── horizontal_hover_thumb.png
│ ├── window_icon.png
│ ├── overlay
│ │ ├── confirm.png
│ │ ├── game_menu.png
│ │ └── main_menu.png
│ ├── button
│ │ ├── idle_background.png
│ │ ├── check_foreground.png
│ │ ├── hover_background.png
│ │ ├── radio_foreground.png
│ │ ├── slot_idle_background.png
│ │ ├── choice_idle_background.png
│ │ ├── quick_hover_background.png
│ │ ├── quick_idle_background.png
│ │ ├── slot_hover_background.png
│ │ ├── check_selected_foreground.png
│ │ ├── choice_hover_background.png
│ │ └── radio_selected_foreground.png
│ ├── slider
│ │ ├── vertical_idle_bar.png
│ │ ├── horizontal_hover_bar.png
│ │ ├── horizontal_idle_bar.png
│ │ ├── vertical_hover_bar.png
│ │ ├── vertical_hover_thumb.png
│ │ ├── vertical_idle_thumb.png
│ │ ├── horizontal_hover_thumb.png
│ │ └── horizontal_idle_thumb.png
│ └── scrollbar
│ │ ├── vertical_idle_bar.png
│ │ ├── horizontal_idle_bar.png
│ │ ├── vertical_hover_bar.png
│ │ ├── vertical_idle_thumb.png
│ │ ├── horizontal_hover_bar.png
│ │ ├── horizontal_hover_thumb.png
│ │ ├── horizontal_idle_thumb.png
│ │ └── vertical_hover_thumb.png
│ ├── tl
│ └── None
│ │ └── common.rpymc
│ ├── SourceHanSansLite.ttf
│ ├── Resources
│ └── Hiyori
│ │ ├── Hiyori.moc3
│ │ ├── Hiyori.2048
│ │ ├── texture_00.png
│ │ └── texture_01.png
│ │ ├── Hiyori.pose3.json
│ │ ├── Hiyori.userdata3.json
│ │ ├── hiyori.model3.json
│ │ ├── Hiyori.cdi3.json
│ │ └── motions
│ │ ├── Hiyori_m04.motion3.json
│ │ ├── Hiyori_talking.motion3.json
│ │ ├── Hiyori_m10.motion3.json
│ │ └── Hiyori_m07.motion3.json
│ ├── script.rpy
│ └── options.rpy
├── .vscode
└── settings.json
├── requirements.txt
├── text
├── __init__.py
├── LICENSE
├── thai.py
├── ngu_dialect.py
├── sanskrit.py
├── cantonese.py
├── shanghainese.py
├── japanese.py
├── english.py
├── cleaners.py
├── korean.py
└── mandarin.py
├── LICENSE
├── README-original.md
├── README.md
├── utils.py
├── commons.py
├── mel_processing.py
├── .gitignore
├── hubert_model.py
├── transforms.py
├── server.py
└── attentions.py
/readme/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/1.png
--------------------------------------------------------------------------------
/readme/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/2.png
--------------------------------------------------------------------------------
/readme/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/3.png
--------------------------------------------------------------------------------
/readme/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/4.png
--------------------------------------------------------------------------------
/readme/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/5.png
--------------------------------------------------------------------------------
/readme/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/6.png
--------------------------------------------------------------------------------
/readme/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/7.png
--------------------------------------------------------------------------------
/readme/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/8.png
--------------------------------------------------------------------------------
/readme/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/9.png
--------------------------------------------------------------------------------
/readme/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/10.png
--------------------------------------------------------------------------------
/readme/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/11.png
--------------------------------------------------------------------------------
/readme/12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/12.png
--------------------------------------------------------------------------------
/readme/13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/13.png
--------------------------------------------------------------------------------
/readme/token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/token.png
--------------------------------------------------------------------------------
/readme/cyberchat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/readme/cyberchat.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/nvl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/nvl.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/skip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/skip.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/bar/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/bar/top.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/frame.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/namebox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/namebox.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/notify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/notify.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/textbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/textbox.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/bar/left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/bar/left.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/bar/right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/bar/right.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/game_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/game_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/main_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/main_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/nvl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/nvl.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/bar/bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/bar/bottom.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/window_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/window_icon.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/tl/None/common.rpymc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/tl/None/common.rpymc
--------------------------------------------------------------------------------
/ChatWithGPT/game/SourceHanSansLite.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/SourceHanSansLite.ttf
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/bar/left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/bar/left.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/bar/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/bar/top.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/textbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/textbox.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/overlay/confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/overlay/confirm.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/overlay/game_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/overlay/game_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/overlay/main_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/overlay/main_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/bar/bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/bar/bottom.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/bar/right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/bar/right.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.moc3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/Resources/Hiyori/Hiyori.moc3
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/check_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/check_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/radio_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/radio_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/overlay/game_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/overlay/game_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/overlay/main_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/overlay/main_menu.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/vertical_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/vertical_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/slot_idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/slot_idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/vertical_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/vertical_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/horizontal_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/horizontal_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/horizontal_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/horizontal_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/vertical_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/vertical_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/vertical_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/vertical_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/vertical_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/vertical_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/choice_idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/choice_idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/quick_hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/quick_hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/quick_idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/quick_idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/slot_hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/slot_hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/check_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/check_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/radio_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/radio_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/horizontal_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/horizontal_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/vertical_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/vertical_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/vertical_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/vertical_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/horizontal_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/horizontal_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/slider/horizontal_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/slider/horizontal_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/check_selected_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/check_selected_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/choice_hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/choice_hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/button/radio_selected_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/button/radio_selected_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/horizontal_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/horizontal_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/vertical_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/vertical_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/vertical_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/vertical_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/vertical_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/vertical_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/horizontal_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/horizontal_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/horizontal_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/horizontal_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/horizontal_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/horizontal_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/scrollbar/vertical_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/scrollbar/vertical_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/slot_hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/slot_hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/slot_idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/slot_idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/vertical_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/vertical_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/vertical_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/vertical_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/horizontal_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/horizontal_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/horizontal_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/horizontal_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/vertical_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/vertical_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.2048/texture_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/Resources/Hiyori/Hiyori.2048/texture_00.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.2048/texture_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/Resources/Hiyori/Hiyori.2048/texture_01.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/choice_hover_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/choice_hover_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/choice_idle_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/choice_idle_background.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/horizontal_hover_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/horizontal_hover_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/horizontal_idle_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/horizontal_idle_bar.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/horizontal_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/horizontal_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/vertical_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/vertical_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/vertical_idle_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/vertical_idle_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/slider/horizontal_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/slider/horizontal_hover_thumb.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/check_selected_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/check_selected_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/button/radio_selected_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/button/radio_selected_foreground.png
--------------------------------------------------------------------------------
/ChatWithGPT/game/gui/phone/scrollbar/horizontal_hover_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ouor/ChatWaifu-API/HEAD/ChatWithGPT/game/gui/phone/scrollbar/horizontal_hover_thumb.png
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/*.rpyc": true,
4 | "**/*.rpa": true,
5 | "**/*.rpymc": true,
6 | "**/cache/": true
7 | }
8 | }
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.pose3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Type": "Live2D Pose",
3 | "FadeInTime": 0.5,
4 | "Groups": [
5 | [
6 | {
7 | "Id": "PartArmA",
8 | "Link": []
9 | },
10 | {
11 | "Id": "PartArmB",
12 | "Link": []
13 | }
14 | ]
15 | ]
16 | }
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numba
2 | librosa
3 | numpy
4 | scipy
5 | torch
6 | unidecode
7 | openjtalk>=0.3.0.dev2
8 | jamo
9 | pypinyin
10 | jieba
11 | protobuf
12 | cn2an
13 | inflect
14 | eng_to_ipa
15 | ko_pron
16 | indic_transliteration
17 | num_thai
18 | opencc
19 | vosk
20 | sounddevice
21 | pydub
22 | openai
23 | navertts
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.userdata3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "UserDataCount": 7,
5 | "TotalUserDataSize": 35
6 | },
7 | "UserData": [
8 | {
9 | "Target": "ArtMesh",
10 | "Id": "ArtMesh93",
11 | "Value": "ribon"
12 | },
13 | {
14 | "Target": "ArtMesh",
15 | "Id": "ArtMesh94",
16 | "Value": "ribon"
17 | },
18 | {
19 | "Target": "ArtMesh",
20 | "Id": "ArtMesh95",
21 | "Value": "ribon"
22 | },
23 | {
24 | "Target": "ArtMesh",
25 | "Id": "ArtMesh57",
26 | "Value": "ribon"
27 | },
28 | {
29 | "Target": "ArtMesh",
30 | "Id": "ArtMesh58",
31 | "Value": "ribon"
32 | },
33 | {
34 | "Target": "ArtMesh",
35 | "Id": "ArtMesh59",
36 | "Value": "ribon"
37 | },
38 | {
39 | "Target": "ArtMesh",
40 | "Id": "ArtMesh60",
41 | "Value": "ribon"
42 | }
43 | ]
44 | }
--------------------------------------------------------------------------------
/text/__init__.py:
--------------------------------------------------------------------------------
1 | """ from https://github.com/keithito/tacotron """
2 | from text import cleaners
3 |
4 |
5 | def text_to_sequence(text, symbols, cleaner_names):
6 | '''Converts a string of text to a sequence of IDs corresponding to the symbols in the text.
7 | Args:
8 | text: string to convert to a sequence
9 | cleaner_names: names of the cleaner functions to run the text through
10 | Returns:
11 | List of integers corresponding to the symbols in the text
12 | '''
13 | _symbol_to_id = {s: i for i, s in enumerate(symbols)}
14 |
15 | sequence = []
16 |
17 | clean_text = _clean_text(text, cleaner_names)
18 | for symbol in clean_text:
19 | if symbol not in _symbol_to_id.keys():
20 | continue
21 | symbol_id = _symbol_to_id[symbol]
22 | sequence += [symbol_id]
23 | return sequence
24 |
25 |
26 | def _clean_text(text, cleaner_names):
27 | for name in cleaner_names:
28 | cleaner = getattr(cleaners, name)
29 | if not cleaner:
30 | raise Exception('Unknown cleaner: %s' % name)
31 | text = cleaner(text)
32 | return text
33 |
--------------------------------------------------------------------------------
/text/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Keith Ito
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/text/thai.py:
--------------------------------------------------------------------------------
1 | import re
2 | from num_thai.thainumbers import NumThai
3 |
4 |
5 | num = NumThai()
6 |
7 | # List of (Latin alphabet, Thai) pairs:
8 | _latin_to_thai = [(re.compile('%s' % x[0], re.IGNORECASE), x[1]) for x in [
9 | ('a', 'เอ'),
10 | ('b','บี'),
11 | ('c','ซี'),
12 | ('d','ดี'),
13 | ('e','อี'),
14 | ('f','เอฟ'),
15 | ('g','จี'),
16 | ('h','เอช'),
17 | ('i','ไอ'),
18 | ('j','เจ'),
19 | ('k','เค'),
20 | ('l','แอล'),
21 | ('m','เอ็ม'),
22 | ('n','เอ็น'),
23 | ('o','โอ'),
24 | ('p','พี'),
25 | ('q','คิว'),
26 | ('r','แอร์'),
27 | ('s','เอส'),
28 | ('t','ที'),
29 | ('u','ยู'),
30 | ('v','วี'),
31 | ('w','ดับเบิลยู'),
32 | ('x','เอ็กซ์'),
33 | ('y','วาย'),
34 | ('z','ซี')
35 | ]]
36 |
37 |
38 | def num_to_thai(text):
39 | return re.sub(r'(?:\d+(?:,?\d+)?)+(?:\.\d+(?:,?\d+)?)?', lambda x: ''.join(num.NumberToTextThai(float(x.group(0).replace(',', '')))), text)
40 |
41 | def latin_to_thai(text):
42 | for regex, replacement in _latin_to_thai:
43 | text = re.sub(regex, replacement, text)
44 | return text
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 CjangCjengh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/text/ngu_dialect.py:
--------------------------------------------------------------------------------
1 | import re
2 | import opencc
3 |
4 |
5 | dialects = {'SZ': 'suzhou', 'WX': 'wuxi', 'CZ': 'changzhou', 'HZ': 'hangzhou',
6 | 'SX': 'shaoxing', 'NB': 'ningbo', 'JJ': 'jingjiang', 'YX': 'yixing',
7 | 'JD': 'jiading', 'ZR': 'zhenru', 'PH': 'pinghu', 'TX': 'tongxiang',
8 | 'JS': 'jiashan', 'HN': 'xiashi', 'LP': 'linping', 'XS': 'xiaoshan',
9 | 'FY': 'fuyang', 'RA': 'ruao', 'CX': 'cixi', 'SM': 'sanmen',
10 | 'TT': 'tiantai', 'WZ': 'wenzhou', 'SC': 'suichang', 'YB': 'youbu'}
11 |
12 | converters = {}
13 |
14 | for dialect in dialects.values():
15 | try:
16 | converters[dialect] = opencc.OpenCC(dialect)
17 | except:
18 | pass
19 |
20 |
21 | def ngu_dialect_to_ipa(text, dialect):
22 | dialect = dialects[dialect]
23 | text = converters[dialect].convert(text).replace('-','').replace('$',' ')
24 | text = re.sub(r'[、;:]', ',', text)
25 | text = re.sub(r'\s*,\s*', ', ', text)
26 | text = re.sub(r'\s*。\s*', '. ', text)
27 | text = re.sub(r'\s*?\s*', '? ', text)
28 | text = re.sub(r'\s*!\s*', '! ', text)
29 | text = re.sub(r'\s*$', '', text)
30 | return text
31 |
--------------------------------------------------------------------------------
/README-original.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | [Korean](README.md)
10 |
11 | > ### 这是一个基于TTS+VITS的ChatGPT语音对话程序!
12 |
13 | 效果演示BiliBIli:[《青春猪头少年不会梦见赛博女友》](https://www.bilibili.com/video/BV1rv4y1Q7eT "BiliBili")
14 |
15 | **当前支持功能:**
16 | * [x] ChatGPT的对话聊天
17 | * [x] 回答转语音
18 | * [x] 多角色语音
19 | * [x] 语音识别对话 (研发了一款真正人性化的智能语音Q宝
20 | * [x] 对接Live2D的Web版本
21 | * [x] [对接Marai机器人](https://github.com/MuBai-He/ChatWaifu-marai)
22 |
23 | # 运行方法
24 | #### 如果您在国内,可能需要使用vpn
25 |
26 | # 如何获取Token
27 | #### 在浏览器登入https://api.openai.com
28 | #### 在个人账号界面添加新的api token并复制保存
29 | #### 将值复制进入游戏并回车
30 |
31 | ## 6.鸣谢:
32 | - [MoeGoe_GUI]https://github.com/CjangCjengh/MoeGoe_GUI
33 | - [Pretrained models]https://github.com/CjangCjengh/TTSModels
34 |
--------------------------------------------------------------------------------
/text/sanskrit.py:
--------------------------------------------------------------------------------
1 | import re
2 | from indic_transliteration import sanscript
3 |
4 |
5 | # List of (iast, ipa) pairs:
6 | _iast_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
7 | ('a', 'ə'),
8 | ('ā', 'aː'),
9 | ('ī', 'iː'),
10 | ('ū', 'uː'),
11 | ('ṛ', 'ɹ`'),
12 | ('ṝ', 'ɹ`ː'),
13 | ('ḷ', 'l`'),
14 | ('ḹ', 'l`ː'),
15 | ('e', 'eː'),
16 | ('o', 'oː'),
17 | ('k', 'k⁼'),
18 | ('k⁼h', 'kʰ'),
19 | ('g', 'g⁼'),
20 | ('g⁼h', 'gʰ'),
21 | ('ṅ', 'ŋ'),
22 | ('c', 'ʧ⁼'),
23 | ('ʧ⁼h', 'ʧʰ'),
24 | ('j', 'ʥ⁼'),
25 | ('ʥ⁼h', 'ʥʰ'),
26 | ('ñ', 'n^'),
27 | ('ṭ', 't`⁼'),
28 | ('t`⁼h', 't`ʰ'),
29 | ('ḍ', 'd`⁼'),
30 | ('d`⁼h', 'd`ʰ'),
31 | ('ṇ', 'n`'),
32 | ('t', 't⁼'),
33 | ('t⁼h', 'tʰ'),
34 | ('d', 'd⁼'),
35 | ('d⁼h', 'dʰ'),
36 | ('p', 'p⁼'),
37 | ('p⁼h', 'pʰ'),
38 | ('b', 'b⁼'),
39 | ('b⁼h', 'bʰ'),
40 | ('y', 'j'),
41 | ('ś', 'ʃ'),
42 | ('ṣ', 's`'),
43 | ('r', 'ɾ'),
44 | ('l̤', 'l`'),
45 | ('h', 'ɦ'),
46 | ("'", ''),
47 | ('~', '^'),
48 | ('ṃ', '^')
49 | ]]
50 |
51 |
52 | def devanagari_to_ipa(text):
53 | text = text.replace('ॐ', 'ओम्')
54 | text = re.sub(r'\s*।\s*$', '.', text)
55 | text = re.sub(r'\s*।\s*', ', ', text)
56 | text = re.sub(r'\s*॥', '.', text)
57 | text = sanscript.transliterate(text, sanscript.DEVANAGARI, sanscript.IAST)
58 | for regex, replacement in _iast_to_ipa:
59 | text = re.sub(regex, replacement, text)
60 | text = re.sub('(.)[`ː]*ḥ', lambda x: x.group(0)
61 | [:-1]+'h'+x.group(1)+'*', text)
62 | return text
63 |
--------------------------------------------------------------------------------
/text/cantonese.py:
--------------------------------------------------------------------------------
1 | import re
2 | import cn2an
3 | import opencc
4 |
5 |
6 | converter = opencc.OpenCC('jyutjyu')
7 |
8 | # List of (Latin alphabet, ipa) pairs:
9 | _latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
10 | ('A', 'ei˥'),
11 | ('B', 'biː˥'),
12 | ('C', 'siː˥'),
13 | ('D', 'tiː˥'),
14 | ('E', 'iː˥'),
15 | ('F', 'e˥fuː˨˩'),
16 | ('G', 'tsiː˥'),
17 | ('H', 'ɪk̚˥tsʰyː˨˩'),
18 | ('I', 'ɐi˥'),
19 | ('J', 'tsei˥'),
20 | ('K', 'kʰei˥'),
21 | ('L', 'e˥llou˨˩'),
22 | ('M', 'ɛːm˥'),
23 | ('N', 'ɛːn˥'),
24 | ('O', 'ou˥'),
25 | ('P', 'pʰiː˥'),
26 | ('Q', 'kʰiːu˥'),
27 | ('R', 'aː˥lou˨˩'),
28 | ('S', 'ɛː˥siː˨˩'),
29 | ('T', 'tʰiː˥'),
30 | ('U', 'juː˥'),
31 | ('V', 'wiː˥'),
32 | ('W', 'tʊk̚˥piː˥juː˥'),
33 | ('X', 'ɪk̚˥siː˨˩'),
34 | ('Y', 'waːi˥'),
35 | ('Z', 'iː˨sɛːt̚˥')
36 | ]]
37 |
38 |
39 | def number_to_cantonese(text):
40 | return re.sub(r'\d+(?:\.?\d+)?', lambda x: cn2an.an2cn(x.group()), text)
41 |
42 |
43 | def latin_to_ipa(text):
44 | for regex, replacement in _latin_to_ipa:
45 | text = re.sub(regex, replacement, text)
46 | return text
47 |
48 |
49 | def cantonese_to_ipa(text):
50 | text = number_to_cantonese(text.upper())
51 | text = converter.convert(text).replace('-','').replace('$',' ')
52 | text = re.sub(r'[A-Z]', lambda x: latin_to_ipa(x.group())+' ', text)
53 | text = re.sub(r'[、;:]', ',', text)
54 | text = re.sub(r'\s*,\s*', ', ', text)
55 | text = re.sub(r'\s*。\s*', '. ', text)
56 | text = re.sub(r'\s*?\s*', '? ', text)
57 | text = re.sub(r'\s*!\s*', '! ', text)
58 | text = re.sub(r'\s*$', '', text)
59 | return text
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | [original readme](README-original.md)
10 |
11 | > ## How to run
12 | ### Create virtual environment (optional)
13 | ```
14 | python -m venv venv
15 | venv\Scripts\activate
16 | ```
17 | ### Install pytorch
18 | ```
19 | pip3 install torch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 --index-url https://download.pytorch.org/whl/cu117
20 | ```
21 | ### Install requirements
22 | ```
23 | pip3 install -r requirements.txt
24 | ```
25 | if error occurs, install visual studio and build tools and try again.
26 |
27 | ### Install Ren'py
28 | - Download [Ren'py sdk](https://www.renpy.org/latest.html) and add path to environment variable
29 | - Install Live2D library
30 | ```
31 | Setting - Install library - Install Live2D Cubism
32 | ```
33 |
34 | ### Place your vits model ./userfile/tts/
35 | such this structure:
36 | ```
37 | ──┬─userfile/tts/
38 | ├── config.json
39 | └── G_128000.pth
40 | ```
41 |
42 | ### Run server
43 | ```
44 | python server.py
45 | ```
46 |
47 | ### Run game
48 | ```
49 | renpy ./ChatWithGPT/
50 | ```
51 | You can get api key [here](https://platform.openai.com/account/api-keys)
52 |
53 | ## VITS credit
54 | - [MoeGoe_GUI]https://github.com/CjangCjengh/MoeGoe_GUI
55 | - [Pretrained models]https://github.com/CjangCjengh/TTSModels
56 |
--------------------------------------------------------------------------------
/text/shanghainese.py:
--------------------------------------------------------------------------------
1 | import re
2 | import cn2an
3 | import opencc
4 |
5 |
6 | converter = opencc.OpenCC('zaonhe')
7 |
8 | # List of (Latin alphabet, ipa) pairs:
9 | _latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
10 | ('A', 'ᴇ'),
11 | ('B', 'bi'),
12 | ('C', 'si'),
13 | ('D', 'di'),
14 | ('E', 'i'),
15 | ('F', 'ᴇf'),
16 | ('G', 'dʑi'),
17 | ('H', 'ᴇtɕʰ'),
18 | ('I', 'ᴀi'),
19 | ('J', 'dʑᴇ'),
20 | ('K', 'kʰᴇ'),
21 | ('L', 'ᴇl'),
22 | ('M', 'ᴇm'),
23 | ('N', 'ᴇn'),
24 | ('O', 'o'),
25 | ('P', 'pʰi'),
26 | ('Q', 'kʰiu'),
27 | ('R', 'ᴀl'),
28 | ('S', 'ᴇs'),
29 | ('T', 'tʰi'),
30 | ('U', 'ɦiu'),
31 | ('V', 'vi'),
32 | ('W', 'dᴀbɤliu'),
33 | ('X', 'ᴇks'),
34 | ('Y', 'uᴀi'),
35 | ('Z', 'zᴇ')
36 | ]]
37 |
38 |
39 | def _number_to_shanghainese(num):
40 | num = cn2an.an2cn(num).replace('一十','十').replace('二十', '廿').replace('二', '两')
41 | return re.sub(r'((?:^|[^三四五六七八九])十|廿)两', r'\1二', num)
42 |
43 |
44 | def number_to_shanghainese(text):
45 | return re.sub(r'\d+(?:\.?\d+)?', lambda x: _number_to_shanghainese(x.group()), text)
46 |
47 |
48 | def latin_to_ipa(text):
49 | for regex, replacement in _latin_to_ipa:
50 | text = re.sub(regex, replacement, text)
51 | return text
52 |
53 |
54 | def shanghainese_to_ipa(text):
55 | text = number_to_shanghainese(text.upper())
56 | text = converter.convert(text).replace('-','').replace('$',' ')
57 | text = re.sub(r'[A-Z]', lambda x: latin_to_ipa(x.group())+' ', text)
58 | text = re.sub(r'[、;:]', ',', text)
59 | text = re.sub(r'\s*,\s*', ', ', text)
60 | text = re.sub(r'\s*。\s*', '. ', text)
61 | text = re.sub(r'\s*?\s*', '? ', text)
62 | text = re.sub(r'\s*!\s*', '! ', text)
63 | text = re.sub(r'\s*$', '', text)
64 | return text
65 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from json import loads
3 | import torch
4 | from torch import load, FloatTensor
5 | from numpy import float32
6 | import librosa
7 |
8 |
9 | class HParams():
10 | def __init__(self, **kwargs):
11 | for k, v in kwargs.items():
12 | if type(v) == dict:
13 | v = HParams(**v)
14 | self[k] = v
15 |
16 | def keys(self):
17 | return self.__dict__.keys()
18 |
19 | def items(self):
20 | return self.__dict__.items()
21 |
22 | def values(self):
23 | return self.__dict__.values()
24 |
25 | def __len__(self):
26 | return len(self.__dict__)
27 |
28 | def __getitem__(self, key):
29 | return getattr(self, key)
30 |
31 | def __setitem__(self, key, value):
32 | return setattr(self, key, value)
33 |
34 | def __contains__(self, key):
35 | return key in self.__dict__
36 |
37 | def __repr__(self):
38 | return self.__dict__.__repr__()
39 |
40 |
41 | def load_checkpoint(checkpoint_path, model):
42 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
43 | checkpoint_dict = load(checkpoint_path, map_location=device)
44 | iteration = checkpoint_dict['iteration']
45 | saved_state_dict = checkpoint_dict['model']
46 | if hasattr(model, 'module'):
47 | state_dict = model.module.state_dict()
48 | else:
49 | state_dict = model.state_dict()
50 | new_state_dict= {}
51 | for k, v in state_dict.items():
52 | try:
53 | new_state_dict[k] = saved_state_dict[k]
54 | except:
55 | logging.info("%s is not in the checkpoint" % k)
56 | new_state_dict[k] = v
57 | if hasattr(model, 'module'):
58 | model.module.load_state_dict(new_state_dict)
59 | else:
60 | model.load_state_dict(new_state_dict)
61 | logging.info("Loaded checkpoint '{}' (iteration {})" .format(
62 | checkpoint_path, iteration))
63 | return
64 |
65 |
66 | def get_hparams_from_file(config_path):
67 | with open(config_path, "r", encoding='utf-8') as f:
68 | data = f.read()
69 | config = loads(data)
70 |
71 | hparams = HParams(**config)
72 | return hparams
73 |
74 |
75 | def load_audio_to_torch(full_path, target_sampling_rate):
76 | audio, sampling_rate = librosa.load(full_path, sr=target_sampling_rate, mono=True)
77 | return FloatTensor(audio.astype(float32))
78 |
--------------------------------------------------------------------------------
/commons.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.nn import functional as F
3 | import torch.jit
4 |
5 |
6 | def script_method(fn, _rcb=None):
7 | return fn
8 |
9 |
10 | def script(obj, optimize=True, _frames_up=0, _rcb=None):
11 | return obj
12 |
13 |
14 | torch.jit.script_method = script_method
15 | torch.jit.script = script
16 |
17 |
18 | def init_weights(m, mean=0.0, std=0.01):
19 | classname = m.__class__.__name__
20 | if classname.find("Conv") != -1:
21 | m.weight.data.normal_(mean, std)
22 |
23 |
24 | def get_padding(kernel_size, dilation=1):
25 | return int((kernel_size*dilation - dilation)/2)
26 |
27 |
28 | def intersperse(lst, item):
29 | result = [item] * (len(lst) * 2 + 1)
30 | result[1::2] = lst
31 | return result
32 |
33 |
34 | def slice_segments(x, ids_str, segment_size=4):
35 | ret = torch.zeros_like(x[:, :, :segment_size])
36 | for i in range(x.size(0)):
37 | idx_str = ids_str[i]
38 | idx_end = idx_str + segment_size
39 | ret[i] = x[i, :, idx_str:idx_end]
40 | return ret
41 |
42 |
43 | def rand_slice_segments(x, x_lengths=None, segment_size=4):
44 | b, d, t = x.size()
45 | if x_lengths is None:
46 | x_lengths = t
47 | ids_str_max = x_lengths - segment_size + 1
48 | ids_str = (torch.rand([b]).to(device=x.device) * ids_str_max).to(dtype=torch.long)
49 | ret = slice_segments(x, ids_str, segment_size)
50 | return ret, ids_str
51 |
52 |
53 | def subsequent_mask(length):
54 | mask = torch.tril(torch.ones(length, length)).unsqueeze(0).unsqueeze(0)
55 | return mask
56 |
57 |
58 | @torch.jit.script
59 | def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
60 | n_channels_int = n_channels[0]
61 | in_act = input_a + input_b
62 | t_act = torch.tanh(in_act[:, :n_channels_int, :])
63 | s_act = torch.sigmoid(in_act[:, n_channels_int:, :])
64 | acts = t_act * s_act
65 | return acts
66 |
67 |
68 | def convert_pad_shape(pad_shape):
69 | l = pad_shape[::-1]
70 | pad_shape = [item for sublist in l for item in sublist]
71 | return pad_shape
72 |
73 |
74 | def sequence_mask(length, max_length=None):
75 | if max_length is None:
76 | max_length = length.max()
77 | x = torch.arange(max_length, dtype=length.dtype, device=length.device)
78 | return x.unsqueeze(0) < length.unsqueeze(1)
79 |
80 |
81 | def generate_path(duration, mask):
82 | """
83 | duration: [b, 1, t_x]
84 | mask: [b, 1, t_y, t_x]
85 | """
86 | device = duration.device
87 |
88 | b, _, t_y, t_x = mask.shape
89 | cum_duration = torch.cumsum(duration, -1)
90 |
91 | cum_duration_flat = cum_duration.view(b * t_x)
92 | path = sequence_mask(cum_duration_flat, t_y).to(mask.dtype)
93 | path = path.view(b, t_x, t_y)
94 | path = path - F.pad(path, convert_pad_shape([[0, 0], [1, 0], [0, 0]]))[:, :-1]
95 | path = path.unsqueeze(1).transpose(2,3) * mask
96 | return path
97 |
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/hiyori.model3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "FileReferences": {
4 | "Moc": "Hiyori.moc3",
5 | "Textures": [
6 | "Hiyori.2048/texture_00.png",
7 | "Hiyori.2048/texture_01.png"
8 | ],
9 | "Physics": "Hiyori.physics3.json",
10 | "UserData": "Hiyori.userdata3.json",
11 | "Pose": "Hiyori.pose3.json",
12 | "DisplayInfo": "Hiyori.cdi3.json",
13 | "Motions": {
14 | "Idle": [
15 | {
16 | "File": "motions/Hiyori_m01.motion3.json",
17 | "FadeInTime": 0.5,
18 | "FadeOutTime": 0.5
19 | },
20 | {
21 | "File": "motions/Hiyori_m02.motion3.json",
22 | "FadeInTime": 0.5,
23 | "FadeOutTime": 0.5
24 | },
25 | {
26 | "File": "motions/Hiyori_m03.motion3.json",
27 | "FadeInTime": 0.5,
28 | "FadeOutTime": 0.5
29 | },
30 | {
31 | "File": "motions/Hiyori_m05.motion3.json",
32 | "FadeInTime": 0.5,
33 | "FadeOutTime": 0.5
34 | },
35 | {
36 | "File": "motions/Hiyori_m06.motion3.json",
37 | "FadeInTime": 0.5,
38 | "FadeOutTime": 0.5
39 | },
40 | {
41 | "File": "motions/Hiyori_m07.motion3.json",
42 | "FadeInTime": 0.5,
43 | "FadeOutTime": 0.5
44 | },
45 | {
46 | "File": "motions/Hiyori_m08.motion3.json",
47 | "FadeInTime": 0.5,
48 | "FadeOutTime": 0.5
49 | },
50 | {
51 | "File": "motions/Hiyori_m09.motion3.json",
52 | "FadeInTime": 0.5,
53 | "FadeOutTime": 0.5
54 | },
55 | {
56 | "File": "motions/Hiyori_m10.motion3.json",
57 | "FadeInTime": 0.5,
58 | "FadeOutTime": 0.5
59 | }
60 | ],
61 | "TapBody": [
62 | {
63 | "File": "motions/Hiyori_m04.motion3.json",
64 | "FadeInTime": 0.5,
65 | "FadeOutTime": 0.5
66 | }
67 | ],
68 | "": [
69 | {
70 | "File": "motions/Hiyori_m01.motion3.json"
71 | },
72 | {
73 | "File": "motions/Hiyori_m02.motion3.json"
74 | },
75 | {
76 | "File": "motions/Hiyori_m03.motion3.json"
77 | },
78 | {
79 | "File": "motions/Hiyori_m04.motion3.json"
80 | },
81 | {
82 | "File": "motions/Hiyori_m05.motion3.json"
83 | },
84 | {
85 | "File": "motions/Hiyori_m06.motion3.json"
86 | },
87 | {
88 | "File": "motions/Hiyori_m07.motion3.json"
89 | },
90 | {
91 | "File": "motions/Hiyori_m08.motion3.json"
92 | },
93 | {
94 | "File": "motions/Hiyori_m09.motion3.json"
95 | },
96 | {
97 | "File": "motions/Hiyori_m10.motion3.json"
98 | },
99 | {
100 | "File": "motions/Hiyori_talking.motion3.json"
101 | },
102 | {
103 | "File": "motions/Hiyori_talking.motion3.json"
104 | }
105 | ]
106 | }
107 | },
108 | "Groups": [
109 | {
110 | "Target": "Parameter",
111 | "Name": "LipSync",
112 | "Ids": [
113 | "ParamMouthOpenY"
114 | ]
115 | },
116 | {
117 | "Target": "Parameter",
118 | "Name": "EyeBlink",
119 | "Ids": [
120 | "ParamEyeLOpen",
121 | "ParamEyeROpen"
122 | ]
123 | }
124 | ],
125 | "HitAreas": [
126 | {
127 | "Id": "HitArea",
128 | "Name": "Body"
129 | }
130 | ]
131 | }
--------------------------------------------------------------------------------
/ChatWithGPT/game/script.rpy:
--------------------------------------------------------------------------------
1 | # Game scripts can be placed in this file.
2 |
3 | # Declare the characters used by this game. The color parameter colors the character name.
4 |
5 | define e = Character("챗봇")
6 | define y = Character("사용자")
7 | define config.gl2 = True
8 |
9 | image hiyori = Live2D("Resources/Hiyori", base=.6, loop = True, fade=True)
10 |
11 | init python:
12 | import socket
13 | import time
14 | thinking = 0
15 | total_data = bytes()
16 | renpy.block_rollback()
17 | ip_port = ('127.0.0.1', 9000)
18 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
19 | client.connect(ip_port)
20 |
21 |
22 | # The game starts here.
23 |
24 | label start:
25 | $ renpy.block_rollback()
26 | show hiyori m01
27 |
28 | jump chooseTts
29 |
30 | label chooseTts:
31 | $ renpy.block_rollback()
32 | menu TTSChoice:
33 | e"TTS 서비스를 선택해주세요"
34 | "로컬 VITS":
35 | python:
36 | client.send(("0").encode())
37 | jump modelChoice
38 | "네이버 TTS":
39 | python:
40 | client.send(("1").encode())
41 | jump getApiKey
42 |
43 | label modelChoice:
44 | $ renpy.block_rollback()
45 | menu KRmodelChoice:
46 | e "음성 출력할 캐릭터를 선택해주세요"
47 | "index 0":
48 | python:
49 | client.send(("0").encode())
50 | "index 1":
51 | python:
52 | client.send(("1").encode())
53 | "index 2":
54 | python:
55 | client.send(("2").encode())
56 | "index 3":
57 | python:
58 | client.send(("3").encode())
59 | "index 4":
60 | python:
61 | client.send(("4").encode())
62 | "index 5":
63 | python:
64 | client.send(("5").encode())
65 |
66 | jump getApiKey
67 |
68 |
69 | label getApiKey:
70 | $ renpy.block_rollback()
71 |
72 | python:
73 | token = renpy.input("open AI API KEY를 입력해주세요")
74 | client.send(token.encode())
75 |
76 | jump uploadSetting
77 | return
78 |
79 |
80 | label uploadSetting:
81 | $ renpy.block_rollback()
82 | python:
83 | token = renpy.input("원하는 배경 설정을 입력해주세요")
84 | client.send(token.encode())
85 | jump uploadInit
86 |
87 | label uploadInit:
88 | $ renpy.block_rollback()
89 | python:
90 | token = renpy.input("해당 캐릭터의 첫 대사를 입력해주세요")
91 | client.send(token.encode())
92 | jump talk_keyboard
93 |
94 |
95 | label talk_keyboard:
96 | $ renpy.block_rollback()
97 | show hiyori m02
98 | python:
99 | message = renpy.input("나:")
100 | client.send(message.encode())
101 | data = bytes()
102 | jump checkRes
103 |
104 | label checkRes:
105 | $ renpy.block_rollback()
106 | if(thinking == 0):
107 | show hiyori m03
108 | e "..."
109 |
110 | python:
111 | client.setblocking(0)
112 | try:
113 | data = client.recv(1024)
114 | total_data += data
115 | except:
116 | data = bytes()
117 | client.setblocking(1)
118 |
119 | if(len(data) > 0 and len(data) < 1024):
120 | python:
121 | response = total_data.decode()
122 | total_data = bytes()
123 | thinking = 0
124 | jump answer
125 | else:
126 | $ renpy.block_rollback()
127 | e "......"
128 | $ thinking = 1
129 | jump checkRes
130 |
131 |
132 |
133 |
134 | label answer:
135 | show hiyori talking
136 | voice "/audio/test.ogg"
137 | $ renpy.block_rollback()
138 | e "[response]"
139 | voice sustain
140 |
141 | $ client.send("음성 재생 완료".encode())
142 | jump talk_keyboard
--------------------------------------------------------------------------------
/mel_processing.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.utils.data
3 | from librosa.filters import mel as librosa_mel_fn
4 |
5 | MAX_WAV_VALUE = 32768.0
6 |
7 |
8 | def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
9 | """
10 | PARAMS
11 | ------
12 | C: compression factor
13 | """
14 | return torch.log(torch.clamp(x, min=clip_val) * C)
15 |
16 |
17 | def dynamic_range_decompression_torch(x, C=1):
18 | """
19 | PARAMS
20 | ------
21 | C: compression factor used to compress
22 | """
23 | return torch.exp(x) / C
24 |
25 |
26 | def spectral_normalize_torch(magnitudes):
27 | output = dynamic_range_compression_torch(magnitudes)
28 | return output
29 |
30 |
31 | def spectral_de_normalize_torch(magnitudes):
32 | output = dynamic_range_decompression_torch(magnitudes)
33 | return output
34 |
35 |
36 | mel_basis = {}
37 | hann_window = {}
38 |
39 |
40 | def spectrogram_torch(y, n_fft, sampling_rate, hop_size, win_size, center=False):
41 | if torch.min(y) < -1.:
42 | print('min value is ', torch.min(y))
43 | if torch.max(y) > 1.:
44 | print('max value is ', torch.max(y))
45 |
46 | global hann_window
47 | dtype_device = str(y.dtype) + '_' + str(y.device)
48 | wnsize_dtype_device = str(win_size) + '_' + dtype_device
49 | if wnsize_dtype_device not in hann_window:
50 | hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(dtype=y.dtype, device=y.device)
51 |
52 | y = torch.nn.functional.pad(y.unsqueeze(1), (int((n_fft-hop_size)/2), int((n_fft-hop_size)/2)), mode='reflect')
53 | y = y.squeeze(1)
54 |
55 | spec = torch.stft(y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[wnsize_dtype_device],
56 | center=center, pad_mode='reflect', normalized=False, onesided=True, return_complex=False)
57 |
58 | spec = torch.sqrt(spec.pow(2).sum(-1) + 1e-6)
59 | return spec
60 |
61 |
62 | def spec_to_mel_torch(spec, n_fft, num_mels, sampling_rate, fmin, fmax):
63 | global mel_basis
64 | dtype_device = str(spec.dtype) + '_' + str(spec.device)
65 | fmax_dtype_device = str(fmax) + '_' + dtype_device
66 | if fmax_dtype_device not in mel_basis:
67 | mel = librosa_mel_fn(sampling_rate, n_fft, num_mels, fmin, fmax)
68 | mel_basis[fmax_dtype_device] = torch.from_numpy(mel).to(dtype=spec.dtype, device=spec.device)
69 | spec = torch.matmul(mel_basis[fmax_dtype_device], spec)
70 | spec = spectral_normalize_torch(spec)
71 | return spec
72 |
73 |
74 | def mel_spectrogram_torch(y, n_fft, num_mels, sampling_rate, hop_size, win_size, fmin, fmax, center=False):
75 | if torch.min(y) < -1.:
76 | print('min value is ', torch.min(y))
77 | if torch.max(y) > 1.:
78 | print('max value is ', torch.max(y))
79 |
80 | global mel_basis, hann_window
81 | dtype_device = str(y.dtype) + '_' + str(y.device)
82 | fmax_dtype_device = str(fmax) + '_' + dtype_device
83 | wnsize_dtype_device = str(win_size) + '_' + dtype_device
84 | if fmax_dtype_device not in mel_basis:
85 | mel = librosa_mel_fn(sampling_rate, n_fft, num_mels, fmin, fmax)
86 | mel_basis[fmax_dtype_device] = torch.from_numpy(mel).to(dtype=y.dtype, device=y.device)
87 | if wnsize_dtype_device not in hann_window:
88 | hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(dtype=y.dtype, device=y.device)
89 |
90 | y = torch.nn.functional.pad(y.unsqueeze(1), (int((n_fft-hop_size)/2), int((n_fft-hop_size)/2)), mode='reflect')
91 | y = y.squeeze(1)
92 |
93 | spec = torch.stft(y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[wnsize_dtype_device],
94 | center=center, pad_mode='reflect', normalized=False, onesided=True)
95 |
96 | spec = torch.sqrt(spec.pow(2).sum(-1) + 1e-6)
97 |
98 | spec = torch.matmul(mel_basis[fmax_dtype_device], spec)
99 | spec = spectral_normalize_torch(spec)
100 |
101 | return spec
102 |
--------------------------------------------------------------------------------
/text/japanese.py:
--------------------------------------------------------------------------------
1 | import re
2 | from unidecode import unidecode
3 | import pyopenjtalk
4 |
5 |
6 | # Regular expression matching Japanese without punctuation marks:
7 | _japanese_characters = re.compile(
8 | r'[A-Za-z\d\u3005\u3040-\u30ff\u4e00-\u9fff\uff11-\uff19\uff21-\uff3a\uff41-\uff5a\uff66-\uff9d]')
9 |
10 | # Regular expression matching non-Japanese characters or punctuation marks:
11 | _japanese_marks = re.compile(
12 | r'[^A-Za-z\d\u3005\u3040-\u30ff\u4e00-\u9fff\uff11-\uff19\uff21-\uff3a\uff41-\uff5a\uff66-\uff9d]')
13 |
14 | # List of (symbol, Japanese) pairs for marks:
15 | _symbols_to_japanese = [(re.compile('%s' % x[0]), x[1]) for x in [
16 | ('%', 'パーセント')
17 | ]]
18 |
19 | # List of (romaji, ipa) pairs for marks:
20 | _romaji_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
21 | ('ts', 'ʦ'),
22 | ('u', 'ɯ'),
23 | ('j', 'ʥ'),
24 | ('y', 'j'),
25 | ('ni', 'n^i'),
26 | ('nj', 'n^'),
27 | ('hi', 'çi'),
28 | ('hj', 'ç'),
29 | ('f', 'ɸ'),
30 | ('I', 'i*'),
31 | ('U', 'ɯ*'),
32 | ('r', 'ɾ')
33 | ]]
34 |
35 | # List of (romaji, ipa2) pairs for marks:
36 | _romaji_to_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [
37 | ('u', 'ɯ'),
38 | ('ʧ', 'tʃ'),
39 | ('j', 'dʑ'),
40 | ('y', 'j'),
41 | ('ni', 'n^i'),
42 | ('nj', 'n^'),
43 | ('hi', 'çi'),
44 | ('hj', 'ç'),
45 | ('f', 'ɸ'),
46 | ('I', 'i*'),
47 | ('U', 'ɯ*'),
48 | ('r', 'ɾ')
49 | ]]
50 |
51 | # List of (consonant, sokuon) pairs:
52 | _real_sokuon = [(re.compile('%s' % x[0]), x[1]) for x in [
53 | (r'Q([↑↓]*[kg])', r'k#\1'),
54 | (r'Q([↑↓]*[tdjʧ])', r't#\1'),
55 | (r'Q([↑↓]*[sʃ])', r's\1'),
56 | (r'Q([↑↓]*[pb])', r'p#\1')
57 | ]]
58 |
59 | # List of (consonant, hatsuon) pairs:
60 | _real_hatsuon = [(re.compile('%s' % x[0]), x[1]) for x in [
61 | (r'N([↑↓]*[pbm])', r'm\1'),
62 | (r'N([↑↓]*[ʧʥj])', r'n^\1'),
63 | (r'N([↑↓]*[tdn])', r'n\1'),
64 | (r'N([↑↓]*[kg])', r'ŋ\1')
65 | ]]
66 |
67 |
68 | def symbols_to_japanese(text):
69 | for regex, replacement in _symbols_to_japanese:
70 | text = re.sub(regex, replacement, text)
71 | return text
72 |
73 |
74 | def japanese_to_romaji_with_accent(text):
75 | '''Reference https://r9y9.github.io/ttslearn/latest/notebooks/ch10_Recipe-Tacotron.html'''
76 | text = symbols_to_japanese(text)
77 | sentences = re.split(_japanese_marks, text)
78 | marks = re.findall(_japanese_marks, text)
79 | text = ''
80 | for i, sentence in enumerate(sentences):
81 | if re.match(_japanese_characters, sentence):
82 | if text != '':
83 | text += ' '
84 | labels = pyopenjtalk.extract_fullcontext(sentence)
85 | for n, label in enumerate(labels):
86 | phoneme = re.search(r'\-([^\+]*)\+', label).group(1)
87 | if phoneme not in ['sil', 'pau']:
88 | text += phoneme.replace('ch', 'ʧ').replace('sh',
89 | 'ʃ').replace('cl', 'Q')
90 | else:
91 | continue
92 | # n_moras = int(re.search(r'/F:(\d+)_', label).group(1))
93 | a1 = int(re.search(r"/A:(\-?[0-9]+)\+", label).group(1))
94 | a2 = int(re.search(r"\+(\d+)\+", label).group(1))
95 | a3 = int(re.search(r"\+(\d+)/", label).group(1))
96 | if re.search(r'\-([^\+]*)\+', labels[n + 1]).group(1) in ['sil', 'pau']:
97 | a2_next = -1
98 | else:
99 | a2_next = int(
100 | re.search(r"\+(\d+)\+", labels[n + 1]).group(1))
101 | # Accent phrase boundary
102 | if a3 == 1 and a2_next == 1:
103 | text += ' '
104 | # Falling
105 | elif a1 == 0 and a2_next == a2 + 1:
106 | text += '↓'
107 | # Rising
108 | elif a2 == 1 and a2_next == 2:
109 | text += '↑'
110 | if i < len(marks):
111 | text += unidecode(marks[i]).replace(' ', '')
112 | return text
113 |
114 |
115 | def get_real_sokuon(text):
116 | for regex, replacement in _real_sokuon:
117 | text = re.sub(regex, replacement, text)
118 | return text
119 |
120 |
121 | def get_real_hatsuon(text):
122 | for regex, replacement in _real_hatsuon:
123 | text = re.sub(regex, replacement, text)
124 | return text
125 |
126 |
127 | def japanese_to_ipa(text):
128 | text = japanese_to_romaji_with_accent(text).replace('...', '…')
129 | text = re.sub(
130 | r'([aiueo])\1+', lambda x: x.group(0)[0]+'ː'*(len(x.group(0))-1), text)
131 | text = get_real_sokuon(text)
132 | text = get_real_hatsuon(text)
133 | for regex, replacement in _romaji_to_ipa:
134 | text = re.sub(regex, replacement, text)
135 | return text
136 |
137 |
138 | def japanese_to_ipa2(text):
139 | text = japanese_to_romaji_with_accent(text).replace('...', '…')
140 | text = get_real_sokuon(text)
141 | text = get_real_hatsuon(text)
142 | for regex, replacement in _romaji_to_ipa2:
143 | text = re.sub(regex, replacement, text)
144 | return text
145 |
146 |
147 | def japanese_to_ipa3(text):
148 | text = japanese_to_ipa2(text).replace('n^', 'ȵ').replace(
149 | 'ʃ', 'ɕ').replace('*', '\u0325').replace('#', '\u031a')
150 | text = re.sub(
151 | r'([aiɯeo])\1+', lambda x: x.group(0)[0]+'ː'*(len(x.group(0))-1), text)
152 | text = re.sub(r'((?:^|\s)(?:ts|tɕ|[kpt]))', r'\1ʰ', text)
153 | return text
154 |
--------------------------------------------------------------------------------
/ChatWithGPT/game/options.rpy:
--------------------------------------------------------------------------------
1 | ## 이 파일은 귀하의 게임 커스텀으로 변경될 수 있는 옵션을 포함합니다.
2 | ##
3 | ## 두 개의 '#' 표시로 시작되는 줄은 주석이며, 그것을 없애지 말아야 합니다. 한 개
4 | ## 의 '#' 표시로 시작되는 줄은 주석 처리된 코드로 필요한 경우 제거해도 됩니다.
5 |
6 |
7 | ## 기본 ##########################################################################
8 |
9 | ## 인간이 읽을 수 있는 게임의 이름. 기본 윈도우의 제목으로 사용되며, 인터페이스
10 | ## 와 오류 보고에서 보여집니다.
11 | ##
12 | ## 문자열을 _()로 둘러 쌓으면 씌우면 번역의 대상으로 표시됩니다.
13 |
14 | define config.name = _("ChatWithGPT")
15 |
16 |
17 | ## 위에 주어진 제목이 주 메뉴 화면에 표시되는지 결정합니다. 제목을 숨기려면 이것
18 | ## 을 False로 설정하십시오.
19 |
20 | define gui.show_name = True
21 |
22 |
23 | ## 게임의 버전입니다.
24 |
25 | define config.version = "1.0"
26 |
27 |
28 | ## 게임의 about 스크린에 배치되는 텍스트입니다. 텍스트를 삼중 따옴표 사이에 배치
29 | ## 하고 단락 사이에 빈 줄을 남겨 둡니다.
30 |
31 | define gui.about = _p("""
32 | """)
33 |
34 |
35 | ## 배포판의 실행 파일과 디렉토리에 사용되는 게임의 약식 이름. 이것은 ASCII 전용
36 | ## 이어야 하며 공백, 콜론 또는 세미콜론을 포함해서는 안 됩니다.
37 |
38 | define build.name = "ChatWithGPT"
39 |
40 |
41 | ## 음악과 음향 ######################################################################
42 |
43 | ## These three variables control, among other things, which mixers are shown
44 | ## to the player by default. Setting one of these to False will hide the
45 | ## appropriate mixer.
46 |
47 | define config.has_sound = True
48 | define config.has_music = True
49 | define config.has_voice = True
50 |
51 |
52 | ## 사용자가 음향 또는 음성 채널에서 테스트 사운드를 재생할 수 있게 하려면 아래
53 | ## 줄의 주석을 제거하고 이를 사용하여 재생할 샘플 사운드를 설정하십시오.
54 |
55 | # define config.sample_sound = "sample-sound.ogg"
56 | # define config.sample_voice = "sample-voice.ogg"
57 |
58 |
59 | ## 플레이어가 주 메뉴에 있을 때 재생할 오디오 파일을 설정하려면 다음 줄의 주석
60 | ## 처리를 제거하십시오. 이 파일은 중지되거나 다른 파일이 재생 될 때까지 계속 재
61 | ## 생합니다.
62 |
63 | # define config.main_menu_music = "main-menu-theme.ogg"
64 |
65 |
66 | ## 번역 ##########################################################################
67 | ##
68 | ## 이러한 변수는 특정 이벤트가 발생할 때 사용되는 전환을 설정합니다. 각 변수는
69 | ## 전환으로 설정해야 하며, 전환을 사용하지 말아야 한다는 것을 나타내려면 None으
70 | ## 로 설정해야 합니다.
71 |
72 | ## 게임 메뉴에 진입하거나 나갑니다.
73 |
74 | define config.enter_transition = dissolve
75 | define config.exit_transition = dissolve
76 |
77 |
78 | ## 게임 메뉴 화면 사이입니다.
79 |
80 | define config.intra_transition = dissolve
81 |
82 |
83 | ## 게임이 로드된 후 사용되는 전환입니다.
84 |
85 | define config.after_load_transition = None
86 |
87 |
88 | ## 게임 종료 후 주 메뉴에 진입할 때 사용됩니다.
89 |
90 | define config.end_game_transition = None
91 |
92 |
93 | ## 게임을 시작할 때 사용되는 전환을 설정하는 변수가 없습니다. 대신, 초기 장면을
94 | ## 표시한 후 with 문을 사용하십시오.
95 |
96 |
97 | ## 창 관리 ########################################################################
98 | ##
99 | ## 이것은 대사 창이 표시됐을 때 제어합니다. 만약 "show"면, 그것은 상항 표시됩니
100 | ## 다. 만약 "hide"면, 그것은 대사가 주어질 때만 표시됩니다. 만약 "auto"면, 창은
101 | ## 장면(scene) 문 앞에 숨겨져 대화 상자가 표시되면 다시 표시됩니다.
102 | ##
103 | ## 게임이 시작된 후에는 "window show", "window hide", 그리고 "window auto" 문을
104 | ## 사용하여 변경할 수 있습니다.
105 |
106 | define config.window = "auto"
107 |
108 |
109 | ## 대화 창을 표시하고 숨기는 데 사용되는 전환
110 |
111 | define config.window_show_transition = Dissolve(.2)
112 | define config.window_hide_transition = Dissolve(.2)
113 |
114 |
115 | ## 환경설정 기본값 ####################################################################
116 |
117 | ## 기본 글자 속도를 제어합니다. 기본적으로, 0은 즉시이며 다른 숫자는 초당 입력
118 | ## 할 문자 수입니다.
119 |
120 | default preferences.text_cps = 0
121 |
122 |
123 | ## 기본 auto-forward 지연 시간입니다. 숫자가 클수록 대기 시간이 길어지며, 0 ~ 30
124 | ## 이 유효한 범위가 됩니다.
125 |
126 | default preferences.afm_time = 15
127 |
128 |
129 | ## 세이브 디렉토리 ####################################################################
130 | ##
131 | ## 렌파이는 이 게임에 대한 저장 파일을 플랫폼 별로 배치합니다. 세이브 파일들은
132 | ## 여기에 있습니다:
133 | ##
134 | ## 윈도우즈: %APPDATA\RenPy\
135 | ##
136 | ## 매킨토시: $HOME/Library/RenPy/
137 | ##
138 | ## 리눅스: $HOME/.renpy/
139 | ##
140 | ## 이것은 일반적으로 변경해서는 안 되며, 항상 표현형식이 아닌 정확한 문자열이어
141 | ## 야 합니다.
142 |
143 | define config.save_directory = "ChatWithGPT-1680367288"
144 |
145 |
146 | ## Icon ########################################################################
147 | ##
148 | ## 작업 표시 줄 또는 독에 표시되는 아이콘.
149 |
150 | define config.window_icon = "gui/window_icon.png"
151 |
152 |
153 | ## 빌드 구성 #######################################################################
154 | ##
155 | ## 이 섹션은 렌파이가 프로젝트를 배포 파일로 만드는 방법을 제어합니다.
156 |
157 | init python:
158 |
159 | ## 다음 함수는 파일 패턴을 사용합니다. 파일 패턴은 대/소문자를 구분하지 않으
160 | ## 며, /의 유무와 관계없이 기본 디렉터리의 상대 경로와 일치합니다. 여러 패턴
161 | ## 이 일치하면 첫 번째 패턴이 사용됩니다.
162 | ##
163 | ## 패턴 있음:
164 | ##
165 | ## / 는 디렉토리 구분 기호입니다.
166 | ##
167 | ## * 는 디렉토리 구분자를 제외한 모든 문자와 일치합니다.
168 | ##
169 | ## ** 는 디렉토리 구분자를 포함해 모든 문자와 일치합니다.
170 | ##
171 | ## 예를 들어, "*.txt" 는 기본 디렉토리의 txt 파일들과 일치하고, "game/
172 | ## **.ogg" 는 게임 디렉토리 또는 그 서브 디렉토리의 ogg 파일들과 일치하며,
173 | ## "**.psd" 는 프로젝트에서 모든 곳의 psd 파일들과 일치합니다.
174 |
175 | ## 파일을 None으로 분류하여 배포판으로부터 제외하십시오.
176 |
177 | build.classify('**~', None)
178 | build.classify('**.bak', None)
179 | build.classify('**/.**', None)
180 | build.classify('**/#**', None)
181 | build.classify('**/thumbs.db', None)
182 |
183 | ## 파일을 아카이브하려면 'archive'로 분류하십시오.
184 |
185 | # build.classify('game/**.png', 'archive')
186 | # build.classify('game/**.jpg', 'archive')
187 |
188 | ## 파일들의 매칭 문서 패턴은 맥앱(Mac App) 빌드에서 중복되므로 app 및 zip 파
189 | ## 일에 모두 나타납니다.
190 |
191 | build.documentation('*.html')
192 | build.documentation('*.txt')
193 |
194 |
195 | ## 확장 파일을 다운로드하고 인앱 구매를 수행하려면 Google Play 라이센스 키가 필
196 | ## 요합니다. Google Play 개발자 콘솔의 "서비스 및 API"페이지에서 확인할 수 있습
197 | ## 니다.
198 |
199 | # define build.google_play_key = "..."
200 |
201 |
202 | ## itch.io 프로젝트와 연관된 사용자 이름과 프로젝트 이름이며 슬래시로 구분됩니
203 | ## 다.
204 |
205 | # define build.itch_project = "renpytom/test-project"
206 |
--------------------------------------------------------------------------------
/text/english.py:
--------------------------------------------------------------------------------
1 | """ from https://github.com/keithito/tacotron """
2 |
3 | '''
4 | Cleaners are transformations that run over the input text at both training and eval time.
5 |
6 | Cleaners can be selected by passing a comma-delimited list of cleaner names as the "cleaners"
7 | hyperparameter. Some cleaners are English-specific. You'll typically want to use:
8 | 1. "english_cleaners" for English text
9 | 2. "transliteration_cleaners" for non-English text that can be transliterated to ASCII using
10 | the Unidecode library (https://pypi.python.org/pypi/Unidecode)
11 | 3. "basic_cleaners" if you do not want to transliterate (in this case, you should also update
12 | the symbols in symbols.py to match your data).
13 | '''
14 |
15 |
16 | # Regular expression matching whitespace:
17 |
18 |
19 | import re
20 | import inflect
21 | from unidecode import unidecode
22 | import eng_to_ipa as ipa
23 | _inflect = inflect.engine()
24 | _comma_number_re = re.compile(r'([0-9][0-9\,]+[0-9])')
25 | _decimal_number_re = re.compile(r'([0-9]+\.[0-9]+)')
26 | _pounds_re = re.compile(r'£([0-9\,]*[0-9]+)')
27 | _dollars_re = re.compile(r'\$([0-9\.\,]*[0-9]+)')
28 | _ordinal_re = re.compile(r'[0-9]+(st|nd|rd|th)')
29 | _number_re = re.compile(r'[0-9]+')
30 |
31 | # List of (regular expression, replacement) pairs for abbreviations:
32 | _abbreviations = [(re.compile('\\b%s\\.' % x[0], re.IGNORECASE), x[1]) for x in [
33 | ('mrs', 'misess'),
34 | ('mr', 'mister'),
35 | ('dr', 'doctor'),
36 | ('st', 'saint'),
37 | ('co', 'company'),
38 | ('jr', 'junior'),
39 | ('maj', 'major'),
40 | ('gen', 'general'),
41 | ('drs', 'doctors'),
42 | ('rev', 'reverend'),
43 | ('lt', 'lieutenant'),
44 | ('hon', 'honorable'),
45 | ('sgt', 'sergeant'),
46 | ('capt', 'captain'),
47 | ('esq', 'esquire'),
48 | ('ltd', 'limited'),
49 | ('col', 'colonel'),
50 | ('ft', 'fort'),
51 | ]]
52 |
53 |
54 | # List of (ipa, lazy ipa) pairs:
55 | _lazy_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
56 | ('r', 'ɹ'),
57 | ('æ', 'e'),
58 | ('ɑ', 'a'),
59 | ('ɔ', 'o'),
60 | ('ð', 'z'),
61 | ('θ', 's'),
62 | ('ɛ', 'e'),
63 | ('ɪ', 'i'),
64 | ('ʊ', 'u'),
65 | ('ʒ', 'ʥ'),
66 | ('ʤ', 'ʥ'),
67 | ('ˈ', '↓'),
68 | ]]
69 |
70 | # List of (ipa, lazy ipa2) pairs:
71 | _lazy_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [
72 | ('r', 'ɹ'),
73 | ('ð', 'z'),
74 | ('θ', 's'),
75 | ('ʒ', 'ʑ'),
76 | ('ʤ', 'dʑ'),
77 | ('ˈ', '↓'),
78 | ]]
79 |
80 | # List of (ipa, ipa2) pairs
81 | _ipa_to_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [
82 | ('r', 'ɹ'),
83 | ('ʤ', 'dʒ'),
84 | ('ʧ', 'tʃ')
85 | ]]
86 |
87 |
88 | def expand_abbreviations(text):
89 | for regex, replacement in _abbreviations:
90 | text = re.sub(regex, replacement, text)
91 | return text
92 |
93 |
94 | def collapse_whitespace(text):
95 | return re.sub(r'\s+', ' ', text)
96 |
97 |
98 | def _remove_commas(m):
99 | return m.group(1).replace(',', '')
100 |
101 |
102 | def _expand_decimal_point(m):
103 | return m.group(1).replace('.', ' point ')
104 |
105 |
106 | def _expand_dollars(m):
107 | match = m.group(1)
108 | parts = match.split('.')
109 | if len(parts) > 2:
110 | return match + ' dollars' # Unexpected format
111 | dollars = int(parts[0]) if parts[0] else 0
112 | cents = int(parts[1]) if len(parts) > 1 and parts[1] else 0
113 | if dollars and cents:
114 | dollar_unit = 'dollar' if dollars == 1 else 'dollars'
115 | cent_unit = 'cent' if cents == 1 else 'cents'
116 | return '%s %s, %s %s' % (dollars, dollar_unit, cents, cent_unit)
117 | elif dollars:
118 | dollar_unit = 'dollar' if dollars == 1 else 'dollars'
119 | return '%s %s' % (dollars, dollar_unit)
120 | elif cents:
121 | cent_unit = 'cent' if cents == 1 else 'cents'
122 | return '%s %s' % (cents, cent_unit)
123 | else:
124 | return 'zero dollars'
125 |
126 |
127 | def _expand_ordinal(m):
128 | return _inflect.number_to_words(m.group(0))
129 |
130 |
131 | def _expand_number(m):
132 | num = int(m.group(0))
133 | if num > 1000 and num < 3000:
134 | if num == 2000:
135 | return 'two thousand'
136 | elif num > 2000 and num < 2010:
137 | return 'two thousand ' + _inflect.number_to_words(num % 100)
138 | elif num % 100 == 0:
139 | return _inflect.number_to_words(num // 100) + ' hundred'
140 | else:
141 | return _inflect.number_to_words(num, andword='', zero='oh', group=2).replace(', ', ' ')
142 | else:
143 | return _inflect.number_to_words(num, andword='')
144 |
145 |
146 | def normalize_numbers(text):
147 | text = re.sub(_comma_number_re, _remove_commas, text)
148 | text = re.sub(_pounds_re, r'\1 pounds', text)
149 | text = re.sub(_dollars_re, _expand_dollars, text)
150 | text = re.sub(_decimal_number_re, _expand_decimal_point, text)
151 | text = re.sub(_ordinal_re, _expand_ordinal, text)
152 | text = re.sub(_number_re, _expand_number, text)
153 | return text
154 |
155 |
156 | def mark_dark_l(text):
157 | return re.sub(r'l([^aeiouæɑɔəɛɪʊ ]*(?: |$))', lambda x: 'ɫ'+x.group(1), text)
158 |
159 |
160 | def english_to_ipa(text):
161 | text = unidecode(text).lower()
162 | text = expand_abbreviations(text)
163 | text = normalize_numbers(text)
164 | phonemes = ipa.convert(text)
165 | phonemes = collapse_whitespace(phonemes)
166 | return phonemes
167 |
168 |
169 | def english_to_lazy_ipa(text):
170 | text = english_to_ipa(text)
171 | for regex, replacement in _lazy_ipa:
172 | text = re.sub(regex, replacement, text)
173 | return text
174 |
175 |
176 | def english_to_ipa2(text):
177 | text = english_to_ipa(text)
178 | text = mark_dark_l(text)
179 | for regex, replacement in _ipa_to_ipa2:
180 | text = re.sub(regex, replacement, text)
181 | return text.replace('...', '…')
182 |
183 |
184 | def english_to_lazy_ipa2(text):
185 | text = english_to_ipa(text)
186 | for regex, replacement in _lazy_ipa2:
187 | text = re.sub(regex, replacement, text)
188 | return text
189 |
--------------------------------------------------------------------------------
/text/cleaners.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 |
4 | def japanese_cleaners(text):
5 | from text.japanese import japanese_to_romaji_with_accent
6 | text = japanese_to_romaji_with_accent(text)
7 | text = re.sub(r'([A-Za-z])$', r'\1.', text)
8 | return text
9 |
10 |
11 | def japanese_cleaners2(text):
12 | return japanese_cleaners(text).replace('ts', 'ʦ').replace('...', '…')
13 |
14 |
15 | def korean_cleaners(text):
16 | '''Pipeline for Korean text'''
17 | from text.korean import latin_to_hangul, number_to_hangul, divide_hangul
18 | text = latin_to_hangul(text)
19 | text = number_to_hangul(text)
20 | text = divide_hangul(text)
21 | text = re.sub(r'([\u3131-\u3163])$', r'\1.', text)
22 | return text
23 |
24 |
25 | def chinese_cleaners(text):
26 | '''Pipeline for Chinese text'''
27 | from text.mandarin import number_to_chinese, chinese_to_bopomofo, latin_to_bopomofo
28 | text = number_to_chinese(text)
29 | text = chinese_to_bopomofo(text)
30 | text = latin_to_bopomofo(text)
31 | text = re.sub(r'([ˉˊˇˋ˙])$', r'\1。', text)
32 | return text
33 |
34 |
35 | def zh_ja_mixture_cleaners(text):
36 | from text.mandarin import chinese_to_romaji
37 | from text.japanese import japanese_to_romaji_with_accent
38 | text = re.sub(r'\[ZH\](.*?)\[ZH\]',
39 | lambda x: chinese_to_romaji(x.group(1))+' ', text)
40 | text = re.sub(r'\[JA\](.*?)\[JA\]', lambda x: japanese_to_romaji_with_accent(
41 | x.group(1)).replace('ts', 'ʦ').replace('u', 'ɯ').replace('...', '…')+' ', text)
42 | text = re.sub(r'\s+$', '', text)
43 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
44 | return text
45 |
46 |
47 | def sanskrit_cleaners(text):
48 | text = text.replace('॥', '।').replace('ॐ', 'ओम्')
49 | text = re.sub(r'([^।])$', r'\1।', text)
50 | return text
51 |
52 |
53 | def cjks_cleaners(text):
54 | from text.mandarin import chinese_to_lazy_ipa
55 | from text.japanese import japanese_to_ipa
56 | from text.korean import korean_to_lazy_ipa
57 | from text.sanskrit import devanagari_to_ipa
58 | from text.english import english_to_lazy_ipa
59 | text = re.sub(r'\[ZH\](.*?)\[ZH\]',
60 | lambda x: chinese_to_lazy_ipa(x.group(1))+' ', text)
61 | text = re.sub(r'\[JA\](.*?)\[JA\]',
62 | lambda x: japanese_to_ipa(x.group(1))+' ', text)
63 | text = re.sub(r'\[KO\](.*?)\[KO\]',
64 | lambda x: korean_to_lazy_ipa(x.group(1))+' ', text)
65 | text = re.sub(r'\[SA\](.*?)\[SA\]',
66 | lambda x: devanagari_to_ipa(x.group(1))+' ', text)
67 | text = re.sub(r'\[EN\](.*?)\[EN\]',
68 | lambda x: english_to_lazy_ipa(x.group(1))+' ', text)
69 | text = re.sub(r'\s+$', '', text)
70 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
71 | return text
72 |
73 |
74 | def cjke_cleaners(text):
75 | from text.mandarin import chinese_to_lazy_ipa
76 | from text.japanese import japanese_to_ipa
77 | from text.korean import korean_to_ipa
78 | from text.english import english_to_ipa2
79 | text = re.sub(r'\[ZH\](.*?)\[ZH\]', lambda x: chinese_to_lazy_ipa(x.group(1)).replace(
80 | 'ʧ', 'tʃ').replace('ʦ', 'ts').replace('ɥan', 'ɥæn')+' ', text)
81 | text = re.sub(r'\[JA\](.*?)\[JA\]', lambda x: japanese_to_ipa(x.group(1)).replace('ʧ', 'tʃ').replace(
82 | 'ʦ', 'ts').replace('ɥan', 'ɥæn').replace('ʥ', 'dz')+' ', text)
83 | text = re.sub(r'\[KO\](.*?)\[KO\]',
84 | lambda x: korean_to_ipa(x.group(1))+' ', text)
85 | text = re.sub(r'\[EN\](.*?)\[EN\]', lambda x: english_to_ipa2(x.group(1)).replace('ɑ', 'a').replace(
86 | 'ɔ', 'o').replace('ɛ', 'e').replace('ɪ', 'i').replace('ʊ', 'u')+' ', text)
87 | text = re.sub(r'\s+$', '', text)
88 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
89 | return text
90 |
91 |
92 | def cjke_cleaners2(text):
93 | from text.mandarin import chinese_to_ipa
94 | from text.japanese import japanese_to_ipa2
95 | from text.korean import korean_to_ipa
96 | from text.english import english_to_ipa2
97 | text = re.sub(r'\[ZH\](.*?)\[ZH\]',
98 | lambda x: chinese_to_ipa(x.group(1))+' ', text)
99 | text = re.sub(r'\[JA\](.*?)\[JA\]',
100 | lambda x: japanese_to_ipa2(x.group(1))+' ', text)
101 | text = re.sub(r'\[KO\](.*?)\[KO\]',
102 | lambda x: korean_to_ipa(x.group(1))+' ', text)
103 | text = re.sub(r'\[EN\](.*?)\[EN\]',
104 | lambda x: english_to_ipa2(x.group(1))+' ', text)
105 | text = re.sub(r'\s+$', '', text)
106 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
107 | return text
108 |
109 |
110 | def thai_cleaners(text):
111 | from text.thai import num_to_thai, latin_to_thai
112 | text = num_to_thai(text)
113 | text = latin_to_thai(text)
114 | return text
115 |
116 |
117 | def shanghainese_cleaners(text):
118 | from text.shanghainese import shanghainese_to_ipa
119 | text = shanghainese_to_ipa(text)
120 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
121 | return text
122 |
123 |
124 | def chinese_dialect_cleaners(text):
125 | from text.mandarin import chinese_to_ipa2
126 | from text.japanese import japanese_to_ipa3
127 | from text.shanghainese import shanghainese_to_ipa
128 | from text.cantonese import cantonese_to_ipa
129 | from text.english import english_to_lazy_ipa2
130 | from text.ngu_dialect import ngu_dialect_to_ipa
131 | text = re.sub(r'\[ZH\](.*?)\[ZH\]',
132 | lambda x: chinese_to_ipa2(x.group(1))+' ', text)
133 | text = re.sub(r'\[JA\](.*?)\[JA\]',
134 | lambda x: japanese_to_ipa3(x.group(1)).replace('Q', 'ʔ')+' ', text)
135 | text = re.sub(r'\[SH\](.*?)\[SH\]', lambda x: shanghainese_to_ipa(x.group(1)).replace('1', '˥˧').replace('5',
136 | '˧˧˦').replace('6', '˩˩˧').replace('7', '˥').replace('8', '˩˨').replace('ᴀ', 'ɐ').replace('ᴇ', 'e')+' ', text)
137 | text = re.sub(r'\[GD\](.*?)\[GD\]',
138 | lambda x: cantonese_to_ipa(x.group(1))+' ', text)
139 | text = re.sub(r'\[EN\](.*?)\[EN\]',
140 | lambda x: english_to_lazy_ipa2(x.group(1))+' ', text)
141 | text = re.sub(r'\[([A-Z]{2})\](.*?)\[\1\]', lambda x: ngu_dialect_to_ipa(x.group(2), x.group(
142 | 1)).replace('ʣ', 'dz').replace('ʥ', 'dʑ').replace('ʦ', 'ts').replace('ʨ', 'tɕ')+' ', text)
143 | text = re.sub(r'\s+$', '', text)
144 | text = re.sub(r'([^\.,!\?\-…~])$', r'\1.', text)
145 | return text
146 |
--------------------------------------------------------------------------------
/text/korean.py:
--------------------------------------------------------------------------------
1 | import re
2 | from jamo import h2j, j2hcj
3 | import ko_pron
4 |
5 |
6 | # This is a list of Korean classifiers preceded by pure Korean numerals.
7 | _korean_classifiers = '군데 권 개 그루 닢 대 두 마리 모 모금 뭇 발 발짝 방 번 벌 보루 살 수 술 시 쌈 움큼 정 짝 채 척 첩 축 켤레 톨 통'
8 |
9 | # List of (hangul, hangul divided) pairs:
10 | _hangul_divided = [(re.compile('%s' % x[0]), x[1]) for x in [
11 | ('ㄳ', 'ㄱㅅ'),
12 | ('ㄵ', 'ㄴㅈ'),
13 | ('ㄶ', 'ㄴㅎ'),
14 | ('ㄺ', 'ㄹㄱ'),
15 | ('ㄻ', 'ㄹㅁ'),
16 | ('ㄼ', 'ㄹㅂ'),
17 | ('ㄽ', 'ㄹㅅ'),
18 | ('ㄾ', 'ㄹㅌ'),
19 | ('ㄿ', 'ㄹㅍ'),
20 | ('ㅀ', 'ㄹㅎ'),
21 | ('ㅄ', 'ㅂㅅ'),
22 | ('ㅘ', 'ㅗㅏ'),
23 | ('ㅙ', 'ㅗㅐ'),
24 | ('ㅚ', 'ㅗㅣ'),
25 | ('ㅝ', 'ㅜㅓ'),
26 | ('ㅞ', 'ㅜㅔ'),
27 | ('ㅟ', 'ㅜㅣ'),
28 | ('ㅢ', 'ㅡㅣ'),
29 | ('ㅑ', 'ㅣㅏ'),
30 | ('ㅒ', 'ㅣㅐ'),
31 | ('ㅕ', 'ㅣㅓ'),
32 | ('ㅖ', 'ㅣㅔ'),
33 | ('ㅛ', 'ㅣㅗ'),
34 | ('ㅠ', 'ㅣㅜ')
35 | ]]
36 |
37 | # List of (Latin alphabet, hangul) pairs:
38 | _latin_to_hangul = [(re.compile('%s' % x[0], re.IGNORECASE), x[1]) for x in [
39 | ('a', '에이'),
40 | ('b', '비'),
41 | ('c', '시'),
42 | ('d', '디'),
43 | ('e', '이'),
44 | ('f', '에프'),
45 | ('g', '지'),
46 | ('h', '에이치'),
47 | ('i', '아이'),
48 | ('j', '제이'),
49 | ('k', '케이'),
50 | ('l', '엘'),
51 | ('m', '엠'),
52 | ('n', '엔'),
53 | ('o', '오'),
54 | ('p', '피'),
55 | ('q', '큐'),
56 | ('r', '아르'),
57 | ('s', '에스'),
58 | ('t', '티'),
59 | ('u', '유'),
60 | ('v', '브이'),
61 | ('w', '더블유'),
62 | ('x', '엑스'),
63 | ('y', '와이'),
64 | ('z', '제트')
65 | ]]
66 |
67 | # List of (ipa, lazy ipa) pairs:
68 | _ipa_to_lazy_ipa = [(re.compile('%s' % x[0], re.IGNORECASE), x[1]) for x in [
69 | ('t͡ɕ','ʧ'),
70 | ('d͡ʑ','ʥ'),
71 | ('ɲ','n^'),
72 | ('ɕ','ʃ'),
73 | ('ʷ','w'),
74 | ('ɭ','l`'),
75 | ('ʎ','ɾ'),
76 | ('ɣ','ŋ'),
77 | ('ɰ','ɯ'),
78 | ('ʝ','j'),
79 | ('ʌ','ə'),
80 | ('ɡ','g'),
81 | ('\u031a','#'),
82 | ('\u0348','='),
83 | ('\u031e',''),
84 | ('\u0320',''),
85 | ('\u0339','')
86 | ]]
87 |
88 |
89 | def latin_to_hangul(text):
90 | for regex, replacement in _latin_to_hangul:
91 | text = re.sub(regex, replacement, text)
92 | return text
93 |
94 |
95 | def divide_hangul(text):
96 | text = j2hcj(h2j(text))
97 | for regex, replacement in _hangul_divided:
98 | text = re.sub(regex, replacement, text)
99 | return text
100 |
101 |
102 | def hangul_number(num, sino=True):
103 | '''Reference https://github.com/Kyubyong/g2pK'''
104 | num = re.sub(',', '', num)
105 |
106 | if num == '0':
107 | return '영'
108 | if not sino and num == '20':
109 | return '스무'
110 |
111 | digits = '123456789'
112 | names = '일이삼사오육칠팔구'
113 | digit2name = {d: n for d, n in zip(digits, names)}
114 |
115 | modifiers = '한 두 세 네 다섯 여섯 일곱 여덟 아홉'
116 | decimals = '열 스물 서른 마흔 쉰 예순 일흔 여든 아흔'
117 | digit2mod = {d: mod for d, mod in zip(digits, modifiers.split())}
118 | digit2dec = {d: dec for d, dec in zip(digits, decimals.split())}
119 |
120 | spelledout = []
121 | for i, digit in enumerate(num):
122 | i = len(num) - i - 1
123 | if sino:
124 | if i == 0:
125 | name = digit2name.get(digit, '')
126 | elif i == 1:
127 | name = digit2name.get(digit, '') + '십'
128 | name = name.replace('일십', '십')
129 | else:
130 | if i == 0:
131 | name = digit2mod.get(digit, '')
132 | elif i == 1:
133 | name = digit2dec.get(digit, '')
134 | if digit == '0':
135 | if i % 4 == 0:
136 | last_three = spelledout[-min(3, len(spelledout)):]
137 | if ''.join(last_three) == '':
138 | spelledout.append('')
139 | continue
140 | else:
141 | spelledout.append('')
142 | continue
143 | if i == 2:
144 | name = digit2name.get(digit, '') + '백'
145 | name = name.replace('일백', '백')
146 | elif i == 3:
147 | name = digit2name.get(digit, '') + '천'
148 | name = name.replace('일천', '천')
149 | elif i == 4:
150 | name = digit2name.get(digit, '') + '만'
151 | name = name.replace('일만', '만')
152 | elif i == 5:
153 | name = digit2name.get(digit, '') + '십'
154 | name = name.replace('일십', '십')
155 | elif i == 6:
156 | name = digit2name.get(digit, '') + '백'
157 | name = name.replace('일백', '백')
158 | elif i == 7:
159 | name = digit2name.get(digit, '') + '천'
160 | name = name.replace('일천', '천')
161 | elif i == 8:
162 | name = digit2name.get(digit, '') + '억'
163 | elif i == 9:
164 | name = digit2name.get(digit, '') + '십'
165 | elif i == 10:
166 | name = digit2name.get(digit, '') + '백'
167 | elif i == 11:
168 | name = digit2name.get(digit, '') + '천'
169 | elif i == 12:
170 | name = digit2name.get(digit, '') + '조'
171 | elif i == 13:
172 | name = digit2name.get(digit, '') + '십'
173 | elif i == 14:
174 | name = digit2name.get(digit, '') + '백'
175 | elif i == 15:
176 | name = digit2name.get(digit, '') + '천'
177 | spelledout.append(name)
178 | return ''.join(elem for elem in spelledout)
179 |
180 |
181 | def number_to_hangul(text):
182 | '''Reference https://github.com/Kyubyong/g2pK'''
183 | tokens = set(re.findall(r'(\d[\d,]*)([\uac00-\ud71f]+)', text))
184 | for token in tokens:
185 | num, classifier = token
186 | if classifier[:2] in _korean_classifiers or classifier[0] in _korean_classifiers:
187 | spelledout = hangul_number(num, sino=False)
188 | else:
189 | spelledout = hangul_number(num, sino=True)
190 | text = text.replace(f'{num}{classifier}', f'{spelledout}{classifier}')
191 | # digit by digit for remaining digits
192 | digits = '0123456789'
193 | names = '영일이삼사오육칠팔구'
194 | for d, n in zip(digits, names):
195 | text = text.replace(d, n)
196 | return text
197 |
198 |
199 | def korean_to_lazy_ipa(text):
200 | text = latin_to_hangul(text)
201 | text = number_to_hangul(text)
202 | text=re.sub('[\uac00-\ud7af]+',lambda x:ko_pron.romanise(x.group(0),'ipa').split('] ~ [')[0],text)
203 | for regex, replacement in _ipa_to_lazy_ipa:
204 | text = re.sub(regex, replacement, text)
205 | return text
206 |
207 |
208 | def korean_to_ipa(text):
209 | text = korean_to_lazy_ipa(text)
210 | return text.replace('ʧ','tʃ').replace('ʥ','dʑ')
211 |
--------------------------------------------------------------------------------
/text/mandarin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import re
4 | from pypinyin import lazy_pinyin, BOPOMOFO
5 | import jieba
6 | import cn2an
7 | import logging
8 |
9 | logging.getLogger('jieba').setLevel(logging.WARNING)
10 | jieba.set_dictionary(r'./jieba/dict.txt')
11 | jieba.initialize()
12 |
13 |
14 | # List of (Latin alphabet, bopomofo) pairs:
15 | _latin_to_bopomofo = [(re.compile('%s' % x[0], re.IGNORECASE), x[1]) for x in [
16 | ('a', 'ㄟˉ'),
17 | ('b', 'ㄅㄧˋ'),
18 | ('c', 'ㄙㄧˉ'),
19 | ('d', 'ㄉㄧˋ'),
20 | ('e', 'ㄧˋ'),
21 | ('f', 'ㄝˊㄈㄨˋ'),
22 | ('g', 'ㄐㄧˋ'),
23 | ('h', 'ㄝˇㄑㄩˋ'),
24 | ('i', 'ㄞˋ'),
25 | ('j', 'ㄐㄟˋ'),
26 | ('k', 'ㄎㄟˋ'),
27 | ('l', 'ㄝˊㄛˋ'),
28 | ('m', 'ㄝˊㄇㄨˋ'),
29 | ('n', 'ㄣˉ'),
30 | ('o', 'ㄡˉ'),
31 | ('p', 'ㄆㄧˉ'),
32 | ('q', 'ㄎㄧㄡˉ'),
33 | ('r', 'ㄚˋ'),
34 | ('s', 'ㄝˊㄙˋ'),
35 | ('t', 'ㄊㄧˋ'),
36 | ('u', 'ㄧㄡˉ'),
37 | ('v', 'ㄨㄧˉ'),
38 | ('w', 'ㄉㄚˋㄅㄨˋㄌㄧㄡˋ'),
39 | ('x', 'ㄝˉㄎㄨˋㄙˋ'),
40 | ('y', 'ㄨㄞˋ'),
41 | ('z', 'ㄗㄟˋ')
42 | ]]
43 |
44 | # List of (bopomofo, romaji) pairs:
45 | _bopomofo_to_romaji = [(re.compile('%s' % x[0]), x[1]) for x in [
46 | ('ㄅㄛ', 'p⁼wo'),
47 | ('ㄆㄛ', 'pʰwo'),
48 | ('ㄇㄛ', 'mwo'),
49 | ('ㄈㄛ', 'fwo'),
50 | ('ㄅ', 'p⁼'),
51 | ('ㄆ', 'pʰ'),
52 | ('ㄇ', 'm'),
53 | ('ㄈ', 'f'),
54 | ('ㄉ', 't⁼'),
55 | ('ㄊ', 'tʰ'),
56 | ('ㄋ', 'n'),
57 | ('ㄌ', 'l'),
58 | ('ㄍ', 'k⁼'),
59 | ('ㄎ', 'kʰ'),
60 | ('ㄏ', 'h'),
61 | ('ㄐ', 'ʧ⁼'),
62 | ('ㄑ', 'ʧʰ'),
63 | ('ㄒ', 'ʃ'),
64 | ('ㄓ', 'ʦ`⁼'),
65 | ('ㄔ', 'ʦ`ʰ'),
66 | ('ㄕ', 's`'),
67 | ('ㄖ', 'ɹ`'),
68 | ('ㄗ', 'ʦ⁼'),
69 | ('ㄘ', 'ʦʰ'),
70 | ('ㄙ', 's'),
71 | ('ㄚ', 'a'),
72 | ('ㄛ', 'o'),
73 | ('ㄜ', 'ə'),
74 | ('ㄝ', 'e'),
75 | ('ㄞ', 'ai'),
76 | ('ㄟ', 'ei'),
77 | ('ㄠ', 'au'),
78 | ('ㄡ', 'ou'),
79 | ('ㄧㄢ', 'yeNN'),
80 | ('ㄢ', 'aNN'),
81 | ('ㄧㄣ', 'iNN'),
82 | ('ㄣ', 'əNN'),
83 | ('ㄤ', 'aNg'),
84 | ('ㄧㄥ', 'iNg'),
85 | ('ㄨㄥ', 'uNg'),
86 | ('ㄩㄥ', 'yuNg'),
87 | ('ㄥ', 'əNg'),
88 | ('ㄦ', 'əɻ'),
89 | ('ㄧ', 'i'),
90 | ('ㄨ', 'u'),
91 | ('ㄩ', 'ɥ'),
92 | ('ˉ', '→'),
93 | ('ˊ', '↑'),
94 | ('ˇ', '↓↑'),
95 | ('ˋ', '↓'),
96 | ('˙', ''),
97 | (',', ','),
98 | ('。', '.'),
99 | ('!', '!'),
100 | ('?', '?'),
101 | ('—', '-')
102 | ]]
103 |
104 | # List of (romaji, ipa) pairs:
105 | _romaji_to_ipa = [(re.compile('%s' % x[0], re.IGNORECASE), x[1]) for x in [
106 | ('ʃy', 'ʃ'),
107 | ('ʧʰy', 'ʧʰ'),
108 | ('ʧ⁼y', 'ʧ⁼'),
109 | ('NN', 'n'),
110 | ('Ng', 'ŋ'),
111 | ('y', 'j'),
112 | ('h', 'x')
113 | ]]
114 |
115 | # List of (bopomofo, ipa) pairs:
116 | _bopomofo_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
117 | ('ㄅㄛ', 'p⁼wo'),
118 | ('ㄆㄛ', 'pʰwo'),
119 | ('ㄇㄛ', 'mwo'),
120 | ('ㄈㄛ', 'fwo'),
121 | ('ㄅ', 'p⁼'),
122 | ('ㄆ', 'pʰ'),
123 | ('ㄇ', 'm'),
124 | ('ㄈ', 'f'),
125 | ('ㄉ', 't⁼'),
126 | ('ㄊ', 'tʰ'),
127 | ('ㄋ', 'n'),
128 | ('ㄌ', 'l'),
129 | ('ㄍ', 'k⁼'),
130 | ('ㄎ', 'kʰ'),
131 | ('ㄏ', 'x'),
132 | ('ㄐ', 'tʃ⁼'),
133 | ('ㄑ', 'tʃʰ'),
134 | ('ㄒ', 'ʃ'),
135 | ('ㄓ', 'ts`⁼'),
136 | ('ㄔ', 'ts`ʰ'),
137 | ('ㄕ', 's`'),
138 | ('ㄖ', 'ɹ`'),
139 | ('ㄗ', 'ts⁼'),
140 | ('ㄘ', 'tsʰ'),
141 | ('ㄙ', 's'),
142 | ('ㄚ', 'a'),
143 | ('ㄛ', 'o'),
144 | ('ㄜ', 'ə'),
145 | ('ㄝ', 'ɛ'),
146 | ('ㄞ', 'aɪ'),
147 | ('ㄟ', 'eɪ'),
148 | ('ㄠ', 'ɑʊ'),
149 | ('ㄡ', 'oʊ'),
150 | ('ㄧㄢ', 'jɛn'),
151 | ('ㄩㄢ', 'ɥæn'),
152 | ('ㄢ', 'an'),
153 | ('ㄧㄣ', 'in'),
154 | ('ㄩㄣ', 'ɥn'),
155 | ('ㄣ', 'ən'),
156 | ('ㄤ', 'ɑŋ'),
157 | ('ㄧㄥ', 'iŋ'),
158 | ('ㄨㄥ', 'ʊŋ'),
159 | ('ㄩㄥ', 'jʊŋ'),
160 | ('ㄥ', 'əŋ'),
161 | ('ㄦ', 'əɻ'),
162 | ('ㄧ', 'i'),
163 | ('ㄨ', 'u'),
164 | ('ㄩ', 'ɥ'),
165 | ('ˉ', '→'),
166 | ('ˊ', '↑'),
167 | ('ˇ', '↓↑'),
168 | ('ˋ', '↓'),
169 | ('˙', ''),
170 | (',', ','),
171 | ('。', '.'),
172 | ('!', '!'),
173 | ('?', '?'),
174 | ('—', '-')
175 | ]]
176 |
177 | # List of (bopomofo, ipa2) pairs:
178 | _bopomofo_to_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [
179 | ('ㄅㄛ', 'pwo'),
180 | ('ㄆㄛ', 'pʰwo'),
181 | ('ㄇㄛ', 'mwo'),
182 | ('ㄈㄛ', 'fwo'),
183 | ('ㄅ', 'p'),
184 | ('ㄆ', 'pʰ'),
185 | ('ㄇ', 'm'),
186 | ('ㄈ', 'f'),
187 | ('ㄉ', 't'),
188 | ('ㄊ', 'tʰ'),
189 | ('ㄋ', 'n'),
190 | ('ㄌ', 'l'),
191 | ('ㄍ', 'k'),
192 | ('ㄎ', 'kʰ'),
193 | ('ㄏ', 'h'),
194 | ('ㄐ', 'tɕ'),
195 | ('ㄑ', 'tɕʰ'),
196 | ('ㄒ', 'ɕ'),
197 | ('ㄓ', 'tʂ'),
198 | ('ㄔ', 'tʂʰ'),
199 | ('ㄕ', 'ʂ'),
200 | ('ㄖ', 'ɻ'),
201 | ('ㄗ', 'ts'),
202 | ('ㄘ', 'tsʰ'),
203 | ('ㄙ', 's'),
204 | ('ㄚ', 'a'),
205 | ('ㄛ', 'o'),
206 | ('ㄜ', 'ɤ'),
207 | ('ㄝ', 'ɛ'),
208 | ('ㄞ', 'aɪ'),
209 | ('ㄟ', 'eɪ'),
210 | ('ㄠ', 'ɑʊ'),
211 | ('ㄡ', 'oʊ'),
212 | ('ㄧㄢ', 'jɛn'),
213 | ('ㄩㄢ', 'yæn'),
214 | ('ㄢ', 'an'),
215 | ('ㄧㄣ', 'in'),
216 | ('ㄩㄣ', 'yn'),
217 | ('ㄣ', 'ən'),
218 | ('ㄤ', 'ɑŋ'),
219 | ('ㄧㄥ', 'iŋ'),
220 | ('ㄨㄥ', 'ʊŋ'),
221 | ('ㄩㄥ', 'jʊŋ'),
222 | ('ㄥ', 'ɤŋ'),
223 | ('ㄦ', 'əɻ'),
224 | ('ㄧ', 'i'),
225 | ('ㄨ', 'u'),
226 | ('ㄩ', 'y'),
227 | ('ˉ', '˥'),
228 | ('ˊ', '˧˥'),
229 | ('ˇ', '˨˩˦'),
230 | ('ˋ', '˥˩'),
231 | ('˙', ''),
232 | (',', ','),
233 | ('。', '.'),
234 | ('!', '!'),
235 | ('?', '?'),
236 | ('—', '-')
237 | ]]
238 |
239 |
240 | def number_to_chinese(text):
241 | numbers = re.findall(r'\d+(?:\.?\d+)?', text)
242 | for number in numbers:
243 | text = text.replace(number, cn2an.an2cn(number), 1)
244 | return text
245 |
246 |
247 | def chinese_to_bopomofo(text):
248 | text = text.replace('、', ',').replace(';', ',').replace(':', ',')
249 | words = jieba.lcut(text, cut_all=False)
250 | text = ''
251 | for word in words:
252 | bopomofos = lazy_pinyin(word, BOPOMOFO)
253 | if not re.search('[\u4e00-\u9fff]', word):
254 | text += word
255 | continue
256 | for i in range(len(bopomofos)):
257 | bopomofos[i] = re.sub(r'([\u3105-\u3129])$', r'\1ˉ', bopomofos[i])
258 | if text != '':
259 | text += ' '
260 | text += ''.join(bopomofos)
261 | return text
262 |
263 |
264 | def latin_to_bopomofo(text):
265 | for regex, replacement in _latin_to_bopomofo:
266 | text = re.sub(regex, replacement, text)
267 | return text
268 |
269 |
270 | def bopomofo_to_romaji(text):
271 | for regex, replacement in _bopomofo_to_romaji:
272 | text = re.sub(regex, replacement, text)
273 | return text
274 |
275 |
276 | def bopomofo_to_ipa(text):
277 | for regex, replacement in _bopomofo_to_ipa:
278 | text = re.sub(regex, replacement, text)
279 | return text
280 |
281 |
282 | def bopomofo_to_ipa2(text):
283 | for regex, replacement in _bopomofo_to_ipa2:
284 | text = re.sub(regex, replacement, text)
285 | return text
286 |
287 |
288 | def chinese_to_romaji(text):
289 | text = number_to_chinese(text)
290 | text = chinese_to_bopomofo(text)
291 | text = latin_to_bopomofo(text)
292 | text = bopomofo_to_romaji(text)
293 | text = re.sub('i([aoe])', r'y\1', text)
294 | text = re.sub('u([aoəe])', r'w\1', text)
295 | text = re.sub('([ʦsɹ]`[⁼ʰ]?)([→↓↑ ]+|$)',
296 | r'\1ɹ`\2', text).replace('ɻ', 'ɹ`')
297 | text = re.sub('([ʦs][⁼ʰ]?)([→↓↑ ]+|$)', r'\1ɹ\2', text)
298 | return text
299 |
300 |
301 | def chinese_to_lazy_ipa(text):
302 | text = chinese_to_romaji(text)
303 | for regex, replacement in _romaji_to_ipa:
304 | text = re.sub(regex, replacement, text)
305 | return text
306 |
307 |
308 | def chinese_to_ipa(text):
309 | text = number_to_chinese(text)
310 | text = chinese_to_bopomofo(text)
311 | text = latin_to_bopomofo(text)
312 | text = bopomofo_to_ipa(text)
313 | text = re.sub('i([aoe])', r'j\1', text)
314 | text = re.sub('u([aoəe])', r'w\1', text)
315 | text = re.sub('([sɹ]`[⁼ʰ]?)([→↓↑ ]+|$)',
316 | r'\1ɹ`\2', text).replace('ɻ', 'ɹ`')
317 | text = re.sub('([s][⁼ʰ]?)([→↓↑ ]+|$)', r'\1ɹ\2', text)
318 | return text
319 |
320 |
321 | def chinese_to_ipa2(text):
322 | text = number_to_chinese(text)
323 | text = chinese_to_bopomofo(text)
324 | text = latin_to_bopomofo(text)
325 | text = bopomofo_to_ipa2(text)
326 | text = re.sub(r'i([aoe])', r'j\1', text)
327 | text = re.sub(r'u([aoəe])', r'w\1', text)
328 | text = re.sub(r'([ʂɹ]ʰ?)([˩˨˧˦˥ ]+|$)', r'\1ʅ\2', text)
329 | text = re.sub(r'(sʰ?)([˩˨˧˦˥ ]+|$)', r'\1ɿ\2', text)
330 | return text
331 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
364 |
365 | # build
366 | build
367 | monotonic_align/core.c
368 | *.o
369 | *.so
370 | *.dll
371 |
372 | # data
373 | /config.json
374 | /*.pth
375 | *.wav
376 | /monotonic_align/monotonic_align
377 | /resources
378 | /MoeGoe.spec
379 | /dist/MoeGoe
380 | /dist
381 |
382 | # MacOS
383 | .DS_Store
384 |
385 | # 가상환경
386 | .venv/
387 |
388 | # 개인 기록
389 | userfile/log/*
390 | userfile/tts/*
391 | output.wav
392 | test.ogg
393 | log.txt
394 |
395 | # 테스트용
396 | *.ipynb
397 |
398 | # 렌파이 생성 파일
399 | *.rpyc
400 | ChatWithGPT/game/saves/
401 | ChatWithGPT/game/cache/
402 | ChatWithGPT/game/Resources/*
403 | !ChatWithGPT/game/Resources/Hiyori/
404 |
--------------------------------------------------------------------------------
/hubert_model.py:
--------------------------------------------------------------------------------
1 | import copy
2 | from typing import Optional, Tuple
3 | import random
4 |
5 | import torch
6 | import torch.nn as nn
7 | import torch.nn.functional as F
8 | from torch.nn.modules.utils import consume_prefix_in_state_dict_if_present
9 |
10 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
11 |
12 | class Hubert(nn.Module):
13 | def __init__(self, num_label_embeddings: int = 100, mask: bool = True):
14 | super().__init__()
15 | self._mask = mask
16 | self.feature_extractor = FeatureExtractor().to(device)
17 | self.feature_projection = FeatureProjection().to(device)
18 | self.positional_embedding = PositionalConvEmbedding().to(device)
19 | self.norm = nn.LayerNorm(768).to(device)
20 | self.dropout = nn.Dropout(0.1).to(device)
21 | self.encoder = TransformerEncoder(
22 | nn.TransformerEncoderLayer(
23 | 768, 12, 3072, activation="gelu", batch_first=True
24 | ),
25 | 12,
26 | ).to(device)
27 | self.proj = nn.Linear(768, 256).to(device)
28 |
29 | self.masked_spec_embed = nn.Parameter(torch.cuda.FloatTensor(768).uniform_())
30 | self.label_embedding = nn.Embedding(num_label_embeddings, 256).to(device)
31 |
32 | def mask(self, x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
33 | mask = None
34 | if self.training and self._mask:
35 | mask = _compute_mask((x.size(0), x.size(1)), 0.8, 10, x.device, 2)
36 | x[mask] = self.masked_spec_embed.to(x.dtype)
37 | return x, mask
38 |
39 | def encode(
40 | self, x: torch.Tensor, layer: Optional[int] = None
41 | ) -> Tuple[torch.Tensor, torch.Tensor]:
42 | x = self.feature_extractor(x.to(device))
43 | x = self.feature_projection(x.transpose(1, 2))
44 | x, mask = self.mask(x)
45 | x = x + self.positional_embedding(x)
46 | x = self.dropout(self.norm(x))
47 | x = self.encoder(x, output_layer=layer)
48 | return x, mask
49 |
50 | def logits(self, x: torch.Tensor) -> torch.Tensor:
51 | logits = torch.cosine_similarity(
52 | x.unsqueeze(2),
53 | self.label_embedding.weight.unsqueeze(0).unsqueeze(0),
54 | dim=-1,
55 | )
56 | return logits / 0.1
57 |
58 | def forward(self, x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
59 | x, mask = self.encode(x.to(device))
60 | x = self.proj(x)
61 | logits = self.logits(x)
62 | return logits, mask
63 |
64 |
65 | class HubertSoft(Hubert):
66 | def __init__(self):
67 | super().__init__()
68 |
69 | @torch.jit.script
70 | @torch.jit.unused
71 | def units(self, wav: torch.Tensor) -> torch.Tensor:
72 | wav = F.pad(wav, ((400 - 320) // 2, (400 - 320) // 2))
73 | x, _ = self.encode(wav.to(device))
74 | return self.proj(x)
75 |
76 |
77 | class FeatureExtractor(nn.Module):
78 | def __init__(self):
79 | super().__init__()
80 | self.conv0 = nn.Conv1d(1, 512, 10, 5, bias=False)
81 | self.norm0 = nn.GroupNorm(512, 512)
82 | self.conv1 = nn.Conv1d(512, 512, 3, 2, bias=False)
83 | self.conv2 = nn.Conv1d(512, 512, 3, 2, bias=False)
84 | self.conv3 = nn.Conv1d(512, 512, 3, 2, bias=False)
85 | self.conv4 = nn.Conv1d(512, 512, 3, 2, bias=False)
86 | self.conv5 = nn.Conv1d(512, 512, 2, 2, bias=False)
87 | self.conv6 = nn.Conv1d(512, 512, 2, 2, bias=False)
88 |
89 | def forward(self, x: torch.Tensor) -> torch.Tensor:
90 | x = F.gelu(self.norm0(self.conv0(x.to(device))))
91 | x = F.gelu(self.conv1(x))
92 | x = F.gelu(self.conv2(x))
93 | x = F.gelu(self.conv3(x))
94 | x = F.gelu(self.conv4(x))
95 | x = F.gelu(self.conv5(x))
96 | x = F.gelu(self.conv6(x))
97 | return x
98 |
99 |
100 | class FeatureProjection(nn.Module):
101 | def __init__(self):
102 | super().__init__()
103 | self.norm = nn.LayerNorm(512)
104 | self.projection = nn.Linear(512, 768)
105 | self.dropout = nn.Dropout(0.1)
106 |
107 | def forward(self, x: torch.Tensor) -> torch.Tensor:
108 | x = self.norm(x.to(device))
109 | x = self.projection(x)
110 | x = self.dropout(x)
111 | return x
112 |
113 |
114 | class PositionalConvEmbedding(nn.Module):
115 | def __init__(self):
116 | super().__init__()
117 | self.conv = nn.Conv1d(
118 | 768,
119 | 768,
120 | kernel_size=128,
121 | padding=128 // 2,
122 | groups=16,
123 | )
124 | self.conv = nn.utils.weight_norm(self.conv.to(device), name="weight", dim=2)
125 |
126 | def forward(self, x: torch.Tensor) -> torch.Tensor:
127 | x = self.conv(x.transpose(1, 2))
128 | x = F.gelu(x[:, :, :-1])
129 | return x.transpose(1, 2)
130 |
131 |
132 | class TransformerEncoder(nn.Module):
133 | def __init__(
134 | self, encoder_layer: nn.TransformerEncoderLayer, num_layers: int
135 | ) -> None:
136 | super(TransformerEncoder, self).__init__()
137 | self.layers = nn.ModuleList(
138 | [copy.deepcopy(encoder_layer) for _ in range(num_layers)]
139 | )
140 | self.num_layers = num_layers
141 |
142 | def forward(
143 | self,
144 | src: torch.Tensor,
145 | mask: torch.Tensor = None,
146 | src_key_padding_mask: torch.Tensor = None,
147 | output_layer: Optional[int] = None,
148 | ) -> torch.Tensor:
149 | output = src.to(device)
150 | if mask is not None:
151 | mask = mask.to(device)
152 | if src_key_padding_mask is not None:
153 | src_key_padding_mask = src_key_padding_mask.to(device)
154 | for layer in self.layers[:output_layer]:
155 | output = layer(
156 | output.to(device), src_mask=mask, src_key_padding_mask=src_key_padding_mask
157 | )
158 | return output
159 |
160 |
161 | def _compute_mask(
162 | shape: Tuple[int, int],
163 | mask_prob: float,
164 | mask_length: int,
165 | device: torch.device,
166 | min_masks: int = 0,
167 | ) -> torch.Tensor:
168 | batch_size, sequence_length = shape
169 |
170 | if mask_length < 1:
171 | raise ValueError("`mask_length` has to be bigger than 0.")
172 |
173 | if mask_length > sequence_length:
174 | raise ValueError(
175 | f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and `sequence_length`: {sequence_length}`"
176 | )
177 |
178 | # compute number of masked spans in batch
179 | num_masked_spans = int(mask_prob * sequence_length / mask_length + random.random())
180 | num_masked_spans = max(num_masked_spans, min_masks)
181 |
182 | # make sure num masked indices <= sequence_length
183 | if num_masked_spans * mask_length > sequence_length:
184 | num_masked_spans = sequence_length // mask_length
185 |
186 | # SpecAugment mask to fill
187 | mask = torch.zeros((batch_size, sequence_length), device=device, dtype=torch.bool)
188 |
189 | # uniform distribution to sample from, make sure that offset samples are < sequence_length
190 | uniform_dist = torch.ones(
191 | (batch_size, sequence_length - (mask_length - 1)), device=device
192 | )
193 |
194 | # get random indices to mask
195 | mask_indices = torch.multinomial(uniform_dist, num_masked_spans)
196 |
197 | # expand masked indices to masked spans
198 | mask_indices = (
199 | mask_indices.unsqueeze(dim=-1)
200 | .expand((batch_size, num_masked_spans, mask_length))
201 | .reshape(batch_size, num_masked_spans * mask_length)
202 | )
203 | offsets = (
204 | torch.arange(mask_length, device=device)[None, None, :]
205 | .expand((batch_size, num_masked_spans, mask_length))
206 | .reshape(batch_size, num_masked_spans * mask_length)
207 | )
208 | mask_idxs = mask_indices + offsets
209 |
210 | # scatter indices to mask
211 | mask = mask.scatter(1, mask_idxs, True)
212 |
213 | return mask.to(torch.bool)
214 |
215 |
216 | def hubert_soft(path: str) -> HubertSoft:
217 | r"""HuBERT-Soft from `"A Comparison of Discrete and Soft Speech Units for Improved Voice Conversion"`.
218 | Args:
219 | path (str): path of a pretrained model
220 | """
221 | hubert = HubertSoft()
222 | checkpoint = torch.load(path, map_location=device)
223 | consume_prefix_in_state_dict_if_present(checkpoint, "module.")
224 | hubert.load_state_dict(checkpoint)
225 | hubert.to(device)
226 | hubert.eval()
227 | return hubert
--------------------------------------------------------------------------------
/transforms.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.nn import functional as F
3 |
4 | import numpy as np
5 |
6 |
7 | DEFAULT_MIN_BIN_WIDTH = 1e-3
8 | DEFAULT_MIN_BIN_HEIGHT = 1e-3
9 | DEFAULT_MIN_DERIVATIVE = 1e-3
10 |
11 |
12 | def piecewise_rational_quadratic_transform(inputs,
13 | unnormalized_widths,
14 | unnormalized_heights,
15 | unnormalized_derivatives,
16 | inverse=False,
17 | tails=None,
18 | tail_bound=1.,
19 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
20 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
21 | min_derivative=DEFAULT_MIN_DERIVATIVE):
22 |
23 | if tails is None:
24 | spline_fn = rational_quadratic_spline
25 | spline_kwargs = {}
26 | else:
27 | spline_fn = unconstrained_rational_quadratic_spline
28 | spline_kwargs = {
29 | 'tails': tails,
30 | 'tail_bound': tail_bound
31 | }
32 |
33 | outputs, logabsdet = spline_fn(
34 | inputs=inputs,
35 | unnormalized_widths=unnormalized_widths,
36 | unnormalized_heights=unnormalized_heights,
37 | unnormalized_derivatives=unnormalized_derivatives,
38 | inverse=inverse,
39 | min_bin_width=min_bin_width,
40 | min_bin_height=min_bin_height,
41 | min_derivative=min_derivative,
42 | **spline_kwargs
43 | )
44 | return outputs, logabsdet
45 |
46 |
47 | def searchsorted(bin_locations, inputs, eps=1e-6):
48 | bin_locations[..., -1] += eps
49 | return torch.sum(
50 | inputs[..., None] >= bin_locations,
51 | dim=-1
52 | ) - 1
53 |
54 |
55 | def unconstrained_rational_quadratic_spline(inputs,
56 | unnormalized_widths,
57 | unnormalized_heights,
58 | unnormalized_derivatives,
59 | inverse=False,
60 | tails='linear',
61 | tail_bound=1.,
62 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
63 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
64 | min_derivative=DEFAULT_MIN_DERIVATIVE):
65 | inside_interval_mask = (inputs >= -tail_bound) & (inputs <= tail_bound)
66 | outside_interval_mask = ~inside_interval_mask
67 |
68 | outputs = torch.zeros_like(inputs)
69 | logabsdet = torch.zeros_like(inputs)
70 |
71 | if tails == 'linear':
72 | unnormalized_derivatives = F.pad(unnormalized_derivatives, pad=(1, 1))
73 | constant = np.log(np.exp(1 - min_derivative) - 1)
74 | unnormalized_derivatives[..., 0] = constant
75 | unnormalized_derivatives[..., -1] = constant
76 |
77 | outputs[outside_interval_mask] = inputs[outside_interval_mask]
78 | logabsdet[outside_interval_mask] = 0
79 | else:
80 | raise RuntimeError('{} tails are not implemented.'.format(tails))
81 |
82 | outputs[inside_interval_mask], logabsdet[inside_interval_mask] = rational_quadratic_spline(
83 | inputs=inputs[inside_interval_mask],
84 | unnormalized_widths=unnormalized_widths[inside_interval_mask, :],
85 | unnormalized_heights=unnormalized_heights[inside_interval_mask, :],
86 | unnormalized_derivatives=unnormalized_derivatives[inside_interval_mask, :],
87 | inverse=inverse,
88 | left=-tail_bound, right=tail_bound, bottom=-tail_bound, top=tail_bound,
89 | min_bin_width=min_bin_width,
90 | min_bin_height=min_bin_height,
91 | min_derivative=min_derivative
92 | )
93 |
94 | return outputs, logabsdet
95 |
96 | def rational_quadratic_spline(inputs,
97 | unnormalized_widths,
98 | unnormalized_heights,
99 | unnormalized_derivatives,
100 | inverse=False,
101 | left=0., right=1., bottom=0., top=1.,
102 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
103 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
104 | min_derivative=DEFAULT_MIN_DERIVATIVE):
105 | if torch.min(inputs) < left or torch.max(inputs) > right:
106 | raise ValueError('Input to a transform is not within its domain')
107 |
108 | num_bins = unnormalized_widths.shape[-1]
109 |
110 | if min_bin_width * num_bins > 1.0:
111 | raise ValueError('Minimal bin width too large for the number of bins')
112 | if min_bin_height * num_bins > 1.0:
113 | raise ValueError('Minimal bin height too large for the number of bins')
114 |
115 | widths = F.softmax(unnormalized_widths, dim=-1)
116 | widths = min_bin_width + (1 - min_bin_width * num_bins) * widths
117 | cumwidths = torch.cumsum(widths, dim=-1)
118 | cumwidths = F.pad(cumwidths, pad=(1, 0), mode='constant', value=0.0)
119 | cumwidths = (right - left) * cumwidths + left
120 | cumwidths[..., 0] = left
121 | cumwidths[..., -1] = right
122 | widths = cumwidths[..., 1:] - cumwidths[..., :-1]
123 |
124 | derivatives = min_derivative + F.softplus(unnormalized_derivatives)
125 |
126 | heights = F.softmax(unnormalized_heights, dim=-1)
127 | heights = min_bin_height + (1 - min_bin_height * num_bins) * heights
128 | cumheights = torch.cumsum(heights, dim=-1)
129 | cumheights = F.pad(cumheights, pad=(1, 0), mode='constant', value=0.0)
130 | cumheights = (top - bottom) * cumheights + bottom
131 | cumheights[..., 0] = bottom
132 | cumheights[..., -1] = top
133 | heights = cumheights[..., 1:] - cumheights[..., :-1]
134 |
135 | if inverse:
136 | bin_idx = searchsorted(cumheights, inputs)[..., None]
137 | else:
138 | bin_idx = searchsorted(cumwidths, inputs)[..., None]
139 |
140 | input_cumwidths = cumwidths.gather(-1, bin_idx)[..., 0]
141 | input_bin_widths = widths.gather(-1, bin_idx)[..., 0]
142 |
143 | input_cumheights = cumheights.gather(-1, bin_idx)[..., 0]
144 | delta = heights / widths
145 | input_delta = delta.gather(-1, bin_idx)[..., 0]
146 |
147 | input_derivatives = derivatives.gather(-1, bin_idx)[..., 0]
148 | input_derivatives_plus_one = derivatives[..., 1:].gather(-1, bin_idx)[..., 0]
149 |
150 | input_heights = heights.gather(-1, bin_idx)[..., 0]
151 |
152 | if inverse:
153 | a = (((inputs - input_cumheights) * (input_derivatives
154 | + input_derivatives_plus_one
155 | - 2 * input_delta)
156 | + input_heights * (input_delta - input_derivatives)))
157 | b = (input_heights * input_derivatives
158 | - (inputs - input_cumheights) * (input_derivatives
159 | + input_derivatives_plus_one
160 | - 2 * input_delta))
161 | c = - input_delta * (inputs - input_cumheights)
162 |
163 | discriminant = b.pow(2) - 4 * a * c
164 | assert (discriminant >= 0).all()
165 |
166 | root = (2 * c) / (-b - torch.sqrt(discriminant))
167 | outputs = root * input_bin_widths + input_cumwidths
168 |
169 | theta_one_minus_theta = root * (1 - root)
170 | denominator = input_delta + ((input_derivatives + input_derivatives_plus_one - 2 * input_delta)
171 | * theta_one_minus_theta)
172 | derivative_numerator = input_delta.pow(2) * (input_derivatives_plus_one * root.pow(2)
173 | + 2 * input_delta * theta_one_minus_theta
174 | + input_derivatives * (1 - root).pow(2))
175 | logabsdet = torch.log(derivative_numerator) - 2 * torch.log(denominator)
176 |
177 | return outputs, -logabsdet
178 | else:
179 | theta = (inputs - input_cumwidths) / input_bin_widths
180 | theta_one_minus_theta = theta * (1 - theta)
181 |
182 | numerator = input_heights * (input_delta * theta.pow(2)
183 | + input_derivatives * theta_one_minus_theta)
184 | denominator = input_delta + ((input_derivatives + input_derivatives_plus_one - 2 * input_delta)
185 | * theta_one_minus_theta)
186 | outputs = input_cumheights + numerator / denominator
187 |
188 | derivative_numerator = input_delta.pow(2) * (input_derivatives_plus_one * theta.pow(2)
189 | + 2 * input_delta * theta_one_minus_theta
190 | + input_derivatives * (1 - theta).pow(2))
191 | logabsdet = torch.log(derivative_numerator) - 2 * torch.log(denominator)
192 |
193 | return outputs, logabsdet
194 |
--------------------------------------------------------------------------------
/server.py:
--------------------------------------------------------------------------------
1 | from scipy.io.wavfile import write
2 | from text import text_to_sequence
3 | from models import SynthesizerTrn
4 | import utils
5 | import commons
6 | import sys
7 | import re
8 | from pydub import AudioSegment
9 | import torch
10 | from torch import no_grad, LongTensor
11 | import logging
12 | import argparse
13 | import requests
14 | import json
15 | import os
16 | import openai
17 | import socket
18 | from navertts import NaverTTS
19 | import datetime
20 | import glob
21 |
22 | class SocketServer:
23 | def __init__(self, host, port):
24 | self.host = host
25 | self.port = port
26 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
27 |
28 | def start(self):
29 | self.socket.bind((self.host, self.port))
30 | self.socket.listen(5)
31 | self.client, self.addr = self.socket.accept()
32 |
33 | def receive(self):
34 | total_data = b""
35 | while True:
36 | data = self.client.recv(1024)
37 | total_data += data
38 | if len(data) < 1024:
39 | break
40 | return total_data.decode()
41 |
42 | def send(self, data):
43 | self.client.send(data.encode())
44 |
45 | def stop(self):
46 | self.socket.close()
47 |
48 | class vits():
49 | def __init__(self, model, config):
50 | logging.getLogger('numba').setLevel(logging.WARNING)
51 | self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
52 |
53 | hps_ms = utils.get_hparams_from_file(config)
54 | n_speakers = hps_ms.data.n_speakers if 'n_speakers' in hps_ms.data.keys() else 0
55 | self.n_symbols = len(hps_ms.symbols) if 'symbols' in hps_ms.keys() else 0
56 |
57 | self.net_g_ms = SynthesizerTrn(
58 | self.n_symbols,
59 | hps_ms.data.filter_length // 2 + 1,
60 | hps_ms.train.segment_size // hps_ms.data.hop_length,
61 | n_speakers=n_speakers,
62 | **hps_ms.model).to(self.device)
63 | _ = self.net_g_ms.eval()
64 | self.hps_ms = hps_ms
65 | utils.load_checkpoint(model, self.net_g_ms)
66 |
67 | def get_text(self, text, hps, cleaned=False):
68 | if cleaned:
69 | text_norm = text_to_sequence(text, hps.symbols, [])
70 | else:
71 | text_norm = text_to_sequence(text, hps.symbols, hps.data.text_cleaners)
72 | if hps.data.add_blank:
73 | text_norm = commons.intersperse(text_norm, 0)
74 | text_norm = LongTensor(text_norm)
75 | return text_norm
76 |
77 | def get_label_value(self, text, label, default, warning_name='value'):
78 | value = re.search(rf'\[{label}=(.+?)\]', text)
79 | if value:
80 | try:
81 | text = re.sub(rf'\[{label}=(.+?)\]', '', text, 1)
82 | value = float(value.group(1))
83 | except:
84 | print(f'Invalid {warning_name}!')
85 | sys.exit(1)
86 | else:
87 | value = default
88 | return value, text
89 |
90 |
91 | def get_label(self, text, label):
92 | if f'[{label}]' in text:
93 | return True, text.replace(f'[{label}]', '')
94 | else:
95 | return False, text
96 |
97 | def generateSound(self, inputString, id):
98 | if self.n_symbols != 0:
99 | text = inputString
100 |
101 | length_scale, text = self.get_label_value(
102 | text, 'LENGTH', 1, 'length scale')
103 | noise_scale, text = self.get_label_value(
104 | text, 'NOISE', 0.667, 'noise scale')
105 | noise_scale_w, text = self.get_label_value(
106 | text, 'NOISEW', 0.8, 'deviation of noise')
107 | cleaned, text = self.get_label(text, 'CLEANED')
108 |
109 | stn_tst = self.get_text(text, self.hps_ms, cleaned=cleaned)
110 |
111 | speaker_id = id
112 | out_path = "./output.wav"
113 | with no_grad():
114 | x_tst = stn_tst.unsqueeze(0).to(self.device)
115 | x_tst_lengths = LongTensor([stn_tst.size(0)]).to(self.device)
116 | sid = LongTensor([speaker_id]).to(self.device)
117 | audio = self.net_g_ms.infer(x_tst, x_tst_lengths, sid=sid, noise_scale=noise_scale,
118 | noise_scale_w=noise_scale_w, length_scale=length_scale)[0][0, 0].data.to(self.device).cpu().float().numpy()
119 |
120 | write(out_path, self.hps_ms.data.sampling_rate, audio)
121 | print('Successfully saved!')
122 | # torch.cuda.empty_cache()
123 | return out_path
124 |
125 | get_dir = lambda x: os.path.split(os.path.realpath(x))[0]
126 |
127 | def download_file(url, save_dir):
128 | local_filename = url.split('/')[-1]
129 | r = requests.get(url, stream=True)
130 | with open(os.path.join(save_dir, local_filename), 'wb') as f:
131 | for chunk in r.iter_content(chunk_size=1024):
132 | if chunk: # filter out keep-alive new chunks
133 | f.write(chunk)
134 | return local_filename
135 |
136 | class openai_session():
137 | def __init__(self, api_key):
138 | self.api_key = api_key
139 | openai.api_key = api_key
140 | self.messages = []
141 | self.model = "gpt-3.5-turbo"
142 | self.currunt_log = f"userfile/log/{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.json"
143 | if not os.path.exists("userfile/log"):
144 | os.makedirs("userfile/log")
145 |
146 | def save(self):
147 | with open(self.currunt_log, 'w', encoding='utf-8') as f:
148 | data = json.dumps(self.messages, ensure_ascii=False, indent=4)
149 | f.write(data)
150 |
151 | def set_role(self, role):
152 | prefix = "이제부터 당신은 다음과 같은 역할을 맡아 대화를 진행합니다: \n"
153 | self.messages.append({"role": "system", "content": prefix + role})
154 |
155 | def set_greeting(self, greeting):
156 | self.messages.append({"role": "assistant", "content": greeting})
157 |
158 | def send_message(self, message):
159 | try:
160 | self.messages.append({"role": "user", "content": message})
161 | res = openai.ChatCompletion.create(
162 | model=self.model,
163 | messages=self.messages if len(self.messages) <= 30 else [self.messages[0]] + self.messages[-9:],
164 | )
165 | answer = res['choices'][0]['message']['content']
166 | self.messages.append({"role": "assistant", "content": answer})
167 | self.save()
168 | except Exception as e:
169 | answer = "앗.. 뭐라고 하셨었죠? 다시 한번 말씀해 주실 수 있나요?"
170 | print("에러 발생: " + str(e))
171 |
172 | return answer
173 |
174 | class navertts():
175 | def generateSound(self, inputString, id):
176 | output_path = "./output.mp3"
177 | tts = NaverTTS(inputString, lang='ko')
178 | tts.save(output_path)
179 | print('Successfully saved!')
180 | return output_path
181 |
182 | def main():
183 | server = SocketServer("127.0.0.1", 9000)
184 | print("렌파이 클라이언트와 연결 대기중...")
185 | server.start()
186 |
187 | print("렌파이 클라이언트와 연결되었습니다.")
188 |
189 | tts_service = int(server.receive()) # 0: 로컬 vits, 1: 네이버
190 |
191 | if tts_service == 0:
192 | korean_model_path = r"userfile\tts\model.pth"
193 | korean_config_path = r"userfile\tts\config.json"
194 |
195 | if not os.path.isfile(korean_model_path):
196 | os.makedirs(get_dir(korean_model_path), exist_ok=True)
197 | print("TTS 모델 체크포인트 파일이 없습니다.해당 파일을 다운로드 받습니다.")
198 | url = 'https://huggingface.co/spaces/skytnt/moe-tts/resolve/main/saved_model/6/model.pth'
199 | download_file(url, get_dir(korean_model_path))
200 | print("TTS 모델 체크포인트 파일 다운로드 완료")
201 |
202 | if not os.path.isfile(korean_config_path):
203 | os.makedirs(get_dir(korean_config_path), exist_ok=True)
204 | print("TTS 모델 설정 파일이 없습니다.해당 파일을 다운로드 받습니다.")
205 | url = 'https://huggingface.co/spaces/skytnt/moe-tts/resolve/main/saved_model/6/config.json'
206 | download_file(url, get_dir(korean_config_path))
207 | print("TTS 모델 설정 파일 다운로드 완료")
208 |
209 | tts = vits(korean_model_path, korean_config_path)
210 | config = json.load(open(korean_config_path, 'r'))
211 | spk_list = config['speakers']
212 | speaker = int(server.receive())
213 | print("선택된 음성: " + spk_list[speaker])
214 |
215 | elif tts_service == 1:
216 | tts = navertts()
217 | speaker = 0
218 |
219 | print("렌파이에서 API KEY를 입력해주세요.")
220 | print("API KEY는 https://platform.openai.com/account/api-keys 에서 발급할 수 있습니다.")
221 |
222 | session_token = server.receive()
223 |
224 | if(session_token):
225 | print(f"API KEY: ...{session_token[-8:]}")
226 | oai = openai_session(session_token)
227 |
228 | setting = server.receive()
229 | oai.set_role(setting)
230 | print("배경 설정: "+ setting)
231 |
232 | greeting = server.receive()
233 | oai.set_greeting(greeting)
234 | print("인사말: "+ greeting)
235 |
236 | while True:
237 | question = server.receive()
238 | print("Question Received: " + question)
239 |
240 | answer = oai.send_message(question)
241 | print("ChatGPT:", answer)
242 |
243 | tts_audio_path = tts.generateSound(answer, speaker)
244 |
245 | # convert wav to ogg
246 | src = tts_audio_path
247 | dst = "./ChatWithGPT/game/audio/test.ogg"
248 | sound = getattr(AudioSegment, f'from_{src.split(".")[-1]}')(src)
249 | sound.export(dst, format="ogg")
250 |
251 | # send response to UI
252 | server.send(answer)
253 |
254 | # finish playing audio
255 | print(server.receive())
256 |
257 | if __name__ == "__main__":
258 | try:
259 | main()
260 | except KeyboardInterrupt:
261 | print("종료합니다.")
262 | sys.exit(0)
263 | except ConnectionResetError:
264 | print("클라이언트와의 연결이 끊겼습니다.")
265 | sys.exit(0)
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/Hiyori.cdi3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Parameters": [
4 | {
5 | "Id": "ParamAngleX",
6 | "GroupId": "ParamGroupFace",
7 | "Name": "角度 X"
8 | },
9 | {
10 | "Id": "ParamAngleY",
11 | "GroupId": "ParamGroupFace",
12 | "Name": "角度 Y"
13 | },
14 | {
15 | "Id": "ParamAngleZ",
16 | "GroupId": "ParamGroupFace",
17 | "Name": "角度 Z"
18 | },
19 | {
20 | "Id": "ParamCheek",
21 | "GroupId": "ParamGroupFace",
22 | "Name": "照れ"
23 | },
24 | {
25 | "Id": "ParamEyeLOpen",
26 | "GroupId": "ParamGroupEyes",
27 | "Name": "左目 開閉"
28 | },
29 | {
30 | "Id": "ParamEyeLSmile",
31 | "GroupId": "ParamGroupEyes",
32 | "Name": "左目 笑顔"
33 | },
34 | {
35 | "Id": "ParamEyeROpen",
36 | "GroupId": "ParamGroupEyes",
37 | "Name": "右目 開閉"
38 | },
39 | {
40 | "Id": "ParamEyeRSmile",
41 | "GroupId": "ParamGroupEyes",
42 | "Name": "右目 笑顔"
43 | },
44 | {
45 | "Id": "ParamEyeBallX",
46 | "GroupId": "ParamGroupEyeballs",
47 | "Name": "目玉 X"
48 | },
49 | {
50 | "Id": "ParamEyeBallY",
51 | "GroupId": "ParamGroupEyeballs",
52 | "Name": "目玉 Y"
53 | },
54 | {
55 | "Id": "ParamBrowLY",
56 | "GroupId": "ParamGroupBrows",
57 | "Name": "左眉 上下"
58 | },
59 | {
60 | "Id": "ParamBrowRY",
61 | "GroupId": "ParamGroupBrows",
62 | "Name": "右眉 上下"
63 | },
64 | {
65 | "Id": "ParamBrowLX",
66 | "GroupId": "ParamGroupBrows",
67 | "Name": "左眉 左右"
68 | },
69 | {
70 | "Id": "ParamBrowRX",
71 | "GroupId": "ParamGroupBrows",
72 | "Name": "右眉 左右"
73 | },
74 | {
75 | "Id": "ParamBrowLAngle",
76 | "GroupId": "ParamGroupBrows",
77 | "Name": "左眉 角度"
78 | },
79 | {
80 | "Id": "ParamBrowRAngle",
81 | "GroupId": "ParamGroupBrows",
82 | "Name": "右眉 角度"
83 | },
84 | {
85 | "Id": "ParamBrowLForm",
86 | "GroupId": "ParamGroupBrows",
87 | "Name": "左眉 変形"
88 | },
89 | {
90 | "Id": "ParamBrowRForm",
91 | "GroupId": "ParamGroupBrows",
92 | "Name": "右眉 変形"
93 | },
94 | {
95 | "Id": "ParamMouthForm",
96 | "GroupId": "ParamGroupMouth",
97 | "Name": "口 変形"
98 | },
99 | {
100 | "Id": "ParamMouthOpenY",
101 | "GroupId": "ParamGroupMouth",
102 | "Name": "口 開閉"
103 | },
104 | {
105 | "Id": "ParamBodyAngleX",
106 | "GroupId": "ParamGroupBody",
107 | "Name": "体の回転 X"
108 | },
109 | {
110 | "Id": "ParamBodyAngleY",
111 | "GroupId": "ParamGroupBody",
112 | "Name": "体の回転 Y"
113 | },
114 | {
115 | "Id": "ParamBodyAngleZ",
116 | "GroupId": "ParamGroupBody",
117 | "Name": "体の回転 Z"
118 | },
119 | {
120 | "Id": "ParamBreath",
121 | "GroupId": "ParamGroupBody",
122 | "Name": "呼吸"
123 | },
124 | {
125 | "Id": "ParamShoulder",
126 | "GroupId": "ParamGroupBody",
127 | "Name": "肩 すくみ"
128 | },
129 | {
130 | "Id": "ParamLeg",
131 | "GroupId": "ParamGroupBody",
132 | "Name": "あし"
133 | },
134 | {
135 | "Id": "ParamArmLA",
136 | "GroupId": "ParamGroupArms",
137 | "Name": "左腕 A"
138 | },
139 | {
140 | "Id": "ParamArmRA",
141 | "GroupId": "ParamGroupArms",
142 | "Name": "右腕 A"
143 | },
144 | {
145 | "Id": "ParamArmLB",
146 | "GroupId": "ParamGroupArms",
147 | "Name": "左腕 B"
148 | },
149 | {
150 | "Id": "ParamArmRB",
151 | "GroupId": "ParamGroupArms",
152 | "Name": "右腕 B"
153 | },
154 | {
155 | "Id": "ParamHandLB",
156 | "GroupId": "ParamGroupArms",
157 | "Name": "左手B 回転"
158 | },
159 | {
160 | "Id": "ParamHandRB",
161 | "GroupId": "ParamGroupArms",
162 | "Name": "右手B 回転"
163 | },
164 | {
165 | "Id": "ParamHandL",
166 | "GroupId": "ParamGroupArms",
167 | "Name": "左手"
168 | },
169 | {
170 | "Id": "ParamHandR",
171 | "GroupId": "ParamGroupArms",
172 | "Name": "右手"
173 | },
174 | {
175 | "Id": "ParamBustY",
176 | "GroupId": "ParamGroupSway",
177 | "Name": "胸 揺れ"
178 | },
179 | {
180 | "Id": "ParamHairAhoge",
181 | "GroupId": "ParamGroupSway",
182 | "Name": "髪揺れ アホ毛"
183 | },
184 | {
185 | "Id": "ParamHairFront",
186 | "GroupId": "ParamGroupSway",
187 | "Name": "髪揺れ 前"
188 | },
189 | {
190 | "Id": "ParamHairBack",
191 | "GroupId": "ParamGroupSway",
192 | "Name": "髪揺れ 後"
193 | },
194 | {
195 | "Id": "ParamSideupRibbon",
196 | "GroupId": "ParamGroupSway",
197 | "Name": "髪飾りの揺れ"
198 | },
199 | {
200 | "Id": "ParamRibbon",
201 | "GroupId": "ParamGroupSway",
202 | "Name": "胸リボンの揺れ"
203 | },
204 | {
205 | "Id": "ParamSkirt",
206 | "GroupId": "ParamGroupSway",
207 | "Name": "スカートの揺れ"
208 | },
209 | {
210 | "Id": "ParamSkirt2",
211 | "GroupId": "ParamGroupSway",
212 | "Name": "スカートめくれ"
213 | },
214 | {
215 | "Id": "Param_Angle_Rotation_1_ArtMesh62",
216 | "GroupId": "ParamGroup2",
217 | "Name": "[0]サイドアップ左"
218 | },
219 | {
220 | "Id": "Param_Angle_Rotation_2_ArtMesh62",
221 | "GroupId": "ParamGroup2",
222 | "Name": "[1]サイドアップ左"
223 | },
224 | {
225 | "Id": "Param_Angle_Rotation_3_ArtMesh62",
226 | "GroupId": "ParamGroup2",
227 | "Name": "[2]サイドアップ左"
228 | },
229 | {
230 | "Id": "Param_Angle_Rotation_4_ArtMesh62",
231 | "GroupId": "ParamGroup2",
232 | "Name": "[3]サイドアップ左"
233 | },
234 | {
235 | "Id": "Param_Angle_Rotation_5_ArtMesh62",
236 | "GroupId": "ParamGroup2",
237 | "Name": "[4]サイドアップ左"
238 | },
239 | {
240 | "Id": "Param_Angle_Rotation_6_ArtMesh62",
241 | "GroupId": "ParamGroup2",
242 | "Name": "[5]サイドアップ左"
243 | },
244 | {
245 | "Id": "Param_Angle_Rotation_7_ArtMesh62",
246 | "GroupId": "ParamGroup2",
247 | "Name": "[6]サイドアップ左"
248 | },
249 | {
250 | "Id": "Param_Angle_Rotation_1_ArtMesh61",
251 | "GroupId": "ParamGroup",
252 | "Name": "[0]サイドアップ右"
253 | },
254 | {
255 | "Id": "Param_Angle_Rotation_2_ArtMesh61",
256 | "GroupId": "ParamGroup",
257 | "Name": "[1]サイドアップ右"
258 | },
259 | {
260 | "Id": "Param_Angle_Rotation_3_ArtMesh61",
261 | "GroupId": "ParamGroup",
262 | "Name": "[2]サイドアップ右"
263 | },
264 | {
265 | "Id": "Param_Angle_Rotation_4_ArtMesh61",
266 | "GroupId": "ParamGroup",
267 | "Name": "[3]サイドアップ右"
268 | },
269 | {
270 | "Id": "Param_Angle_Rotation_5_ArtMesh61",
271 | "GroupId": "ParamGroup",
272 | "Name": "[4]サイドアップ右"
273 | },
274 | {
275 | "Id": "Param_Angle_Rotation_6_ArtMesh61",
276 | "GroupId": "ParamGroup",
277 | "Name": "[5]サイドアップ右"
278 | },
279 | {
280 | "Id": "Param_Angle_Rotation_7_ArtMesh61",
281 | "GroupId": "ParamGroup",
282 | "Name": "[6]サイドアップ右"
283 | },
284 | {
285 | "Id": "Param_Angle_Rotation_1_ArtMesh55",
286 | "GroupId": "ParamGroup4",
287 | "Name": "[0]前髪左"
288 | },
289 | {
290 | "Id": "Param_Angle_Rotation_2_ArtMesh55",
291 | "GroupId": "ParamGroup4",
292 | "Name": "[1]前髪左"
293 | },
294 | {
295 | "Id": "Param_Angle_Rotation_3_ArtMesh55",
296 | "GroupId": "ParamGroup4",
297 | "Name": "[2]前髪左"
298 | },
299 | {
300 | "Id": "Param_Angle_Rotation_4_ArtMesh55",
301 | "GroupId": "ParamGroup4",
302 | "Name": "[3]前髪左"
303 | },
304 | {
305 | "Id": "Param_Angle_Rotation_5_ArtMesh55",
306 | "GroupId": "ParamGroup4",
307 | "Name": "[4]前髪左"
308 | },
309 | {
310 | "Id": "Param_Angle_Rotation_6_ArtMesh55",
311 | "GroupId": "ParamGroup4",
312 | "Name": "[5]前髪左"
313 | },
314 | {
315 | "Id": "Param_Angle_Rotation_7_ArtMesh55",
316 | "GroupId": "ParamGroup4",
317 | "Name": "[6]前髪左"
318 | },
319 | {
320 | "Id": "Param_Angle_Rotation_1_ArtMesh54",
321 | "GroupId": "ParamGroup3",
322 | "Name": "[0]前髪右"
323 | },
324 | {
325 | "Id": "Param_Angle_Rotation_2_ArtMesh54",
326 | "GroupId": "ParamGroup3",
327 | "Name": "[1]前髪右"
328 | },
329 | {
330 | "Id": "Param_Angle_Rotation_3_ArtMesh54",
331 | "GroupId": "ParamGroup3",
332 | "Name": "[2]前髪右"
333 | },
334 | {
335 | "Id": "Param_Angle_Rotation_4_ArtMesh54",
336 | "GroupId": "ParamGroup3",
337 | "Name": "[3]前髪右"
338 | },
339 | {
340 | "Id": "Param_Angle_Rotation_5_ArtMesh54",
341 | "GroupId": "ParamGroup3",
342 | "Name": "[4]前髪右"
343 | },
344 | {
345 | "Id": "Param_Angle_Rotation_6_ArtMesh54",
346 | "GroupId": "ParamGroup3",
347 | "Name": "[5]前髪右"
348 | },
349 | {
350 | "Id": "Param_Angle_Rotation_7_ArtMesh54",
351 | "GroupId": "ParamGroup3",
352 | "Name": "[6]前髪右"
353 | }
354 | ],
355 | "ParameterGroups": [
356 | {
357 | "Id": "ParamGroupFace",
358 | "GroupId": "",
359 | "Name": "顔"
360 | },
361 | {
362 | "Id": "ParamGroupEyes",
363 | "GroupId": "",
364 | "Name": "目"
365 | },
366 | {
367 | "Id": "ParamGroupEyeballs",
368 | "GroupId": "",
369 | "Name": "目玉"
370 | },
371 | {
372 | "Id": "ParamGroupBrows",
373 | "GroupId": "",
374 | "Name": "眉"
375 | },
376 | {
377 | "Id": "ParamGroupMouth",
378 | "GroupId": "",
379 | "Name": "口"
380 | },
381 | {
382 | "Id": "ParamGroupBody",
383 | "GroupId": "",
384 | "Name": "体"
385 | },
386 | {
387 | "Id": "ParamGroupArms",
388 | "GroupId": "",
389 | "Name": "腕"
390 | },
391 | {
392 | "Id": "ParamGroupSway",
393 | "GroupId": "",
394 | "Name": "揺れ"
395 | },
396 | {
397 | "Id": "ParamGroup2",
398 | "GroupId": "",
399 | "Name": "揺れ サイドアップ左"
400 | },
401 | {
402 | "Id": "ParamGroup",
403 | "GroupId": "",
404 | "Name": "揺れ サイドアップ右"
405 | },
406 | {
407 | "Id": "ParamGroup4",
408 | "GroupId": "",
409 | "Name": "揺れ 前髪左"
410 | },
411 | {
412 | "Id": "ParamGroup3",
413 | "GroupId": "",
414 | "Name": "揺れ 前髪右"
415 | }
416 | ],
417 | "Parts": [
418 | {
419 | "Id": "PartCore",
420 | "Name": "コア"
421 | },
422 | {
423 | "Id": "PartCheek",
424 | "Name": "頬"
425 | },
426 | {
427 | "Id": "PartBrow",
428 | "Name": "まゆ毛"
429 | },
430 | {
431 | "Id": "PartEye",
432 | "Name": "目"
433 | },
434 | {
435 | "Id": "PartNose",
436 | "Name": "鼻"
437 | },
438 | {
439 | "Id": "PartMouth",
440 | "Name": "口"
441 | },
442 | {
443 | "Id": "PartFace",
444 | "Name": "顔"
445 | },
446 | {
447 | "Id": "PartEar",
448 | "Name": "耳"
449 | },
450 | {
451 | "Id": "PartHairSide",
452 | "Name": "横髪"
453 | },
454 | {
455 | "Id": "PartHairFront",
456 | "Name": "前髪"
457 | },
458 | {
459 | "Id": "PartHairBack",
460 | "Name": "後ろ髪"
461 | },
462 | {
463 | "Id": "PartNeck",
464 | "Name": "首"
465 | },
466 | {
467 | "Id": "PartArmA",
468 | "Name": "腕 A"
469 | },
470 | {
471 | "Id": "PartArmB",
472 | "Name": "腕 B"
473 | },
474 | {
475 | "Id": "PartBody",
476 | "Name": "体"
477 | },
478 | {
479 | "Id": "PartBackground",
480 | "Name": "背景"
481 | },
482 | {
483 | "Id": "PartSketch",
484 | "Name": "[ 下絵 ]"
485 | },
486 | {
487 | "Id": "PartEyeBall",
488 | "Name": "目玉"
489 | },
490 | {
491 | "Id": "ArtMesh55_Skinning",
492 | "Name": "前髪左(スキニング)"
493 | },
494 | {
495 | "Id": "Part4",
496 | "Name": "前髪左(回転)"
497 | },
498 | {
499 | "Id": "ArtMesh54_Skinning",
500 | "Name": "前髪右(スキニング)"
501 | },
502 | {
503 | "Id": "Part3",
504 | "Name": "前髪右(回転)"
505 | },
506 | {
507 | "Id": "ArtMesh61_Skinning",
508 | "Name": "サイドアップ右(スキニング)"
509 | },
510 | {
511 | "Id": "Part",
512 | "Name": "サイドアップ右(回転)"
513 | },
514 | {
515 | "Id": "ArtMesh62_Skinning",
516 | "Name": "サイドアップ左(スキニング)"
517 | },
518 | {
519 | "Id": "Part2",
520 | "Name": "サイドアップ左(回転)"
521 | }
522 | ]
523 | }
--------------------------------------------------------------------------------
/attentions.py:
--------------------------------------------------------------------------------
1 | import math
2 | import torch
3 | from torch import nn
4 | from torch.nn import functional as F
5 |
6 | import commons
7 | from modules import LayerNorm
8 |
9 |
10 | class Encoder(nn.Module):
11 | def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., window_size=4, **kwargs):
12 | super().__init__()
13 | self.hidden_channels = hidden_channels
14 | self.filter_channels = filter_channels
15 | self.n_heads = n_heads
16 | self.n_layers = n_layers
17 | self.kernel_size = kernel_size
18 | self.p_dropout = p_dropout
19 | self.window_size = window_size
20 |
21 | self.drop = nn.Dropout(p_dropout)
22 | self.attn_layers = nn.ModuleList()
23 | self.norm_layers_1 = nn.ModuleList()
24 | self.ffn_layers = nn.ModuleList()
25 | self.norm_layers_2 = nn.ModuleList()
26 | for i in range(self.n_layers):
27 | self.attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, window_size=window_size))
28 | self.norm_layers_1.append(LayerNorm(hidden_channels))
29 | self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout))
30 | self.norm_layers_2.append(LayerNorm(hidden_channels))
31 |
32 | def forward(self, x, x_mask):
33 | attn_mask = x_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
34 | x = x * x_mask
35 | for i in range(self.n_layers):
36 | y = self.attn_layers[i](x, x, attn_mask)
37 | y = self.drop(y)
38 | x = self.norm_layers_1[i](x + y)
39 |
40 | y = self.ffn_layers[i](x, x_mask)
41 | y = self.drop(y)
42 | x = self.norm_layers_2[i](x + y)
43 | x = x * x_mask
44 | return x
45 |
46 |
47 | class Decoder(nn.Module):
48 | def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., proximal_bias=False, proximal_init=True, **kwargs):
49 | super().__init__()
50 | self.hidden_channels = hidden_channels
51 | self.filter_channels = filter_channels
52 | self.n_heads = n_heads
53 | self.n_layers = n_layers
54 | self.kernel_size = kernel_size
55 | self.p_dropout = p_dropout
56 | self.proximal_bias = proximal_bias
57 | self.proximal_init = proximal_init
58 |
59 | self.drop = nn.Dropout(p_dropout)
60 | self.self_attn_layers = nn.ModuleList()
61 | self.norm_layers_0 = nn.ModuleList()
62 | self.encdec_attn_layers = nn.ModuleList()
63 | self.norm_layers_1 = nn.ModuleList()
64 | self.ffn_layers = nn.ModuleList()
65 | self.norm_layers_2 = nn.ModuleList()
66 | for i in range(self.n_layers):
67 | self.self_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, proximal_bias=proximal_bias, proximal_init=proximal_init))
68 | self.norm_layers_0.append(LayerNorm(hidden_channels))
69 | self.encdec_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout))
70 | self.norm_layers_1.append(LayerNorm(hidden_channels))
71 | self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout, causal=True))
72 | self.norm_layers_2.append(LayerNorm(hidden_channels))
73 |
74 | def forward(self, x, x_mask, h, h_mask):
75 | """
76 | x: decoder input
77 | h: encoder output
78 | """
79 | self_attn_mask = commons.subsequent_mask(x_mask.size(2)).to(device=x.device, dtype=x.dtype)
80 | encdec_attn_mask = h_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
81 | x = x * x_mask
82 | for i in range(self.n_layers):
83 | y = self.self_attn_layers[i](x, x, self_attn_mask)
84 | y = self.drop(y)
85 | x = self.norm_layers_0[i](x + y)
86 |
87 | y = self.encdec_attn_layers[i](x, h, encdec_attn_mask)
88 | y = self.drop(y)
89 | x = self.norm_layers_1[i](x + y)
90 |
91 | y = self.ffn_layers[i](x, x_mask)
92 | y = self.drop(y)
93 | x = self.norm_layers_2[i](x + y)
94 | x = x * x_mask
95 | return x
96 |
97 |
98 | class MultiHeadAttention(nn.Module):
99 | def __init__(self, channels, out_channels, n_heads, p_dropout=0., window_size=None, heads_share=True, block_length=None, proximal_bias=False, proximal_init=False):
100 | super().__init__()
101 | assert channels % n_heads == 0
102 |
103 | self.channels = channels
104 | self.out_channels = out_channels
105 | self.n_heads = n_heads
106 | self.p_dropout = p_dropout
107 | self.window_size = window_size
108 | self.heads_share = heads_share
109 | self.block_length = block_length
110 | self.proximal_bias = proximal_bias
111 | self.proximal_init = proximal_init
112 | self.attn = None
113 |
114 | self.k_channels = channels // n_heads
115 | self.conv_q = nn.Conv1d(channels, channels, 1)
116 | self.conv_k = nn.Conv1d(channels, channels, 1)
117 | self.conv_v = nn.Conv1d(channels, channels, 1)
118 | self.conv_o = nn.Conv1d(channels, out_channels, 1)
119 | self.drop = nn.Dropout(p_dropout)
120 |
121 | if window_size is not None:
122 | n_heads_rel = 1 if heads_share else n_heads
123 | rel_stddev = self.k_channels**-0.5
124 | self.emb_rel_k = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
125 | self.emb_rel_v = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
126 |
127 | nn.init.xavier_uniform_(self.conv_q.weight)
128 | nn.init.xavier_uniform_(self.conv_k.weight)
129 | nn.init.xavier_uniform_(self.conv_v.weight)
130 | if proximal_init:
131 | with torch.no_grad():
132 | self.conv_k.weight.copy_(self.conv_q.weight)
133 | self.conv_k.bias.copy_(self.conv_q.bias)
134 |
135 | def forward(self, x, c, attn_mask=None):
136 | q = self.conv_q(x)
137 | k = self.conv_k(c)
138 | v = self.conv_v(c)
139 |
140 | x, self.attn = self.attention(q, k, v, mask=attn_mask)
141 |
142 | x = self.conv_o(x)
143 | return x
144 |
145 | def attention(self, query, key, value, mask=None):
146 | # reshape [b, d, t] -> [b, n_h, t, d_k]
147 | b, d, t_s, t_t = (*key.size(), query.size(2))
148 | query = query.view(b, self.n_heads, self.k_channels, t_t).transpose(2, 3)
149 | key = key.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
150 | value = value.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
151 |
152 | scores = torch.matmul(query / math.sqrt(self.k_channels), key.transpose(-2, -1))
153 | if self.window_size is not None:
154 | assert t_s == t_t, "Relative attention is only available for self-attention."
155 | key_relative_embeddings = self._get_relative_embeddings(self.emb_rel_k, t_s)
156 | rel_logits = self._matmul_with_relative_keys(query /math.sqrt(self.k_channels), key_relative_embeddings)
157 | scores_local = self._relative_position_to_absolute_position(rel_logits)
158 | scores = scores + scores_local
159 | if self.proximal_bias:
160 | assert t_s == t_t, "Proximal bias is only available for self-attention."
161 | scores = scores + self._attention_bias_proximal(t_s).to(device=scores.device, dtype=scores.dtype)
162 | if mask is not None:
163 | scores = scores.masked_fill(mask == 0, -1e4)
164 | if self.block_length is not None:
165 | assert t_s == t_t, "Local attention is only available for self-attention."
166 | block_mask = torch.ones_like(scores).triu(-self.block_length).tril(self.block_length)
167 | scores = scores.masked_fill(block_mask == 0, -1e4)
168 | p_attn = F.softmax(scores, dim=-1) # [b, n_h, t_t, t_s]
169 | p_attn = self.drop(p_attn)
170 | output = torch.matmul(p_attn, value)
171 | if self.window_size is not None:
172 | relative_weights = self._absolute_position_to_relative_position(p_attn)
173 | value_relative_embeddings = self._get_relative_embeddings(self.emb_rel_v, t_s)
174 | output = output + self._matmul_with_relative_values(relative_weights, value_relative_embeddings)
175 | output = output.transpose(2, 3).contiguous().view(b, d, t_t) # [b, n_h, t_t, d_k] -> [b, d, t_t]
176 | return output, p_attn
177 |
178 | def _matmul_with_relative_values(self, x, y):
179 | """
180 | x: [b, h, l, m]
181 | y: [h or 1, m, d]
182 | ret: [b, h, l, d]
183 | """
184 | ret = torch.matmul(x, y.unsqueeze(0))
185 | return ret
186 |
187 | def _matmul_with_relative_keys(self, x, y):
188 | """
189 | x: [b, h, l, d]
190 | y: [h or 1, m, d]
191 | ret: [b, h, l, m]
192 | """
193 | ret = torch.matmul(x, y.unsqueeze(0).transpose(-2, -1))
194 | return ret
195 |
196 | def _get_relative_embeddings(self, relative_embeddings, length):
197 | max_relative_position = 2 * self.window_size + 1
198 | # Pad first before slice to avoid using cond ops.
199 | pad_length = max(length - (self.window_size + 1), 0)
200 | slice_start_position = max((self.window_size + 1) - length, 0)
201 | slice_end_position = slice_start_position + 2 * length - 1
202 | if pad_length > 0:
203 | padded_relative_embeddings = F.pad(
204 | relative_embeddings,
205 | commons.convert_pad_shape([[0, 0], [pad_length, pad_length], [0, 0]]))
206 | else:
207 | padded_relative_embeddings = relative_embeddings
208 | used_relative_embeddings = padded_relative_embeddings[:,slice_start_position:slice_end_position]
209 | return used_relative_embeddings
210 |
211 | def _relative_position_to_absolute_position(self, x):
212 | """
213 | x: [b, h, l, 2*l-1]
214 | ret: [b, h, l, l]
215 | """
216 | batch, heads, length, _ = x.size()
217 | # Concat columns of pad to shift from relative to absolute indexing.
218 | x = F.pad(x, commons.convert_pad_shape([[0,0],[0,0],[0,0],[0,1]]))
219 |
220 | # Concat extra elements so to add up to shape (len+1, 2*len-1).
221 | x_flat = x.view([batch, heads, length * 2 * length])
222 | x_flat = F.pad(x_flat, commons.convert_pad_shape([[0,0],[0,0],[0,length-1]]))
223 |
224 | # Reshape and slice out the padded elements.
225 | x_final = x_flat.view([batch, heads, length+1, 2*length-1])[:, :, :length, length-1:]
226 | return x_final
227 |
228 | def _absolute_position_to_relative_position(self, x):
229 | """
230 | x: [b, h, l, l]
231 | ret: [b, h, l, 2*l-1]
232 | """
233 | batch, heads, length, _ = x.size()
234 | # padd along column
235 | x = F.pad(x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, length-1]]))
236 | x_flat = x.view([batch, heads, length**2 + length*(length -1)])
237 | # add 0's in the beginning that will skew the elements after reshape
238 | x_flat = F.pad(x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [length, 0]]))
239 | x_final = x_flat.view([batch, heads, length, 2*length])[:,:,:,1:]
240 | return x_final
241 |
242 | def _attention_bias_proximal(self, length):
243 | """Bias for self-attention to encourage attention to close positions.
244 | Args:
245 | length: an integer scalar.
246 | Returns:
247 | a Tensor with shape [1, 1, length, length]
248 | """
249 | r = torch.arange(length, dtype=torch.float32)
250 | diff = torch.unsqueeze(r, 0) - torch.unsqueeze(r, 1)
251 | return torch.unsqueeze(torch.unsqueeze(-torch.log1p(torch.abs(diff)), 0), 0)
252 |
253 |
254 | class FFN(nn.Module):
255 | def __init__(self, in_channels, out_channels, filter_channels, kernel_size, p_dropout=0., activation=None, causal=False):
256 | super().__init__()
257 | self.in_channels = in_channels
258 | self.out_channels = out_channels
259 | self.filter_channels = filter_channels
260 | self.kernel_size = kernel_size
261 | self.p_dropout = p_dropout
262 | self.activation = activation
263 | self.causal = causal
264 |
265 | if causal:
266 | self.padding = self._causal_padding
267 | else:
268 | self.padding = self._same_padding
269 |
270 | self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size)
271 | self.conv_2 = nn.Conv1d(filter_channels, out_channels, kernel_size)
272 | self.drop = nn.Dropout(p_dropout)
273 |
274 | def forward(self, x, x_mask):
275 | x = self.conv_1(self.padding(x * x_mask))
276 | if self.activation == "gelu":
277 | x = x * torch.sigmoid(1.702 * x)
278 | else:
279 | x = torch.relu(x)
280 | x = self.drop(x)
281 | x = self.conv_2(self.padding(x * x_mask))
282 | return x * x_mask
283 |
284 | def _causal_padding(self, x):
285 | if self.kernel_size == 1:
286 | return x
287 | pad_l = self.kernel_size - 1
288 | pad_r = 0
289 | padding = [[0, 0], [0, 0], [pad_l, pad_r]]
290 | x = F.pad(x, commons.convert_pad_shape(padding))
291 | return x
292 |
293 | def _same_padding(self, x):
294 | if self.kernel_size == 1:
295 | return x
296 | pad_l = (self.kernel_size - 1) // 2
297 | pad_r = self.kernel_size // 2
298 | padding = [[0, 0], [0, 0], [pad_l, pad_r]]
299 | x = F.pad(x, commons.convert_pad_shape(padding))
300 | return x
301 |
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/motions/Hiyori_m04.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 4.43,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": false,
8 | "CurveCount": 31,
9 | "TotalSegmentCount": 106,
10 | "TotalPointCount": 287,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "ParamAngleX",
18 | "Segments": [
19 | 0,
20 | 1,
21 | 1,
22 | 0.211,
23 | 1,
24 | 0.422,
25 | 0,
26 | 0.633,
27 | 0,
28 | 1,
29 | 0.911,
30 | 0,
31 | 1.189,
32 | 5,
33 | 1.467,
34 | 5,
35 | 1,
36 | 1.689,
37 | 5,
38 | 1.911,
39 | -16,
40 | 2.133,
41 | -16,
42 | 1,
43 | 2.356,
44 | -16,
45 | 2.578,
46 | 13.871,
47 | 2.8,
48 | 13.871,
49 | 1,
50 | 2.956,
51 | 13.871,
52 | 3.111,
53 | 0,
54 | 3.267,
55 | 0,
56 | 0,
57 | 4.433,
58 | 0
59 | ]
60 | },
61 | {
62 | "Target": "Parameter",
63 | "Id": "ParamAngleY",
64 | "Segments": [
65 | 0,
66 | 0,
67 | 1,
68 | 0.211,
69 | 0,
70 | 0.422,
71 | 0,
72 | 0.633,
73 | 0,
74 | 1,
75 | 0.911,
76 | 0,
77 | 1.189,
78 | -25,
79 | 1.467,
80 | -25,
81 | 1,
82 | 1.689,
83 | -25,
84 | 1.911,
85 | -15.225,
86 | 2.133,
87 | -11,
88 | 1,
89 | 2.356,
90 | -6.775,
91 | 2.578,
92 | -5.127,
93 | 2.8,
94 | -2.5,
95 | 1,
96 | 2.956,
97 | -0.661,
98 | 3.111,
99 | 0,
100 | 3.267,
101 | 0,
102 | 0,
103 | 4.433,
104 | 0
105 | ]
106 | },
107 | {
108 | "Target": "Parameter",
109 | "Id": "ParamAngleZ",
110 | "Segments": [
111 | 0,
112 | 0,
113 | 1,
114 | 0.222,
115 | 0,
116 | 0.444,
117 | 0,
118 | 0.667,
119 | 0,
120 | 1,
121 | 0.756,
122 | 0,
123 | 0.844,
124 | -4,
125 | 0.933,
126 | -4,
127 | 1,
128 | 1.122,
129 | -4,
130 | 1.311,
131 | 18,
132 | 1.5,
133 | 18,
134 | 1,
135 | 1.722,
136 | 18,
137 | 1.944,
138 | -14,
139 | 2.167,
140 | -14,
141 | 1,
142 | 2.567,
143 | -14,
144 | 2.967,
145 | -14,
146 | 3.367,
147 | -14,
148 | 1,
149 | 3.511,
150 | -14,
151 | 3.656,
152 | -12,
153 | 3.8,
154 | -12,
155 | 0,
156 | 4.433,
157 | -12
158 | ]
159 | },
160 | {
161 | "Target": "Parameter",
162 | "Id": "ParamCheek",
163 | "Segments": [
164 | 0,
165 | 1,
166 | 0,
167 | 4.433,
168 | 1
169 | ]
170 | },
171 | {
172 | "Target": "Parameter",
173 | "Id": "ParamEyeLOpen",
174 | "Segments": [
175 | 0,
176 | 1.2,
177 | 1,
178 | 0.389,
179 | 1.2,
180 | 0.778,
181 | 1.148,
182 | 1.167,
183 | 1,
184 | 1,
185 | 1.211,
186 | 0.983,
187 | 1.256,
188 | 0,
189 | 1.3,
190 | 0,
191 | 1,
192 | 1.322,
193 | 0,
194 | 1.344,
195 | 0,
196 | 1.367,
197 | 0,
198 | 1,
199 | 1.422,
200 | 0,
201 | 1.478,
202 | 1,
203 | 1.533,
204 | 1,
205 | 1,
206 | 1.944,
207 | 1,
208 | 2.356,
209 | 1,
210 | 2.767,
211 | 1,
212 | 1,
213 | 2.811,
214 | 1,
215 | 2.856,
216 | 0,
217 | 2.9,
218 | 0,
219 | 1,
220 | 2.922,
221 | 0,
222 | 2.944,
223 | 0,
224 | 2.967,
225 | 0,
226 | 1,
227 | 3.022,
228 | 0,
229 | 3.078,
230 | 1,
231 | 3.133,
232 | 1,
233 | 0,
234 | 4.433,
235 | 1
236 | ]
237 | },
238 | {
239 | "Target": "Parameter",
240 | "Id": "ParamEyeLSmile",
241 | "Segments": [
242 | 0,
243 | 0,
244 | 0,
245 | 4.433,
246 | 0
247 | ]
248 | },
249 | {
250 | "Target": "Parameter",
251 | "Id": "ParamEyeROpen",
252 | "Segments": [
253 | 0,
254 | 1.2,
255 | 1,
256 | 0.389,
257 | 1.2,
258 | 0.778,
259 | 1.148,
260 | 1.167,
261 | 1,
262 | 1,
263 | 1.211,
264 | 0.983,
265 | 1.256,
266 | 0,
267 | 1.3,
268 | 0,
269 | 1,
270 | 1.322,
271 | 0,
272 | 1.344,
273 | 0,
274 | 1.367,
275 | 0,
276 | 1,
277 | 1.422,
278 | 0,
279 | 1.478,
280 | 1,
281 | 1.533,
282 | 1,
283 | 1,
284 | 1.944,
285 | 1,
286 | 2.356,
287 | 1,
288 | 2.767,
289 | 1,
290 | 1,
291 | 2.811,
292 | 1,
293 | 2.856,
294 | 0,
295 | 2.9,
296 | 0,
297 | 1,
298 | 2.922,
299 | 0,
300 | 2.944,
301 | 0,
302 | 2.967,
303 | 0,
304 | 1,
305 | 3.022,
306 | 0,
307 | 3.078,
308 | 1,
309 | 3.133,
310 | 1,
311 | 0,
312 | 4.433,
313 | 1
314 | ]
315 | },
316 | {
317 | "Target": "Parameter",
318 | "Id": "ParamEyeRSmile",
319 | "Segments": [
320 | 0,
321 | 0,
322 | 0,
323 | 4.433,
324 | 0
325 | ]
326 | },
327 | {
328 | "Target": "Parameter",
329 | "Id": "ParamEyeBallX",
330 | "Segments": [
331 | 0,
332 | 0,
333 | 1,
334 | 0.211,
335 | 0,
336 | 0.422,
337 | 0,
338 | 0.633,
339 | 0,
340 | 1,
341 | 0.911,
342 | 0,
343 | 1.189,
344 | -0.44,
345 | 1.467,
346 | -0.44,
347 | 1,
348 | 1.689,
349 | -0.44,
350 | 1.911,
351 | 0.79,
352 | 2.133,
353 | 0.79,
354 | 1,
355 | 2.511,
356 | 0.79,
357 | 2.889,
358 | 0,
359 | 3.267,
360 | 0,
361 | 0,
362 | 4.433,
363 | 0
364 | ]
365 | },
366 | {
367 | "Target": "Parameter",
368 | "Id": "ParamEyeBallY",
369 | "Segments": [
370 | 0,
371 | 0,
372 | 1,
373 | 0.211,
374 | 0,
375 | 0.422,
376 | 0,
377 | 0.633,
378 | 0,
379 | 1,
380 | 0.911,
381 | 0,
382 | 1.189,
383 | -1,
384 | 1.467,
385 | -1,
386 | 1,
387 | 1.689,
388 | -1,
389 | 1.911,
390 | -1,
391 | 2.133,
392 | -1,
393 | 1,
394 | 2.511,
395 | -1,
396 | 2.889,
397 | 0,
398 | 3.267,
399 | 0,
400 | 0,
401 | 4.433,
402 | 0
403 | ]
404 | },
405 | {
406 | "Target": "Parameter",
407 | "Id": "ParamBrowLY",
408 | "Segments": [
409 | 0,
410 | 1,
411 | 1,
412 | 0.544,
413 | 1,
414 | 1.089,
415 | 1,
416 | 1.633,
417 | 1,
418 | 1,
419 | 1.856,
420 | 1,
421 | 2.078,
422 | 0,
423 | 2.3,
424 | 0,
425 | 1,
426 | 2.5,
427 | 0,
428 | 2.7,
429 | 1,
430 | 2.9,
431 | 1,
432 | 0,
433 | 4.433,
434 | 1
435 | ]
436 | },
437 | {
438 | "Target": "Parameter",
439 | "Id": "ParamBrowRY",
440 | "Segments": [
441 | 0,
442 | 1,
443 | 1,
444 | 0.544,
445 | 1,
446 | 1.089,
447 | 1,
448 | 1.633,
449 | 1,
450 | 1,
451 | 1.856,
452 | 1,
453 | 2.078,
454 | 0,
455 | 2.3,
456 | 0,
457 | 1,
458 | 2.5,
459 | 0,
460 | 2.7,
461 | 1,
462 | 2.9,
463 | 1,
464 | 0,
465 | 4.433,
466 | 1
467 | ]
468 | },
469 | {
470 | "Target": "Parameter",
471 | "Id": "ParamBrowLX",
472 | "Segments": [
473 | 0,
474 | 0,
475 | 0,
476 | 4.433,
477 | 0
478 | ]
479 | },
480 | {
481 | "Target": "Parameter",
482 | "Id": "ParamBrowRX",
483 | "Segments": [
484 | 0,
485 | 0,
486 | 0,
487 | 4.433,
488 | 0
489 | ]
490 | },
491 | {
492 | "Target": "Parameter",
493 | "Id": "ParamBrowLAngle",
494 | "Segments": [
495 | 0,
496 | 0,
497 | 0,
498 | 4.433,
499 | 0
500 | ]
501 | },
502 | {
503 | "Target": "Parameter",
504 | "Id": "ParamBrowRAngle",
505 | "Segments": [
506 | 0,
507 | 0,
508 | 0,
509 | 4.433,
510 | 0
511 | ]
512 | },
513 | {
514 | "Target": "Parameter",
515 | "Id": "ParamBrowLForm",
516 | "Segments": [
517 | 0,
518 | -1,
519 | 0,
520 | 4.433,
521 | -1
522 | ]
523 | },
524 | {
525 | "Target": "Parameter",
526 | "Id": "ParamBrowRForm",
527 | "Segments": [
528 | 0,
529 | -1,
530 | 0,
531 | 4.433,
532 | -1
533 | ]
534 | },
535 | {
536 | "Target": "Parameter",
537 | "Id": "ParamMouthForm",
538 | "Segments": [
539 | 0,
540 | -2,
541 | 0,
542 | 4.433,
543 | -2
544 | ]
545 | },
546 | {
547 | "Target": "Parameter",
548 | "Id": "ParamMouthOpenY",
549 | "Segments": [
550 | 0,
551 | 0,
552 | 0,
553 | 4.433,
554 | 0
555 | ]
556 | },
557 | {
558 | "Target": "Parameter",
559 | "Id": "ParamBodyAngleX",
560 | "Segments": [
561 | 0,
562 | 0,
563 | 1,
564 | 0.244,
565 | 0,
566 | 0.489,
567 | 0,
568 | 0.733,
569 | 0,
570 | 1,
571 | 0.933,
572 | 0,
573 | 1.133,
574 | -7,
575 | 1.333,
576 | -7,
577 | 1,
578 | 1.644,
579 | -7,
580 | 1.956,
581 | 0,
582 | 2.267,
583 | 0,
584 | 0,
585 | 4.433,
586 | 0
587 | ]
588 | },
589 | {
590 | "Target": "Parameter",
591 | "Id": "ParamBodyAngleY",
592 | "Segments": [
593 | 0,
594 | 0,
595 | 1,
596 | 0.244,
597 | 0,
598 | 0.489,
599 | 0,
600 | 0.733,
601 | 0,
602 | 0,
603 | 4.433,
604 | 0
605 | ]
606 | },
607 | {
608 | "Target": "Parameter",
609 | "Id": "ParamBodyAngleZ",
610 | "Segments": [
611 | 0,
612 | 2,
613 | 1,
614 | 0.233,
615 | 2,
616 | 0.467,
617 | 0,
618 | 0.7,
619 | 0,
620 | 1,
621 | 0.733,
622 | 0,
623 | 0.767,
624 | 0,
625 | 0.8,
626 | 0,
627 | 1,
628 | 1,
629 | 0,
630 | 1.2,
631 | -4,
632 | 1.4,
633 | -4,
634 | 1,
635 | 1.711,
636 | -4,
637 | 2.022,
638 | 5,
639 | 2.333,
640 | 5,
641 | 1,
642 | 2.567,
643 | 5,
644 | 2.8,
645 | 3.64,
646 | 3.033,
647 | 0,
648 | 1,
649 | 3.133,
650 | -1.56,
651 | 3.233,
652 | -3,
653 | 3.333,
654 | -3,
655 | 1,
656 | 3.467,
657 | -3,
658 | 3.6,
659 | -2,
660 | 3.733,
661 | -2,
662 | 0,
663 | 4.433,
664 | -2
665 | ]
666 | },
667 | {
668 | "Target": "Parameter",
669 | "Id": "ParamBreath",
670 | "Segments": [
671 | 0,
672 | 0,
673 | 1,
674 | 0.189,
675 | 0,
676 | 0.378,
677 | 1,
678 | 0.567,
679 | 1,
680 | 1,
681 | 0.711,
682 | 1,
683 | 0.856,
684 | 0,
685 | 1,
686 | 0,
687 | 1,
688 | 1.222,
689 | 0,
690 | 1.444,
691 | 1,
692 | 1.667,
693 | 1,
694 | 1,
695 | 1.889,
696 | 1,
697 | 2.111,
698 | 0,
699 | 2.333,
700 | 0,
701 | 1,
702 | 2.544,
703 | 0,
704 | 2.756,
705 | 1,
706 | 2.967,
707 | 1,
708 | 1,
709 | 3.167,
710 | 1,
711 | 3.367,
712 | 0,
713 | 3.567,
714 | 0,
715 | 0,
716 | 4.433,
717 | 0
718 | ]
719 | },
720 | {
721 | "Target": "Parameter",
722 | "Id": "ParamShoulder",
723 | "Segments": [
724 | 0,
725 | 0.1,
726 | 1,
727 | 0.467,
728 | 0.1,
729 | 0.933,
730 | 1,
731 | 1.4,
732 | 1,
733 | 1,
734 | 1.844,
735 | 1,
736 | 2.289,
737 | 1,
738 | 2.733,
739 | 1,
740 | 1,
741 | 2.967,
742 | 1,
743 | 3.2,
744 | -1,
745 | 3.433,
746 | -1,
747 | 0,
748 | 4.433,
749 | -1
750 | ]
751 | },
752 | {
753 | "Target": "Parameter",
754 | "Id": "ParamLeg",
755 | "Segments": [
756 | 0,
757 | 1,
758 | 0,
759 | 4.433,
760 | 1
761 | ]
762 | },
763 | {
764 | "Target": "Parameter",
765 | "Id": "ParamArmLA",
766 | "Segments": [
767 | 0,
768 | -10,
769 | 0,
770 | 4.433,
771 | -10
772 | ]
773 | },
774 | {
775 | "Target": "Parameter",
776 | "Id": "ParamArmRA",
777 | "Segments": [
778 | 0,
779 | -10,
780 | 0,
781 | 4.433,
782 | -10
783 | ]
784 | },
785 | {
786 | "Target": "Parameter",
787 | "Id": "ParamHairAhoge",
788 | "Segments": [
789 | 0,
790 | 0,
791 | 1,
792 | 0.3,
793 | 0,
794 | 0.6,
795 | 0,
796 | 0.9,
797 | -0.012,
798 | 1,
799 | 1.067,
800 | -0.019,
801 | 1.233,
802 | -6.827,
803 | 1.4,
804 | -6.827,
805 | 1,
806 | 1.511,
807 | -6.827,
808 | 1.622,
809 | 7.958,
810 | 1.733,
811 | 7.958,
812 | 1,
813 | 1.944,
814 | 7.958,
815 | 2.156,
816 | -7.565,
817 | 2.367,
818 | -7.565,
819 | 1,
820 | 2.5,
821 | -7.565,
822 | 2.633,
823 | 9.434,
824 | 2.767,
825 | 9.434,
826 | 1,
827 | 2.978,
828 | 9.434,
829 | 3.189,
830 | -8.871,
831 | 3.4,
832 | -8.871,
833 | 1,
834 | 3.5,
835 | -8.871,
836 | 3.6,
837 | 7.588,
838 | 3.7,
839 | 7.588,
840 | 1,
841 | 3.789,
842 | 7.588,
843 | 3.878,
844 | -3.904,
845 | 3.967,
846 | -3.904,
847 | 1,
848 | 4.011,
849 | -3.904,
850 | 4.056,
851 | -0.032,
852 | 4.1,
853 | -0.032,
854 | 0,
855 | 4.433,
856 | -0.032
857 | ]
858 | },
859 | {
860 | "Target": "PartOpacity",
861 | "Id": "PartArmA",
862 | "Segments": [
863 | 0,
864 | 1,
865 | 0,
866 | 4.43,
867 | 1
868 | ]
869 | },
870 | {
871 | "Target": "PartOpacity",
872 | "Id": "PartArmB",
873 | "Segments": [
874 | 0,
875 | 0,
876 | 0,
877 | 4.43,
878 | 0
879 | ]
880 | }
881 | ]
882 | }
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/motions/Hiyori_talking.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 3.167,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": false,
8 | "CurveCount": 30,
9 | "TotalSegmentCount": 107,
10 | "TotalPointCount": 317,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Model",
17 | "Id": "EyeBlink",
18 | "Segments": [
19 | 0,
20 | 1,
21 | 0,
22 | 1.167,
23 | 1,
24 | 1,
25 | 1.267,
26 | 1,
27 | 1.367,
28 | 0,
29 | 1.467,
30 | 0,
31 | 1,
32 | 1.533,
33 | 0,
34 | 1.6,
35 | 0,
36 | 1.667,
37 | 0,
38 | 1,
39 | 1.767,
40 | 0,
41 | 1.867,
42 | 1,
43 | 1.967,
44 | 1,
45 | 0,
46 | 3.167,
47 | 1
48 | ]
49 | },
50 | {
51 | "Target": "Parameter",
52 | "Id": "ParamAngleX",
53 | "Segments": [
54 | 0,
55 | 0,
56 | 0,
57 | 3.167,
58 | 0
59 | ]
60 | },
61 | {
62 | "Target": "Parameter",
63 | "Id": "ParamAngleY",
64 | "Segments": [
65 | 0,
66 | 0,
67 | 0,
68 | 3.167,
69 | 0
70 | ]
71 | },
72 | {
73 | "Target": "Parameter",
74 | "Id": "ParamAngleZ",
75 | "Segments": [
76 | 0,
77 | 0,
78 | 0,
79 | 3.167,
80 | 0
81 | ]
82 | },
83 | {
84 | "Target": "Parameter",
85 | "Id": "ParamCheek",
86 | "Segments": [
87 | 0,
88 | 0,
89 | 0,
90 | 3.167,
91 | 0
92 | ]
93 | },
94 | {
95 | "Target": "Parameter",
96 | "Id": "ParamEyeLOpen",
97 | "Segments": [
98 | 0,
99 | 1,
100 | 0,
101 | 3.167,
102 | 1
103 | ]
104 | },
105 | {
106 | "Target": "Parameter",
107 | "Id": "ParamEyeLSmile",
108 | "Segments": [
109 | 0,
110 | 0,
111 | 0,
112 | 3.167,
113 | 0
114 | ]
115 | },
116 | {
117 | "Target": "Parameter",
118 | "Id": "ParamEyeROpen",
119 | "Segments": [
120 | 0,
121 | 1,
122 | 0,
123 | 3.167,
124 | 1
125 | ]
126 | },
127 | {
128 | "Target": "Parameter",
129 | "Id": "ParamEyeRSmile",
130 | "Segments": [
131 | 0,
132 | 0,
133 | 0,
134 | 3.167,
135 | 0
136 | ]
137 | },
138 | {
139 | "Target": "Parameter",
140 | "Id": "ParamEyeBallX",
141 | "Segments": [
142 | 0,
143 | 0,
144 | 0,
145 | 3.167,
146 | 0
147 | ]
148 | },
149 | {
150 | "Target": "Parameter",
151 | "Id": "ParamEyeBallY",
152 | "Segments": [
153 | 0,
154 | 0,
155 | 0,
156 | 3.167,
157 | 0
158 | ]
159 | },
160 | {
161 | "Target": "Parameter",
162 | "Id": "ParamBrowLForm",
163 | "Segments": [
164 | 0,
165 | 0,
166 | 0,
167 | 3.167,
168 | 0
169 | ]
170 | },
171 | {
172 | "Target": "Parameter",
173 | "Id": "ParamBrowRForm",
174 | "Segments": [
175 | 0,
176 | 0,
177 | 0,
178 | 3.167,
179 | 0
180 | ]
181 | },
182 | {
183 | "Target": "Parameter",
184 | "Id": "ParamMouthForm",
185 | "Segments": [
186 | 0,
187 | 0.5,
188 | 1,
189 | 0.056,
190 | 0.5,
191 | 0.111,
192 | 1,
193 | 0.167,
194 | 1,
195 | 1,
196 | 0.222,
197 | 1,
198 | 0.278,
199 | 0.5,
200 | 0.333,
201 | 0.5,
202 | 1,
203 | 0.389,
204 | 0.5,
205 | 0.444,
206 | 1,
207 | 0.5,
208 | 1,
209 | 1,
210 | 0.556,
211 | 1,
212 | 0.611,
213 | 0.5,
214 | 0.667,
215 | 0.5,
216 | 1,
217 | 0.722,
218 | 0.5,
219 | 0.778,
220 | 1,
221 | 0.833,
222 | 1,
223 | 1,
224 | 0.889,
225 | 1,
226 | 0.944,
227 | 0.5,
228 | 1,
229 | 0.5,
230 | 1,
231 | 1.056,
232 | 0.5,
233 | 1.111,
234 | 1,
235 | 1.167,
236 | 1,
237 | 1,
238 | 1.222,
239 | 1,
240 | 1.278,
241 | 0.5,
242 | 1.333,
243 | 0.5,
244 | 1,
245 | 1.389,
246 | 0.5,
247 | 1.444,
248 | 1,
249 | 1.5,
250 | 1,
251 | 1,
252 | 1.556,
253 | 1,
254 | 1.611,
255 | 0.5,
256 | 1.667,
257 | 0.5,
258 | 1,
259 | 1.722,
260 | 0.5,
261 | 1.778,
262 | 1,
263 | 1.833,
264 | 1,
265 | 1,
266 | 1.889,
267 | 1,
268 | 1.944,
269 | 0.5,
270 | 2,
271 | 0.5,
272 | 1,
273 | 2.056,
274 | 0.5,
275 | 2.111,
276 | 1,
277 | 2.167,
278 | 1,
279 | 1,
280 | 2.222,
281 | 1,
282 | 2.278,
283 | 0.5,
284 | 2.333,
285 | 0.5,
286 | 1,
287 | 2.389,
288 | 0.5,
289 | 2.444,
290 | 1,
291 | 2.5,
292 | 1,
293 | 1,
294 | 2.556,
295 | 1,
296 | 2.611,
297 | 0.5,
298 | 2.667,
299 | 0.5,
300 | 1,
301 | 2.722,
302 | 0.5,
303 | 2.778,
304 | 1,
305 | 2.833,
306 | 1,
307 | 1,
308 | 2.889,
309 | 1,
310 | 2.944,
311 | 0.5,
312 | 3,
313 | 0.5,
314 | 1,
315 | 3.056,
316 | 0.5,
317 | 3.111,
318 | 1,
319 | 3.167,
320 | 1
321 | ]
322 | },
323 | {
324 | "Target": "Parameter",
325 | "Id": "ParamMouthOpenY",
326 | "Segments": [
327 | 0,
328 | 0,
329 | 1,
330 | 0.056,
331 | 0,
332 | 0.111,
333 | 1,
334 | 0.167,
335 | 1,
336 | 1,
337 | 0.222,
338 | 1,
339 | 0.278,
340 | 0.6,
341 | 0.333,
342 | 0.6,
343 | 1,
344 | 0.389,
345 | 0.6,
346 | 0.444,
347 | 1,
348 | 0.5,
349 | 1,
350 | 1,
351 | 0.556,
352 | 1,
353 | 0.611,
354 | 0,
355 | 0.667,
356 | 0,
357 | 1,
358 | 0.722,
359 | 0,
360 | 0.778,
361 | 1,
362 | 0.833,
363 | 1,
364 | 1,
365 | 0.889,
366 | 1,
367 | 0.944,
368 | 0.6,
369 | 1,
370 | 0.6,
371 | 1,
372 | 1.056,
373 | 0.6,
374 | 1.111,
375 | 1,
376 | 1.167,
377 | 1,
378 | 1,
379 | 1.222,
380 | 1,
381 | 1.278,
382 | 0,
383 | 1.333,
384 | 0,
385 | 1,
386 | 1.389,
387 | 0,
388 | 1.444,
389 | 1,
390 | 1.5,
391 | 1,
392 | 1,
393 | 1.556,
394 | 1,
395 | 1.611,
396 | 0.6,
397 | 1.667,
398 | 0.6,
399 | 1,
400 | 1.722,
401 | 0.6,
402 | 1.778,
403 | 1,
404 | 1.833,
405 | 1,
406 | 1,
407 | 1.889,
408 | 1,
409 | 1.944,
410 | 0,
411 | 2,
412 | 0,
413 | 1,
414 | 2.056,
415 | 0,
416 | 2.111,
417 | 1,
418 | 2.167,
419 | 1,
420 | 1,
421 | 2.222,
422 | 1,
423 | 2.278,
424 | 0.6,
425 | 2.333,
426 | 0.6,
427 | 1,
428 | 2.389,
429 | 0.6,
430 | 2.444,
431 | 1,
432 | 2.5,
433 | 1,
434 | 1,
435 | 2.556,
436 | 1,
437 | 2.611,
438 | 0,
439 | 2.667,
440 | 0,
441 | 1,
442 | 2.722,
443 | 0,
444 | 2.778,
445 | 1,
446 | 2.833,
447 | 1,
448 | 1,
449 | 2.889,
450 | 1,
451 | 2.944,
452 | 0.6,
453 | 3,
454 | 0.6,
455 | 1,
456 | 3.056,
457 | 0.6,
458 | 3.111,
459 | 1,
460 | 3.167,
461 | 1
462 | ]
463 | },
464 | {
465 | "Target": "Parameter",
466 | "Id": "ParamBodyAngleX",
467 | "Segments": [
468 | 0,
469 | 0,
470 | 1,
471 | 0.333,
472 | 0,
473 | 0.667,
474 | 2,
475 | 1,
476 | 2,
477 | 1,
478 | 1.356,
479 | 2,
480 | 1.711,
481 | -2,
482 | 2.067,
483 | -2,
484 | 1,
485 | 2.433,
486 | -2,
487 | 2.8,
488 | 0,
489 | 3.167,
490 | 0
491 | ]
492 | },
493 | {
494 | "Target": "Parameter",
495 | "Id": "ParamBodyAngleY",
496 | "Segments": [
497 | 0,
498 | 0,
499 | 1,
500 | 0.056,
501 | 0,
502 | 0.111,
503 | 0,
504 | 0.167,
505 | 0,
506 | 1,
507 | 0.556,
508 | 0,
509 | 0.944,
510 | 5,
511 | 1.333,
512 | 5,
513 | 1,
514 | 1.778,
515 | 5,
516 | 2.222,
517 | 0,
518 | 2.667,
519 | 0,
520 | 0,
521 | 3.167,
522 | 0
523 | ]
524 | },
525 | {
526 | "Target": "Parameter",
527 | "Id": "ParamBodyAngleZ",
528 | "Segments": [
529 | 0,
530 | 0,
531 | 1,
532 | 0.333,
533 | 0,
534 | 0.667,
535 | 2,
536 | 1,
537 | 2,
538 | 1,
539 | 1.356,
540 | 2,
541 | 1.711,
542 | -2,
543 | 2.067,
544 | -2,
545 | 1,
546 | 2.433,
547 | -2,
548 | 2.8,
549 | 0,
550 | 3.167,
551 | 0
552 | ]
553 | },
554 | {
555 | "Target": "Parameter",
556 | "Id": "ParamBreath",
557 | "Segments": [
558 | 0,
559 | 0,
560 | 1,
561 | 0.222,
562 | 0,
563 | 0.444,
564 | 0.167,
565 | 0.667,
566 | 0.5,
567 | 1,
568 | 0.889,
569 | 0.833,
570 | 1.111,
571 | 1,
572 | 1.333,
573 | 1,
574 | 1,
575 | 1.556,
576 | 1,
577 | 1.778,
578 | 0.833,
579 | 2,
580 | 0.5,
581 | 1,
582 | 2.222,
583 | 0.167,
584 | 2.444,
585 | 0,
586 | 2.667,
587 | 0,
588 | 0,
589 | 3.167,
590 | 0
591 | ]
592 | },
593 | {
594 | "Target": "Parameter",
595 | "Id": "ParamArmLA",
596 | "Segments": [
597 | 0,
598 | 0,
599 | 1,
600 | 0.511,
601 | 0,
602 | 1.022,
603 | -3,
604 | 1.533,
605 | -3,
606 | 1,
607 | 2.078,
608 | -3,
609 | 2.622,
610 | 0,
611 | 3.167,
612 | 0
613 | ]
614 | },
615 | {
616 | "Target": "Parameter",
617 | "Id": "ParamArmRA",
618 | "Segments": [
619 | 0,
620 | 0,
621 | 1,
622 | 0.511,
623 | 0,
624 | 1.022,
625 | -3,
626 | 1.533,
627 | -3,
628 | 1,
629 | 2.078,
630 | -3,
631 | 2.622,
632 | 0,
633 | 3.167,
634 | 0
635 | ]
636 | },
637 | {
638 | "Target": "Parameter",
639 | "Id": "ParamBustY",
640 | "Segments": [
641 | 0,
642 | 0,
643 | 0,
644 | 3.167,
645 | 0
646 | ]
647 | },
648 | {
649 | "Target": "Parameter",
650 | "Id": "ParamHairAhoge",
651 | "Segments": [
652 | 0,
653 | 0,
654 | 1,
655 | 0.244,
656 | 0,
657 | 0.489,
658 | 10,
659 | 0.733,
660 | 10,
661 | 1,
662 | 1,
663 | 10,
664 | 1.267,
665 | 6.528,
666 | 1.533,
667 | 0,
668 | 1,
669 | 1.811,
670 | -6.8,
671 | 2.089,
672 | -10,
673 | 2.367,
674 | -10,
675 | 1,
676 | 2.633,
677 | -10,
678 | 2.9,
679 | 0,
680 | 3.167,
681 | 0
682 | ]
683 | },
684 | {
685 | "Target": "Parameter",
686 | "Id": "ParamHairFront",
687 | "Segments": [
688 | 0,
689 | 0,
690 | 1,
691 | 0.244,
692 | 0,
693 | 0.489,
694 | 0.2,
695 | 0.733,
696 | 0.2,
697 | 1,
698 | 1,
699 | 0.2,
700 | 1.267,
701 | 0.131,
702 | 1.533,
703 | 0,
704 | 1,
705 | 1.811,
706 | -0.136,
707 | 2.089,
708 | -0.2,
709 | 2.367,
710 | -0.2,
711 | 1,
712 | 2.633,
713 | -0.2,
714 | 2.9,
715 | 0,
716 | 3.167,
717 | 0
718 | ]
719 | },
720 | {
721 | "Target": "Parameter",
722 | "Id": "ParamHairSide",
723 | "Segments": [
724 | 0,
725 | 0,
726 | 1,
727 | 0.244,
728 | 0,
729 | 0.489,
730 | 0.2,
731 | 0.733,
732 | 0.2,
733 | 1,
734 | 1,
735 | 0.2,
736 | 1.267,
737 | 0.131,
738 | 1.533,
739 | 0,
740 | 1,
741 | 1.811,
742 | -0.136,
743 | 2.089,
744 | -0.2,
745 | 2.367,
746 | -0.2,
747 | 1,
748 | 2.633,
749 | -0.2,
750 | 2.9,
751 | 0,
752 | 3.167,
753 | 0
754 | ]
755 | },
756 | {
757 | "Target": "Parameter",
758 | "Id": "ParamHairBack",
759 | "Segments": [
760 | 0,
761 | 0,
762 | 1,
763 | 0.244,
764 | 0,
765 | 0.489,
766 | 0.2,
767 | 0.733,
768 | 0.2,
769 | 1,
770 | 1,
771 | 0.2,
772 | 1.267,
773 | 0.131,
774 | 1.533,
775 | 0,
776 | 1,
777 | 1.811,
778 | -0.136,
779 | 2.089,
780 | -0.2,
781 | 2.367,
782 | -0.2,
783 | 1,
784 | 2.633,
785 | -0.2,
786 | 2.9,
787 | 0,
788 | 3.167,
789 | 0
790 | ]
791 | },
792 | {
793 | "Target": "Parameter",
794 | "Id": "ParamHairSideUp",
795 | "Segments": [
796 | 0,
797 | 0,
798 | 1,
799 | 0.244,
800 | 0,
801 | 0.489,
802 | 0.2,
803 | 0.733,
804 | 0.2,
805 | 1,
806 | 1,
807 | 0.2,
808 | 1.267,
809 | 0.131,
810 | 1.533,
811 | 0,
812 | 1,
813 | 1.811,
814 | -0.136,
815 | 2.089,
816 | -0.2,
817 | 2.367,
818 | -0.2,
819 | 1,
820 | 2.633,
821 | -0.2,
822 | 2.9,
823 | 0,
824 | 3.167,
825 | 0
826 | ]
827 | },
828 | {
829 | "Target": "Parameter",
830 | "Id": "ParamRibbon",
831 | "Segments": [
832 | 0,
833 | 0,
834 | 1,
835 | 0.244,
836 | 0,
837 | 0.489,
838 | 0.2,
839 | 0.733,
840 | 0.2,
841 | 1,
842 | 1,
843 | 0.2,
844 | 1.267,
845 | 0.131,
846 | 1.533,
847 | 0,
848 | 1,
849 | 1.811,
850 | -0.136,
851 | 2.089,
852 | -0.2,
853 | 2.367,
854 | -0.2,
855 | 1,
856 | 2.633,
857 | -0.2,
858 | 2.9,
859 | 0,
860 | 3.167,
861 | 0
862 | ]
863 | },
864 | {
865 | "Target": "Parameter",
866 | "Id": "ParamSkirt",
867 | "Segments": [
868 | 0,
869 | 0,
870 | 1,
871 | 0.244,
872 | 0,
873 | 0.489,
874 | 0.2,
875 | 0.733,
876 | 0.2,
877 | 1,
878 | 1,
879 | 0.2,
880 | 1.267,
881 | 0.131,
882 | 1.533,
883 | 0,
884 | 1,
885 | 1.811,
886 | -0.136,
887 | 2.089,
888 | -0.2,
889 | 2.367,
890 | -0.2,
891 | 1,
892 | 2.633,
893 | -0.2,
894 | 2.9,
895 | 0,
896 | 3.167,
897 | 0
898 | ]
899 | },
900 | {
901 | "Target": "Parameter",
902 | "Id": "ParamSideUpRibbon",
903 | "Segments": [
904 | 0,
905 | 0,
906 | 1,
907 | 0.244,
908 | 0,
909 | 0.489,
910 | 0.2,
911 | 0.733,
912 | 0.2,
913 | 1,
914 | 1,
915 | 0.2,
916 | 1.267,
917 | 0.131,
918 | 1.533,
919 | 0,
920 | 1,
921 | 1.811,
922 | -0.136,
923 | 2.089,
924 | -0.2,
925 | 2.367,
926 | -0.2,
927 | 1,
928 | 2.633,
929 | -0.2,
930 | 2.9,
931 | 0,
932 | 3.167,
933 | 0
934 | ]
935 | }
936 | ]
937 | }
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/motions/Hiyori_m10.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 4.17,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": false,
8 | "CurveCount": 33,
9 | "TotalSegmentCount": 118,
10 | "TotalPointCount": 321,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "ParamAngleX",
18 | "Segments": [
19 | 0,
20 | 0,
21 | 1,
22 | 0.067,
23 | 0,
24 | 0.133,
25 | 0,
26 | 0.2,
27 | 0,
28 | 1,
29 | 0.4,
30 | 0,
31 | 0.6,
32 | 0,
33 | 0.8,
34 | 0,
35 | 1,
36 | 1.067,
37 | 0,
38 | 1.333,
39 | 1.041,
40 | 1.6,
41 | 1.041,
42 | 1,
43 | 1.844,
44 | 1.041,
45 | 2.089,
46 | -8,
47 | 2.333,
48 | -8,
49 | 1,
50 | 2.656,
51 | -8,
52 | 2.978,
53 | 6,
54 | 3.3,
55 | 6,
56 | 0,
57 | 4.167,
58 | 6
59 | ]
60 | },
61 | {
62 | "Target": "Parameter",
63 | "Id": "ParamAngleY",
64 | "Segments": [
65 | 0,
66 | 0,
67 | 1,
68 | 0.067,
69 | 0,
70 | 0.133,
71 | 0,
72 | 0.2,
73 | 0,
74 | 1,
75 | 0.344,
76 | 0,
77 | 0.489,
78 | -30,
79 | 0.633,
80 | -30,
81 | 0,
82 | 4.167,
83 | -30
84 | ]
85 | },
86 | {
87 | "Target": "Parameter",
88 | "Id": "ParamAngleZ",
89 | "Segments": [
90 | 0,
91 | 0,
92 | 1,
93 | 0.067,
94 | 0,
95 | 0.133,
96 | 0,
97 | 0.2,
98 | 0,
99 | 0,
100 | 4.167,
101 | 0
102 | ]
103 | },
104 | {
105 | "Target": "Parameter",
106 | "Id": "ParamCheek",
107 | "Segments": [
108 | 0,
109 | 0,
110 | 1,
111 | 0.067,
112 | 0,
113 | 0.133,
114 | 0,
115 | 0.2,
116 | 0,
117 | 0,
118 | 4.167,
119 | 0
120 | ]
121 | },
122 | {
123 | "Target": "Parameter",
124 | "Id": "ParamEyeLOpen",
125 | "Segments": [
126 | 0,
127 | 1,
128 | 1,
129 | 0.067,
130 | 1,
131 | 0.133,
132 | 1,
133 | 0.2,
134 | 1,
135 | 1,
136 | 0.311,
137 | 1,
138 | 0.422,
139 | 0.988,
140 | 0.533,
141 | 0.8,
142 | 1,
143 | 0.589,
144 | 0.706,
145 | 0.644,
146 | 0,
147 | 0.7,
148 | 0,
149 | 1,
150 | 0.722,
151 | 0,
152 | 0.744,
153 | 0,
154 | 0.767,
155 | 0,
156 | 1,
157 | 0.822,
158 | 0,
159 | 0.878,
160 | 0.8,
161 | 0.933,
162 | 0.8,
163 | 1,
164 | 1.422,
165 | 0.8,
166 | 1.911,
167 | 0.8,
168 | 2.4,
169 | 0.8,
170 | 1,
171 | 2.456,
172 | 0.8,
173 | 2.511,
174 | 0,
175 | 2.567,
176 | 0,
177 | 1,
178 | 2.589,
179 | 0,
180 | 2.611,
181 | 0,
182 | 2.633,
183 | 0,
184 | 1,
185 | 2.689,
186 | 0,
187 | 2.744,
188 | 0.8,
189 | 2.8,
190 | 0.8,
191 | 0,
192 | 4.167,
193 | 0.8
194 | ]
195 | },
196 | {
197 | "Target": "Parameter",
198 | "Id": "ParamEyeLSmile",
199 | "Segments": [
200 | 0,
201 | 0,
202 | 1,
203 | 0.067,
204 | 0,
205 | 0.133,
206 | 0,
207 | 0.2,
208 | 0,
209 | 0,
210 | 4.167,
211 | 0
212 | ]
213 | },
214 | {
215 | "Target": "Parameter",
216 | "Id": "ParamEyeROpen",
217 | "Segments": [
218 | 0,
219 | 1,
220 | 1,
221 | 0.067,
222 | 1,
223 | 0.133,
224 | 1,
225 | 0.2,
226 | 1,
227 | 1,
228 | 0.311,
229 | 1,
230 | 0.422,
231 | 0.988,
232 | 0.533,
233 | 0.8,
234 | 1,
235 | 0.589,
236 | 0.706,
237 | 0.644,
238 | 0,
239 | 0.7,
240 | 0,
241 | 1,
242 | 0.722,
243 | 0,
244 | 0.744,
245 | 0,
246 | 0.767,
247 | 0,
248 | 1,
249 | 0.822,
250 | 0,
251 | 0.878,
252 | 0.8,
253 | 0.933,
254 | 0.8,
255 | 1,
256 | 1.422,
257 | 0.8,
258 | 1.911,
259 | 0.8,
260 | 2.4,
261 | 0.8,
262 | 1,
263 | 2.456,
264 | 0.8,
265 | 2.511,
266 | 0,
267 | 2.567,
268 | 0,
269 | 1,
270 | 2.589,
271 | 0,
272 | 2.611,
273 | 0,
274 | 2.633,
275 | 0,
276 | 1,
277 | 2.689,
278 | 0,
279 | 2.744,
280 | 0.8,
281 | 2.8,
282 | 0.8,
283 | 0,
284 | 4.167,
285 | 0.8
286 | ]
287 | },
288 | {
289 | "Target": "Parameter",
290 | "Id": "ParamEyeRSmile",
291 | "Segments": [
292 | 0,
293 | 0,
294 | 1,
295 | 0.067,
296 | 0,
297 | 0.133,
298 | 0,
299 | 0.2,
300 | 0,
301 | 1,
302 | 0.278,
303 | 0,
304 | 0.356,
305 | 0,
306 | 0.433,
307 | 0,
308 | 0,
309 | 4.167,
310 | 0
311 | ]
312 | },
313 | {
314 | "Target": "Parameter",
315 | "Id": "ParamEyeBallX",
316 | "Segments": [
317 | 0,
318 | 0,
319 | 1,
320 | 0.067,
321 | 0,
322 | 0.133,
323 | 0,
324 | 0.2,
325 | 0,
326 | 1,
327 | 0.278,
328 | 0,
329 | 0.356,
330 | 0,
331 | 0.433,
332 | 0,
333 | 1,
334 | 0.667,
335 | 0,
336 | 0.9,
337 | 0.004,
338 | 1.133,
339 | -0.01,
340 | 1,
341 | 1.4,
342 | -0.025,
343 | 1.667,
344 | -0.43,
345 | 1.933,
346 | -0.43,
347 | 1,
348 | 2.211,
349 | -0.43,
350 | 2.489,
351 | 0.283,
352 | 2.767,
353 | 0.283,
354 | 0,
355 | 4.167,
356 | 0.283
357 | ]
358 | },
359 | {
360 | "Target": "Parameter",
361 | "Id": "ParamEyeBallY",
362 | "Segments": [
363 | 0,
364 | 0,
365 | 1,
366 | 0.067,
367 | 0,
368 | 0.133,
369 | 0,
370 | 0.2,
371 | 0,
372 | 1,
373 | 0.278,
374 | 0,
375 | 0.356,
376 | -1,
377 | 0.433,
378 | -1,
379 | 0,
380 | 4.167,
381 | -1
382 | ]
383 | },
384 | {
385 | "Target": "Parameter",
386 | "Id": "ParamBrowLY",
387 | "Segments": [
388 | 0,
389 | 0,
390 | 1,
391 | 0.067,
392 | 0,
393 | 0.133,
394 | 0,
395 | 0.2,
396 | 0,
397 | 1,
398 | 0.278,
399 | 0,
400 | 0.356,
401 | 0.19,
402 | 0.433,
403 | 0.19,
404 | 0,
405 | 4.167,
406 | 0.19
407 | ]
408 | },
409 | {
410 | "Target": "Parameter",
411 | "Id": "ParamBrowRY",
412 | "Segments": [
413 | 0,
414 | 0,
415 | 1,
416 | 0.067,
417 | 0,
418 | 0.133,
419 | 0,
420 | 0.2,
421 | 0,
422 | 1,
423 | 0.278,
424 | 0,
425 | 0.356,
426 | 0.11,
427 | 0.433,
428 | 0.11,
429 | 0,
430 | 4.167,
431 | 0.11
432 | ]
433 | },
434 | {
435 | "Target": "Parameter",
436 | "Id": "ParamBrowLX",
437 | "Segments": [
438 | 0,
439 | 0,
440 | 1,
441 | 0.067,
442 | 0,
443 | 0.133,
444 | 0,
445 | 0.2,
446 | 0,
447 | 1,
448 | 0.278,
449 | 0,
450 | 0.356,
451 | -0.48,
452 | 0.433,
453 | -0.48,
454 | 0,
455 | 4.167,
456 | -0.48
457 | ]
458 | },
459 | {
460 | "Target": "Parameter",
461 | "Id": "ParamBrowRX",
462 | "Segments": [
463 | 0,
464 | 0,
465 | 1,
466 | 0.067,
467 | 0,
468 | 0.133,
469 | 0,
470 | 0.2,
471 | 0,
472 | 1,
473 | 0.278,
474 | 0,
475 | 0.356,
476 | 0.29,
477 | 0.433,
478 | 0.29,
479 | 0,
480 | 4.167,
481 | 0.29
482 | ]
483 | },
484 | {
485 | "Target": "Parameter",
486 | "Id": "ParamBrowLAngle",
487 | "Segments": [
488 | 0,
489 | 0,
490 | 1,
491 | 0.067,
492 | 0,
493 | 0.133,
494 | 0,
495 | 0.2,
496 | 0,
497 | 1,
498 | 0.278,
499 | 0,
500 | 0.356,
501 | 1,
502 | 0.433,
503 | 1,
504 | 0,
505 | 4.167,
506 | 1
507 | ]
508 | },
509 | {
510 | "Target": "Parameter",
511 | "Id": "ParamBrowRAngle",
512 | "Segments": [
513 | 0,
514 | 0,
515 | 1,
516 | 0.067,
517 | 0,
518 | 0.133,
519 | 0,
520 | 0.2,
521 | 0,
522 | 1,
523 | 0.278,
524 | 0,
525 | 0.356,
526 | 0.85,
527 | 0.433,
528 | 0.85,
529 | 0,
530 | 4.167,
531 | 0.85
532 | ]
533 | },
534 | {
535 | "Target": "Parameter",
536 | "Id": "ParamBrowLForm",
537 | "Segments": [
538 | 0,
539 | 0,
540 | 1,
541 | 0.067,
542 | 0,
543 | 0.133,
544 | 0,
545 | 0.2,
546 | 0,
547 | 1,
548 | 0.278,
549 | 0,
550 | 0.356,
551 | -0.75,
552 | 0.433,
553 | -0.75,
554 | 0,
555 | 4.167,
556 | -0.75
557 | ]
558 | },
559 | {
560 | "Target": "Parameter",
561 | "Id": "ParamBrowRForm",
562 | "Segments": [
563 | 0,
564 | 0,
565 | 1,
566 | 0.067,
567 | 0,
568 | 0.133,
569 | 0,
570 | 0.2,
571 | 0,
572 | 1,
573 | 0.278,
574 | 0,
575 | 0.356,
576 | -0.87,
577 | 0.433,
578 | -0.87,
579 | 0,
580 | 4.167,
581 | -0.87
582 | ]
583 | },
584 | {
585 | "Target": "Parameter",
586 | "Id": "ParamMouthForm",
587 | "Segments": [
588 | 0,
589 | 1,
590 | 1,
591 | 0.067,
592 | 1,
593 | 0.133,
594 | 1,
595 | 0.2,
596 | 1,
597 | 1,
598 | 0.278,
599 | 1,
600 | 0.356,
601 | -1,
602 | 0.433,
603 | -1,
604 | 0,
605 | 4.167,
606 | -1
607 | ]
608 | },
609 | {
610 | "Target": "Parameter",
611 | "Id": "ParamMouthOpenY",
612 | "Segments": [
613 | 0,
614 | 0,
615 | 1,
616 | 0.067,
617 | 0,
618 | 0.133,
619 | 0,
620 | 0.2,
621 | 0,
622 | 1,
623 | 0.278,
624 | 0,
625 | 0.356,
626 | 1,
627 | 0.433,
628 | 1,
629 | 0,
630 | 4.167,
631 | 1
632 | ]
633 | },
634 | {
635 | "Target": "Parameter",
636 | "Id": "ParamBodyAngleX",
637 | "Segments": [
638 | 0,
639 | 0,
640 | 1,
641 | 0.067,
642 | 0,
643 | 0.133,
644 | 0,
645 | 0.2,
646 | 0,
647 | 1,
648 | 0.444,
649 | 0,
650 | 0.689,
651 | 0,
652 | 0.933,
653 | 0,
654 | 1,
655 | 1.211,
656 | 0,
657 | 1.489,
658 | 0,
659 | 1.767,
660 | 0,
661 | 1,
662 | 2.056,
663 | 0,
664 | 2.344,
665 | -6,
666 | 2.633,
667 | -6,
668 | 1,
669 | 3.033,
670 | -6,
671 | 3.433,
672 | 10,
673 | 3.833,
674 | 10,
675 | 0,
676 | 4.167,
677 | 10
678 | ]
679 | },
680 | {
681 | "Target": "Parameter",
682 | "Id": "ParamBodyAngleY",
683 | "Segments": [
684 | 0,
685 | 0,
686 | 1,
687 | 0.067,
688 | 0,
689 | 0.133,
690 | 0,
691 | 0.2,
692 | 0,
693 | 0,
694 | 4.167,
695 | 0
696 | ]
697 | },
698 | {
699 | "Target": "Parameter",
700 | "Id": "ParamBodyAngleZ",
701 | "Segments": [
702 | 0,
703 | 0,
704 | 1,
705 | 0.067,
706 | 0,
707 | 0.133,
708 | 0,
709 | 0.2,
710 | 0,
711 | 1,
712 | 0.8,
713 | 0,
714 | 1.4,
715 | -2,
716 | 2,
717 | -2,
718 | 1,
719 | 2.456,
720 | -2,
721 | 2.911,
722 | 8.125,
723 | 3.367,
724 | 8.125,
725 | 0,
726 | 4.167,
727 | 8.125
728 | ]
729 | },
730 | {
731 | "Target": "Parameter",
732 | "Id": "ParamBreath",
733 | "Segments": [
734 | 0,
735 | 0,
736 | 1,
737 | 0.067,
738 | 0,
739 | 0.133,
740 | 0,
741 | 0.2,
742 | 0,
743 | 0,
744 | 4.167,
745 | 0
746 | ]
747 | },
748 | {
749 | "Target": "Parameter",
750 | "Id": "ParamShoulder",
751 | "Segments": [
752 | 0,
753 | 0,
754 | 0,
755 | 4.167,
756 | 0
757 | ]
758 | },
759 | {
760 | "Target": "Parameter",
761 | "Id": "ParamLeg",
762 | "Segments": [
763 | 0,
764 | 1,
765 | 1,
766 | 0.667,
767 | 1,
768 | 1.333,
769 | 1,
770 | 2,
771 | 1,
772 | 1,
773 | 2.267,
774 | 1,
775 | 2.533,
776 | 0.948,
777 | 2.8,
778 | 0.948,
779 | 0,
780 | 4.167,
781 | 0.948
782 | ]
783 | },
784 | {
785 | "Target": "Parameter",
786 | "Id": "ParamArmLA",
787 | "Segments": [
788 | 0,
789 | 0,
790 | 1,
791 | 0.067,
792 | 0,
793 | 0.133,
794 | 0,
795 | 0.2,
796 | 0,
797 | 1,
798 | 0.233,
799 | 0,
800 | 0.267,
801 | 0,
802 | 0.3,
803 | 0,
804 | 1,
805 | 0.478,
806 | 0,
807 | 0.656,
808 | -10,
809 | 0.833,
810 | -10,
811 | 1,
812 | 0.922,
813 | -10,
814 | 1.011,
815 | -8.846,
816 | 1.1,
817 | -8.846,
818 | 1,
819 | 1.467,
820 | -8.846,
821 | 1.833,
822 | -8.835,
823 | 2.2,
824 | -9.1,
825 | 1,
826 | 2.622,
827 | -9.405,
828 | 3.044,
829 | -10,
830 | 3.467,
831 | -10,
832 | 0,
833 | 4.167,
834 | -10
835 | ]
836 | },
837 | {
838 | "Target": "Parameter",
839 | "Id": "ParamArmRA",
840 | "Segments": [
841 | 0,
842 | 0,
843 | 1,
844 | 0.067,
845 | 0,
846 | 0.133,
847 | 0,
848 | 0.2,
849 | 0,
850 | 1,
851 | 0.233,
852 | 0,
853 | 0.267,
854 | 0,
855 | 0.3,
856 | 0,
857 | 1,
858 | 0.478,
859 | 0,
860 | 0.656,
861 | -10,
862 | 0.833,
863 | -10,
864 | 1,
865 | 0.922,
866 | -10,
867 | 1.011,
868 | -8.972,
869 | 1.1,
870 | -8.846,
871 | 1,
872 | 1.467,
873 | -8.328,
874 | 1.833,
875 | -8.2,
876 | 2.2,
877 | -8.2,
878 | 1,
879 | 2.622,
880 | -8.2,
881 | 3.044,
882 | -10,
883 | 3.467,
884 | -10,
885 | 0,
886 | 4.167,
887 | -10
888 | ]
889 | },
890 | {
891 | "Target": "Parameter",
892 | "Id": "ParamArmLB",
893 | "Segments": [
894 | 0,
895 | 0,
896 | 0,
897 | 4.167,
898 | 0
899 | ]
900 | },
901 | {
902 | "Target": "Parameter",
903 | "Id": "ParamArmRB",
904 | "Segments": [
905 | 0,
906 | 0,
907 | 0,
908 | 4.167,
909 | 0
910 | ]
911 | },
912 | {
913 | "Target": "Parameter",
914 | "Id": "ParamHairAhoge",
915 | "Segments": [
916 | 0,
917 | 0,
918 | 1,
919 | 0.067,
920 | 0,
921 | 0.133,
922 | 0,
923 | 0.2,
924 | 0,
925 | 1,
926 | 0.233,
927 | 0,
928 | 0.267,
929 | -5,
930 | 0.3,
931 | -5,
932 | 1,
933 | 0.378,
934 | -5,
935 | 0.456,
936 | 10,
937 | 0.533,
938 | 10,
939 | 1,
940 | 0.633,
941 | 10,
942 | 0.733,
943 | 4,
944 | 0.833,
945 | 4,
946 | 0,
947 | 4.167,
948 | 4
949 | ]
950 | },
951 | {
952 | "Target": "PartOpacity",
953 | "Id": "PartArmA",
954 | "Segments": [
955 | 0,
956 | 1,
957 | 0,
958 | 4.17,
959 | 1
960 | ]
961 | },
962 | {
963 | "Target": "PartOpacity",
964 | "Id": "PartArmB",
965 | "Segments": [
966 | 0,
967 | 0,
968 | 0,
969 | 4.17,
970 | 0
971 | ]
972 | }
973 | ]
974 | }
--------------------------------------------------------------------------------
/ChatWithGPT/game/Resources/Hiyori/motions/Hiyori_m07.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 1.9,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": false,
8 | "CurveCount": 32,
9 | "TotalSegmentCount": 121,
10 | "TotalPointCount": 331,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "ParamAngleX",
18 | "Segments": [
19 | 0,
20 | 0,
21 | 1,
22 | 0.111,
23 | 0,
24 | 0.222,
25 | 0,
26 | 0.333,
27 | 0,
28 | 0,
29 | 1.9,
30 | 0
31 | ]
32 | },
33 | {
34 | "Target": "Parameter",
35 | "Id": "ParamAngleY",
36 | "Segments": [
37 | 0,
38 | 0,
39 | 1,
40 | 0.111,
41 | 0,
42 | 0.222,
43 | 0,
44 | 0.333,
45 | 0,
46 | 0,
47 | 1.9,
48 | 0
49 | ]
50 | },
51 | {
52 | "Target": "Parameter",
53 | "Id": "ParamAngleZ",
54 | "Segments": [
55 | 0,
56 | 0,
57 | 1,
58 | 0.111,
59 | 0,
60 | 0.222,
61 | 0,
62 | 0.333,
63 | 0,
64 | 1,
65 | 0.444,
66 | 0,
67 | 0.556,
68 | 8,
69 | 0.667,
70 | 8,
71 | 0,
72 | 1.9,
73 | 8
74 | ]
75 | },
76 | {
77 | "Target": "Parameter",
78 | "Id": "ParamCheek",
79 | "Segments": [
80 | 0,
81 | 0,
82 | 1,
83 | 0.111,
84 | 0,
85 | 0.222,
86 | 0,
87 | 0.333,
88 | 0,
89 | 0,
90 | 1.9,
91 | 0
92 | ]
93 | },
94 | {
95 | "Target": "Parameter",
96 | "Id": "ParamEyeLOpen",
97 | "Segments": [
98 | 0,
99 | 1,
100 | 1,
101 | 0.111,
102 | 1,
103 | 0.222,
104 | 1,
105 | 0.333,
106 | 1,
107 | 1,
108 | 0.378,
109 | 1,
110 | 0.422,
111 | 0,
112 | 0.467,
113 | 0,
114 | 1,
115 | 0.522,
116 | 0,
117 | 0.578,
118 | 1.2,
119 | 0.633,
120 | 1.2,
121 | 1,
122 | 0.744,
123 | 1.2,
124 | 0.856,
125 | 1.2,
126 | 0.967,
127 | 1.2,
128 | 1,
129 | 0.989,
130 | 1.2,
131 | 1.011,
132 | 0,
133 | 1.033,
134 | 0,
135 | 1,
136 | 1.067,
137 | 0,
138 | 1.1,
139 | 1.2,
140 | 1.133,
141 | 1.2,
142 | 1,
143 | 1.167,
144 | 1.2,
145 | 1.2,
146 | 1.2,
147 | 1.233,
148 | 1.2,
149 | 1,
150 | 1.267,
151 | 1.2,
152 | 1.3,
153 | 0,
154 | 1.333,
155 | 0,
156 | 1,
157 | 1.356,
158 | 0,
159 | 1.378,
160 | 1.2,
161 | 1.4,
162 | 1.2,
163 | 0,
164 | 1.9,
165 | 1.2
166 | ]
167 | },
168 | {
169 | "Target": "Parameter",
170 | "Id": "ParamEyeLSmile",
171 | "Segments": [
172 | 0,
173 | 0,
174 | 1,
175 | 0.111,
176 | 0,
177 | 0.222,
178 | 0,
179 | 0.333,
180 | 0,
181 | 0,
182 | 1.9,
183 | 0
184 | ]
185 | },
186 | {
187 | "Target": "Parameter",
188 | "Id": "ParamEyeROpen",
189 | "Segments": [
190 | 0,
191 | 1,
192 | 1,
193 | 0.111,
194 | 1,
195 | 0.222,
196 | 1,
197 | 0.333,
198 | 1,
199 | 1,
200 | 0.378,
201 | 1,
202 | 0.422,
203 | 0,
204 | 0.467,
205 | 0,
206 | 1,
207 | 0.522,
208 | 0,
209 | 0.578,
210 | 1.2,
211 | 0.633,
212 | 1.2,
213 | 1,
214 | 0.744,
215 | 1.2,
216 | 0.856,
217 | 1.2,
218 | 0.967,
219 | 1.2,
220 | 1,
221 | 0.989,
222 | 1.2,
223 | 1.011,
224 | 0,
225 | 1.033,
226 | 0,
227 | 1,
228 | 1.067,
229 | 0,
230 | 1.1,
231 | 1.2,
232 | 1.133,
233 | 1.2,
234 | 1,
235 | 1.167,
236 | 1.2,
237 | 1.2,
238 | 1.2,
239 | 1.233,
240 | 1.2,
241 | 1,
242 | 1.267,
243 | 1.2,
244 | 1.3,
245 | 0,
246 | 1.333,
247 | 0,
248 | 1,
249 | 1.356,
250 | 0,
251 | 1.378,
252 | 1.2,
253 | 1.4,
254 | 1.2,
255 | 0,
256 | 1.9,
257 | 1.2
258 | ]
259 | },
260 | {
261 | "Target": "Parameter",
262 | "Id": "ParamEyeRSmile",
263 | "Segments": [
264 | 0,
265 | 0,
266 | 1,
267 | 0.111,
268 | 0,
269 | 0.222,
270 | 0,
271 | 0.333,
272 | 0,
273 | 1,
274 | 0.356,
275 | 0,
276 | 0.378,
277 | 0,
278 | 0.4,
279 | 0,
280 | 1,
281 | 0.489,
282 | 0,
283 | 0.578,
284 | 0,
285 | 0.667,
286 | 0,
287 | 0,
288 | 1.9,
289 | 0
290 | ]
291 | },
292 | {
293 | "Target": "Parameter",
294 | "Id": "ParamEyeBallX",
295 | "Segments": [
296 | 0,
297 | 0,
298 | 1,
299 | 0.111,
300 | 0,
301 | 0.222,
302 | 0,
303 | 0.333,
304 | 0,
305 | 1,
306 | 0.356,
307 | 0,
308 | 0.378,
309 | 0,
310 | 0.4,
311 | 0,
312 | 1,
313 | 0.489,
314 | 0,
315 | 0.578,
316 | 0,
317 | 0.667,
318 | 0,
319 | 0,
320 | 1.9,
321 | 0
322 | ]
323 | },
324 | {
325 | "Target": "Parameter",
326 | "Id": "ParamEyeBallY",
327 | "Segments": [
328 | 0,
329 | 0,
330 | 1,
331 | 0.111,
332 | 0,
333 | 0.222,
334 | 0,
335 | 0.333,
336 | 0,
337 | 1,
338 | 0.356,
339 | 0,
340 | 0.378,
341 | 0,
342 | 0.4,
343 | 0,
344 | 1,
345 | 0.489,
346 | 0,
347 | 0.578,
348 | 0,
349 | 0.667,
350 | 0,
351 | 0,
352 | 1.9,
353 | 0
354 | ]
355 | },
356 | {
357 | "Target": "Parameter",
358 | "Id": "ParamBrowLY",
359 | "Segments": [
360 | 0,
361 | 0,
362 | 1,
363 | 0.111,
364 | 0,
365 | 0.222,
366 | 0,
367 | 0.333,
368 | 0,
369 | 1,
370 | 0.356,
371 | 0,
372 | 0.378,
373 | 0,
374 | 0.4,
375 | 0,
376 | 1,
377 | 0.489,
378 | 0,
379 | 0.578,
380 | 0.26,
381 | 0.667,
382 | 0.26,
383 | 0,
384 | 1.9,
385 | 0.26
386 | ]
387 | },
388 | {
389 | "Target": "Parameter",
390 | "Id": "ParamBrowRY",
391 | "Segments": [
392 | 0,
393 | 0,
394 | 1,
395 | 0.111,
396 | 0,
397 | 0.222,
398 | 0,
399 | 0.333,
400 | 0,
401 | 1,
402 | 0.356,
403 | 0,
404 | 0.378,
405 | 0,
406 | 0.4,
407 | 0,
408 | 1,
409 | 0.489,
410 | 0,
411 | 0.578,
412 | 0.36,
413 | 0.667,
414 | 0.36,
415 | 0,
416 | 1.9,
417 | 0.36
418 | ]
419 | },
420 | {
421 | "Target": "Parameter",
422 | "Id": "ParamBrowLX",
423 | "Segments": [
424 | 0,
425 | 0,
426 | 1,
427 | 0.111,
428 | 0,
429 | 0.222,
430 | 0,
431 | 0.333,
432 | 0,
433 | 1,
434 | 0.356,
435 | 0,
436 | 0.378,
437 | 0,
438 | 0.4,
439 | 0,
440 | 1,
441 | 0.489,
442 | 0,
443 | 0.578,
444 | 0,
445 | 0.667,
446 | 0,
447 | 0,
448 | 1.9,
449 | 0
450 | ]
451 | },
452 | {
453 | "Target": "Parameter",
454 | "Id": "ParamBrowRX",
455 | "Segments": [
456 | 0,
457 | 0,
458 | 1,
459 | 0.111,
460 | 0,
461 | 0.222,
462 | 0,
463 | 0.333,
464 | 0,
465 | 1,
466 | 0.356,
467 | 0,
468 | 0.378,
469 | 0,
470 | 0.4,
471 | 0,
472 | 1,
473 | 0.489,
474 | 0,
475 | 0.578,
476 | 0.27,
477 | 0.667,
478 | 0.27,
479 | 0,
480 | 1.9,
481 | 0.27
482 | ]
483 | },
484 | {
485 | "Target": "Parameter",
486 | "Id": "ParamBrowLAngle",
487 | "Segments": [
488 | 0,
489 | 0,
490 | 1,
491 | 0.111,
492 | 0,
493 | 0.222,
494 | 0,
495 | 0.333,
496 | 0,
497 | 1,
498 | 0.356,
499 | 0,
500 | 0.378,
501 | 0,
502 | 0.4,
503 | 0,
504 | 1,
505 | 0.489,
506 | 0,
507 | 0.578,
508 | 0.26,
509 | 0.667,
510 | 0.26,
511 | 0,
512 | 1.9,
513 | 0.26
514 | ]
515 | },
516 | {
517 | "Target": "Parameter",
518 | "Id": "ParamBrowRAngle",
519 | "Segments": [
520 | 0,
521 | 0,
522 | 1,
523 | 0.111,
524 | 0,
525 | 0.222,
526 | 0,
527 | 0.333,
528 | 0,
529 | 1,
530 | 0.356,
531 | 0,
532 | 0.378,
533 | 0,
534 | 0.4,
535 | 0,
536 | 1,
537 | 0.489,
538 | 0,
539 | 0.578,
540 | -0.03,
541 | 0.667,
542 | -0.03,
543 | 0,
544 | 1.9,
545 | -0.03
546 | ]
547 | },
548 | {
549 | "Target": "Parameter",
550 | "Id": "ParamBrowLForm",
551 | "Segments": [
552 | 0,
553 | 0,
554 | 1,
555 | 0.111,
556 | 0,
557 | 0.222,
558 | 0,
559 | 0.333,
560 | 0,
561 | 1,
562 | 0.356,
563 | 0,
564 | 0.378,
565 | 0,
566 | 0.4,
567 | 0,
568 | 1,
569 | 0.489,
570 | 0,
571 | 0.578,
572 | 0.33,
573 | 0.667,
574 | 0.33,
575 | 0,
576 | 1.9,
577 | 0.33
578 | ]
579 | },
580 | {
581 | "Target": "Parameter",
582 | "Id": "ParamBrowRForm",
583 | "Segments": [
584 | 0,
585 | 0,
586 | 1,
587 | 0.111,
588 | 0,
589 | 0.222,
590 | 0,
591 | 0.333,
592 | 0,
593 | 1,
594 | 0.356,
595 | 0,
596 | 0.378,
597 | 0,
598 | 0.4,
599 | 0,
600 | 1,
601 | 0.489,
602 | 0,
603 | 0.578,
604 | 0.21,
605 | 0.667,
606 | 0.21,
607 | 0,
608 | 1.9,
609 | 0.21
610 | ]
611 | },
612 | {
613 | "Target": "Parameter",
614 | "Id": "ParamMouthForm",
615 | "Segments": [
616 | 0,
617 | 1,
618 | 1,
619 | 0.111,
620 | 1,
621 | 0.222,
622 | 1,
623 | 0.333,
624 | 1,
625 | 1,
626 | 0.356,
627 | 1,
628 | 0.378,
629 | 1,
630 | 0.4,
631 | 1,
632 | 1,
633 | 0.489,
634 | 1,
635 | 0.578,
636 | -2,
637 | 0.667,
638 | -2,
639 | 0,
640 | 1.9,
641 | -2
642 | ]
643 | },
644 | {
645 | "Target": "Parameter",
646 | "Id": "ParamMouthOpenY",
647 | "Segments": [
648 | 0,
649 | 0,
650 | 1,
651 | 0.111,
652 | 0,
653 | 0.222,
654 | 0,
655 | 0.333,
656 | 0,
657 | 1,
658 | 0.356,
659 | 0,
660 | 0.378,
661 | 0,
662 | 0.4,
663 | 0,
664 | 1,
665 | 0.489,
666 | 0,
667 | 0.578,
668 | 0.75,
669 | 0.667,
670 | 0.75,
671 | 0,
672 | 1.9,
673 | 0.75
674 | ]
675 | },
676 | {
677 | "Target": "Parameter",
678 | "Id": "ParamBodyAngleX",
679 | "Segments": [
680 | 0,
681 | 0,
682 | 1,
683 | 0.111,
684 | 0,
685 | 0.222,
686 | 0,
687 | 0.333,
688 | 0,
689 | 1,
690 | 0.444,
691 | 0,
692 | 0.556,
693 | -6,
694 | 0.667,
695 | -6,
696 | 0,
697 | 1.9,
698 | -6
699 | ]
700 | },
701 | {
702 | "Target": "Parameter",
703 | "Id": "ParamBodyAngleY",
704 | "Segments": [
705 | 0,
706 | 0,
707 | 1,
708 | 0.111,
709 | 0,
710 | 0.222,
711 | 0,
712 | 0.333,
713 | 0,
714 | 1,
715 | 0.422,
716 | 0,
717 | 0.511,
718 | 10,
719 | 0.6,
720 | 10,
721 | 1,
722 | 0.667,
723 | 10,
724 | 0.733,
725 | -6,
726 | 0.8,
727 | -6,
728 | 1,
729 | 0.833,
730 | -6,
731 | 0.867,
732 | 5,
733 | 0.9,
734 | 5,
735 | 1,
736 | 1.011,
737 | 5,
738 | 1.122,
739 | 0,
740 | 1.233,
741 | 0,
742 | 0,
743 | 1.9,
744 | 0
745 | ]
746 | },
747 | {
748 | "Target": "Parameter",
749 | "Id": "ParamBodyAngleZ",
750 | "Segments": [
751 | 0,
752 | 0,
753 | 1,
754 | 0.111,
755 | 0,
756 | 0.222,
757 | 0,
758 | 0.333,
759 | 0,
760 | 1,
761 | 0.444,
762 | 0,
763 | 0.556,
764 | -3,
765 | 0.667,
766 | -3,
767 | 0,
768 | 1.9,
769 | -3
770 | ]
771 | },
772 | {
773 | "Target": "Parameter",
774 | "Id": "ParamBreath",
775 | "Segments": [
776 | 0,
777 | 0,
778 | 1,
779 | 0.111,
780 | 0,
781 | 0.222,
782 | 0,
783 | 0.333,
784 | 0,
785 | 0,
786 | 1.9,
787 | 0
788 | ]
789 | },
790 | {
791 | "Target": "Parameter",
792 | "Id": "ParamShoulder",
793 | "Segments": [
794 | 0,
795 | -0.062,
796 | 1,
797 | 0.111,
798 | -0.062,
799 | 0.222,
800 | -0.103,
801 | 0.333,
802 | 0,
803 | 1,
804 | 0.589,
805 | 0.238,
806 | 0.844,
807 | 1,
808 | 1.1,
809 | 1,
810 | 0,
811 | 1.9,
812 | 1
813 | ]
814 | },
815 | {
816 | "Target": "Parameter",
817 | "Id": "ParamArmLA",
818 | "Segments": [
819 | 0,
820 | 0,
821 | 1,
822 | 0.111,
823 | 0,
824 | 0.222,
825 | 0,
826 | 0.333,
827 | 0,
828 | 1,
829 | 0.478,
830 | 0,
831 | 0.622,
832 | -10,
833 | 0.767,
834 | -10,
835 | 1,
836 | 0.811,
837 | -10,
838 | 0.856,
839 | -8.2,
840 | 0.9,
841 | -8.2,
842 | 0,
843 | 1.9,
844 | -8.2
845 | ]
846 | },
847 | {
848 | "Target": "Parameter",
849 | "Id": "ParamArmRA",
850 | "Segments": [
851 | 0,
852 | 0,
853 | 1,
854 | 0.111,
855 | 0,
856 | 0.222,
857 | 0,
858 | 0.333,
859 | 0,
860 | 1,
861 | 0.478,
862 | 0,
863 | 0.622,
864 | -10,
865 | 0.767,
866 | -10,
867 | 1,
868 | 0.811,
869 | -10,
870 | 0.856,
871 | -7.2,
872 | 0.9,
873 | -7.2,
874 | 0,
875 | 1.9,
876 | -7.2
877 | ]
878 | },
879 | {
880 | "Target": "Parameter",
881 | "Id": "ParamArmLB",
882 | "Segments": [
883 | 0,
884 | 0,
885 | 1,
886 | 0.111,
887 | 0,
888 | 0.222,
889 | 0,
890 | 0.333,
891 | 0,
892 | 0,
893 | 1.9,
894 | 0
895 | ]
896 | },
897 | {
898 | "Target": "Parameter",
899 | "Id": "ParamArmRB",
900 | "Segments": [
901 | 0,
902 | 0,
903 | 1,
904 | 0.111,
905 | 0,
906 | 0.222,
907 | 0,
908 | 0.333,
909 | 0,
910 | 0,
911 | 1.9,
912 | 0
913 | ]
914 | },
915 | {
916 | "Target": "Parameter",
917 | "Id": "ParamHairAhoge",
918 | "Segments": [
919 | 0,
920 | 0,
921 | 1,
922 | 0.111,
923 | 0,
924 | 0.222,
925 | 1.9,
926 | 0.333,
927 | 5.2,
928 | 1,
929 | 0.444,
930 | 8.5,
931 | 0.556,
932 | 9.926,
933 | 0.667,
934 | 9.926,
935 | 1,
936 | 0.744,
937 | 9.926,
938 | 0.822,
939 | -10,
940 | 0.9,
941 | -10,
942 | 1,
943 | 0.956,
944 | -10,
945 | 1.011,
946 | 6,
947 | 1.067,
948 | 6,
949 | 1,
950 | 1.144,
951 | 6,
952 | 1.222,
953 | -4,
954 | 1.3,
955 | -4,
956 | 1,
957 | 1.367,
958 | -4,
959 | 1.433,
960 | 0,
961 | 1.5,
962 | 0,
963 | 0,
964 | 1.9,
965 | 0
966 | ]
967 | },
968 | {
969 | "Target": "PartOpacity",
970 | "Id": "PartArmA",
971 | "Segments": [
972 | 0,
973 | 1,
974 | 0,
975 | 1.9,
976 | 1
977 | ]
978 | },
979 | {
980 | "Target": "PartOpacity",
981 | "Id": "PartArmB",
982 | "Segments": [
983 | 0,
984 | 0,
985 | 0,
986 | 1.9,
987 | 0
988 | ]
989 | }
990 | ]
991 | }
--------------------------------------------------------------------------------