Compare commits

...
384 Commits
Author SHA1 Message Date
erew123 6c20f45154 Add files via upload 2024-03-28 21:51:42 +00:00
erew123 97cda27c7e Delete finetune/put-voice-samples-in-here directory 2024-03-28 21:51:11 +00:00
erew123 a075495a0a Large Update
TTS Generator - Various interface bugs & filtering options cleaned up.
TTS Generator - TTSDiff now scans generated text and TTS for errors.
TTS Generator - TTSSRT now creates subtitle files for video production e.g. a Youtube video.
Finetune - Now uses a customised tokenizer to deal with Japanese.
Finetune - Pre flight check and warning messages.
Finetune - Extra documentation and warnings.
Entire file structure has been re-organised to simplify management and future changes.
Documentation (built in and Github) has been rewritten/tidied up.
Requirements files have been cleaned up and simplified.
ATsetup has been re-written as necessary with additional options.
DeepSpeed moved up to version 14.
Standalone Application moved to PyTorch 2.2.1.
Nvidia CUDA Toolkit installation is NO LONGER needed (other than to compile DeepSpeed on Linux)

Tested on Linux and Windows.
2024-03-28 21:49:33 +00:00
erew123 b205657be3 Delete finetune/compact.py 2024-03-28 21:38:03 +00:00
erew123 483d6c8e79 Delete harvard_sentences.txt 2024-03-28 21:37:52 +00:00
erew123 9bd4665e6b Delete languages.json 2024-03-28 21:37:45 +00:00
erew123 62e1ab7e89 Delete requirements_other.txt 2024-03-28 21:37:35 +00:00
erew123 740c54db1c Delete requirements_nvidia.txt 2024-03-28 21:37:27 +00:00
erew123 e188467730 Delete requirements_finetune.txt 2024-03-28 21:37:12 +00:00
erew123 743f23240e Delete templates directory 2024-03-28 21:36:51 +00:00
erew123 66dadbca25 Finetune - further tidy up
Amended instructions.
Tidied up Pre-Flight check.
Added  dropdowns refresh button for step 3.
2024-03-25 14:09:35 +00:00
erew123 8125b46dbe Update README.md 2024-03-24 14:38:08 +00:00
erew123 d4bd46f203 Update README.md 2024-03-24 14:00:14 +00:00
erew123 f13d6d336b Update README.md 2024-03-24 11:37:33 +00:00
erew123 1fa2f2e110 Update README.md 2024-03-24 11:16:45 +00:00
erew123 9ad4005e52 Update bug-report-support-request.md 2024-03-23 23:06:59 +00:00
erew123 6d6b92d4b2 Update README.md 2024-03-23 12:18:09 +00:00
erew123 bf5d913cae Delete Deepspeed-Windows directory 2024-03-23 12:03:21 +00:00
erew123 f52ccd3931 Update README.md 2024-03-23 11:57:13 +00:00
erew123 37e7c8002d Update README.md 2024-03-22 17:23:12 +00:00
erew123 ad7382ee68 Update README.md 2024-03-22 14:53:28 +00:00
erew123 2428bfe357 Update README.md 2024-03-22 13:59:00 +00:00
erew123 74f3acc51f Update README.md
Large documentation update
2024-03-22 13:53:28 +00:00
erew123 90a98f140b Update ttsgencomp.py 2024-03-20 16:56:59 +00:00
erew123 885311ecd8 ttsgencomp added --threshold
gives a little flexibility to deal with words that sound the same when transcribed.
2024-03-20 16:28:15 +00:00
erew123 c2952e9758 Add files via upload 2024-03-20 15:50:02 +00:00
erew123 7e6e18c6d9 TTSGEN Compare - Work in progress
A BETA test/Proof of concept script to compare Speech that was generated in TTS Generator to the original Text and flag issues.

Anyone reading this, you are welcome to try it, the readme instructions are in the folder, however, I am not providing support on this while it is BETA/Proof of concept.
2024-03-20 15:26:36 +00:00
erew123 47eafafeda Update README.md 2024-03-19 12:35:15 +00:00
erew123 5edaab1356 Update README.md 2024-03-19 12:20:44 +00:00
erew123 7bde34d2ce Update README.md 2024-03-19 12:03:32 +00:00
erew123 0aa4638f68 Update README.md 2024-03-19 11:54:50 +00:00
erew123 22dd9c741c Update README.md 2024-03-19 11:51:03 +00:00
erew123 e000b8bb87 Update README.md 2024-03-19 11:10:00 +00:00
erew123 2d26f309df Update README.md 2024-03-19 11:06:04 +00:00
erew123 22d3e53a28 Update bug-report-support-request.md 2024-03-19 10:42:56 +00:00
erew123 0ea646dbf3 Update bug-report-support-request.md 2024-03-19 10:41:42 +00:00
erew123 282e3ce84c Update bug-report-support-request.md 2024-03-19 10:41:04 +00:00
erew123 772afd47a1 Update README.md 2024-03-19 10:11:29 +00:00
erew123 1612835c5d Update README.md 2024-03-19 09:55:50 +00:00
erew123 ea551d3a84 ID Playing reset on stop - corrected
Corrected the ID playing from resetting when the Stop button is pressed.
2024-03-17 12:51:41 +00:00
erew123 47001203cd Added DeepSpeed v14 for CUDA 11.8 w/PT 2.2.1 2024-03-16 13:21:25 +00:00
erew123 27ff5a12b0 Delete templates/tokenizer/__pycache__ directory 2024-03-16 11:16:01 +00:00
erew123 0a89407e4d Custom tokenizer for Japanese
Replaces the standard TTS tokenizer within Finetuning.
2024-03-16 11:15:01 +00:00
erew123 a579c5e6d2 Additional checks, documentation & tokenizer
Added warnings if PFC is not passed.
Added a custom tokenizer to better handle Japanese.
2024-03-16 11:14:07 +00:00
erew123 5a21d14672 Update atsetup.bat
TTS version updated to 0.22.0
2024-03-16 02:35:58 +00:00
erew123 f4f5f82bb0 Update atsetup.sh
TTS version updated to 0.22.0
2024-03-16 02:35:39 +00:00
erew123 7b03804f9e Finetune updated
Now uses TTS 0.22.0
Pre-flight check system & help documentation.
Cleaned up the interface a little
More yet to do re documentation.
2024-03-16 02:34:17 +00:00
erew123 f46493e6d8 Updated diagnostic checks
Added a few additional checks
Simplified screen output
Cleaned up log file output
2024-03-15 02:14:58 +00:00
erew123 2a64f6ad2b Merge pull request #127 from arthurwolf/arthurwolf-patch-2-clint-cleaned
Added a cleaned up version of the Clint Eastwood file.
2024-03-14 19:21:04 +00:00
erew123 3368f8b016 Merge pull request #126 from arthurwolf/patch-1
Add note about the project's rate.
2024-03-14 19:19:57 +00:00
Arthur Wolf 121585ae84 Update Clint_Eastwood CC3.txt to mention the updated file. 2024-03-14 14:53:40 +01:00
Arthur Wolf 3e6c11740d Uploading new version of the enhanced clint file, with correct bitrate.
Previous version of the file had wrong bitrate.
2024-03-14 14:51:06 +01:00
Arthur Wolf 6b111494b3 Delete voices/Clint_Eastwood CC3 (enhanced).wav
It had the wrong bitrate, replacing.
2024-03-14 14:50:35 +01:00
Arthur Wolf b376a27da2 Added a cleaned up version of the Clint Eastwood file.
As it's a derivative of the original file, it's automatically under the same license.
2024-03-14 14:42:41 +01:00
Arthur Wolf eeec4de703 Add note about the project's rate.
If this is not set correctly, the file will be saved as the incorrect rate despite the resampling (had to search docs for 30 minutes before solving this one...)
2024-03-14 14:07:45 +01:00
erew123 49f98033b3 Added a few extra notes to instructions 2024-03-13 20:15:40 +00:00
erew123 c1470930f4 Update README.md 2024-03-13 09:26:00 +00:00
erew123 1dec4f027b Added Windows DeepSpeed update for PyTorch 2.2.1 2024-03-12 11:34:35 +00:00
erew123 a9ef8edcb4 Update README.md 2024-03-11 13:33:01 +00:00
erew123 299238be7d Update README.md 2024-03-11 13:13:26 +00:00
erew123 29c7ea1526 Update README.md 2024-03-11 13:00:33 +00:00
erew123 e974e14a10 Links update
Just a minor update to make the links to TTS generator dynamic
2024-03-11 12:51:56 +00:00
erew123 59c654bacd Update README.md 2024-03-11 12:21:58 +00:00
erew123 969b4e3f46 Text-gen-webui - SD Image filtering
AllTalk will now strip any image from TTS and re-add the image data after TTS. 

This is so that when used with Stable Diffusion Image generation within Text-generation-webui, AllTalk isnt trying to generate the Image data as TTS.
2024-03-11 11:22:50 +00:00
erew123 86c64fc9ba Documentation & Japanese support
Improved some areas of the documentation to clarify some issues.
Dropped worker threads down ONLY when Japanese is used, due to limitations of the translation.
2024-03-10 15:17:31 +00:00
erew123 b8c0db6f56 Merge pull request #114 from johnbenac/16_to_32_for_1070
Made compatible with older GPUs (1070)
2024-03-10 15:12:42 +00:00
erew123 57982cb810 Update README.md 2024-03-10 14:54:47 +00:00
erew123 6387007f56 Update README.md 2024-03-10 14:53:26 +00:00
erew123 cdf8d695e2 Update README.md 2024-03-10 14:45:20 +00:00
erew123 833bf3da4f Update README.md 2024-03-10 13:52:41 +00:00
erew123 f68086db0b Update requirements_finetune.txt 2024-03-10 11:58:27 +00:00
johnbenac 1f7842ef5a Made compatible with older GPUs (1070) 2024-03-09 20:42:01 -05:00
erew123 9bb0d1fa58 Update README.md 2024-03-04 09:34:55 +00:00
erew123 015b9033ec Additional updates re chinese
CJK Symbols and Punctuation range u3000 > u303F
2024-02-21 20:58:57 +00:00
erew123 7f261bb5e9 Attempt to allow Chinese character set through 2024-02-21 12:24:11 +00:00
erew123 00b93cfe1b explicit allowance for ć, ś, ń, ł etc 2024-02-07 12:44:42 +00:00
erew123 c0d01ee931 Update tts_server.py 2024-02-05 14:05:49 +00:00
erew123 d0ceb2bb65 Update atsetup.sh 2024-01-30 11:37:23 +00:00
erew123 3231e61d56 Bumped transformers requirements >=4.37.1
Now transformers is fixed, bumped requirements up to skip 4.37.0
2024-01-30 11:36:37 +00:00
erew123 32f3b721c2 Update README.md 2024-01-24 17:06:26 +00:00
erew123 8c588939d2 Merge pull request #86 from erew123/dev
merge main > dev
2024-01-23 14:24:57 +00:00
erew123 ff1077f282 Update docker-compose-cuda.yml 2024-01-23 13:25:37 +00:00
erew123 36d0e92ed9 Update docker-compose.yml 2024-01-23 13:25:09 +00:00
erew123 8dfb84d7e2 Merge pull request #83 from Josh-XT/main
Standalone Docker Container
2024-01-23 13:05:38 +00:00
erew123 4caecdc5eb Merge pull request #85 from erew123/main
main to dev merge
2024-01-23 13:01:56 +00:00
Josh XT 40f2fbf54e Merge branch 'erew123:main' into main 2024-01-23 06:57:54 -05:00
erew123 ab37dd8849 Update README.md 2024-01-23 11:45:29 +00:00
erew123 03b02e0e4c Update README.md 2024-01-23 11:18:42 +00:00
Josh XT 351f46c7b5 Merge branch 'erew123:main' into main 2024-01-22 21:20:17 -05:00
Josh XT 71ba584e7c Add voices 2024-01-22 21:15:29 -05:00
Josh XT b3f53e93cc fix typo 2024-01-22 20:46:53 -05:00
Josh XT 0ed3cb75b5 Add modeldownload 2024-01-22 20:44:18 -05:00
Josh XT c29de18ad4 add chmod 2024-01-22 19:41:18 -05:00
Josh XT ec1d0e8c5d Check if running in docker 2024-01-22 19:26:23 -05:00
Josh XT 12bf008b3f Run back end without subprocess 2024-01-22 19:15:54 -05:00
erew123 ecdc10ece5 Update atsetup.bat 2024-01-22 23:27:55 +00:00
Josh XT 360f70cb0a Disable deepspeed 2024-01-22 18:10:20 -05:00
Josh XT 51c91c3d70 Fix config 2024-01-22 17:35:21 -05:00
Josh XT 81a9f4c847 Persist config 2024-01-22 17:33:02 -05:00
Josh XT cdce7511dc Use deepspeed 2024-01-22 17:31:41 -05:00
erew123 6d4b6d336b Update README.md 2024-01-22 22:30:47 +00:00
erew123 6c4a9b19c7 Update README.md 2024-01-22 22:21:21 +00:00
erew123 82ecf3eecc Update README.md 2024-01-22 22:18:16 +00:00
Josh XT d750959f52 Add docker-compose 2024-01-22 17:04:28 -05:00
Josh XT bd74de53da Add portaudio19-dev 2024-01-22 16:53:08 -05:00
Josh XT fcec9d8f5b Fix python alias 2024-01-22 16:32:30 -05:00
Josh XT 85e5e6ab86 Merge branch 'erew123:main' into main 2024-01-22 16:06:30 -05:00
Josh XT d15931bdda 3 2024-01-22 15:54:46 -05:00
erew123 abc9cf1fb7 Update README.md 2024-01-22 20:45:11 +00:00
erew123 2b60f5b0da Update requirements_other.txt 2024-01-22 20:01:16 +00:00
erew123 e524063ec2 Update requirements_nvidia.txt 2024-01-22 20:01:04 +00:00
erew123 d93906a75f Update atsetup.sh 2024-01-22 20:00:47 +00:00
erew123 ad57deed20 Update atsetup.bat 2024-01-22 20:00:21 +00:00
erew123 d0866e3c6c Update README.md 2024-01-22 19:16:54 +00:00
erew123 af907a299d Update requirements_other.txt 2024-01-22 18:56:50 +00:00
erew123 7928af1bb7 Update requirements_nvidia.txt 2024-01-22 18:56:39 +00:00
erew123 4d837a0219 Update atsetup.sh
force     pip install transformers==4.36.2
2024-01-22 18:56:11 +00:00
erew123 e50817a234 Update atsetup.bat
force install of transformers pip install transformers==4.36.2
2024-01-22 18:55:45 +00:00
Josh XT c3bb58d2af Update dockerhub 2024-01-22 12:15:10 -05:00
Josh XT c17959f142 Add dockerhub publish 2024-01-22 12:12:22 -05:00
Josh XT def2d51c5f Use ubuntu 2024-01-22 11:54:29 -05:00
Josh XT 6166d4f751 No arm support 2024-01-22 11:52:41 -05:00
Josh XT cd164ae258 Updates 2024-01-22 11:49:10 -05:00
Josh XT f089e3e85b Add multi build 2024-01-22 11:45:55 -05:00
Josh XT d008c7ab0a Move install 2024-01-22 11:27:35 -05:00
Josh XT a199adfbd6 Add deps 2024-01-22 11:24:54 -05:00
Josh XT 61998b4d39 Set to nvidia 2024-01-22 11:21:15 -05:00
Josh XT 55799b2de8 Add workflow 2024-01-22 10:54:14 -05:00
Josh XT ece55ffe06 Create Dockerfile 2024-01-22 10:46:10 -05:00
erew123 dbc2582fa6 Update README.md 2024-01-21 13:05:35 +00:00
erew123 535c9b652a Update README.md 2024-01-21 12:53:04 +00:00
erew123 6c28d58b4a Update README.md 2024-01-21 12:23:53 +00:00
erew123 c9a222932c Update README.md 2024-01-21 12:22:14 +00:00
erew123 7010369966 Added startup_wait_time to top of script
Making it simple for people to adjust the allowed start-up time
2024-01-21 12:20:29 +00:00
erew123 525a337835 Update README.md 2024-01-20 13:47:58 +00:00
erew123 2bd1ef843e Dynamic IP support 2024-01-20 00:18:06 +00:00
erew123 a9d95fc563 Update script.py 2024-01-18 14:15:34 +00:00
erew123 1a37ae4ba5 Merge pull request #76 from S95Sedan/main
Temperature and Repetition_penalty
2024-01-18 14:14:04 +00:00
erew123 8c6fc4853d Updated ST files 2024-01-17 22:01:51 +00:00
erew123 f34ebbd675 Update README.md 2024-01-16 01:00:48 +00:00
S95Sedan 64cffcdf80 Updated tts_server.py
With changes in: https://github.com/S95Sedan/alltalk_tts/commit/cefd1e045baf15c68fbdcac15fb1978850f8987f#commitcomment-137124105
2024-01-16 01:47:29 +01:00
erew123 2731a559f4 Update README.md 2024-01-16 00:12:54 +00:00
erew123 a91a83268f eval % option 2024-01-15 23:55:54 +00:00
S95Sedan 5d406fbbfb Load variables fix
Load temp/repetition variables in tts_server incase of API only usage.
2024-01-16 00:37:10 +01:00
S95Sedan cefd1e045b Temperature and Repetition_penalty modification
Modified script.py to enable temperature and repetition_penalty to be parsed and tts_server.py to recieve those variables.
2024-01-15 21:51:00 +01:00
erew123 bec4e905d3 Push JS mimetype on /static
Push JS files with mimetype of application/javascript
2024-01-15 16:38:37 +00:00
erew123 f5e99a5e72 Update README.md 2024-01-15 13:38:28 +00:00
erew123 631ea6dd8a Update README.md 2024-01-15 13:38:00 +00:00
erew123 08a04ba506 Added warning about starting from disk location 2024-01-15 11:36:29 +00:00
erew123 c78927b80a Create FND 2024-01-14 12:51:41 +00:00
erew123 04e08c58b8 Delete .github/ISSUE_TEMPLATE/FUNDING.yml 2024-01-14 12:50:57 +00:00
erew123 893747c9a9 Add files via upload 2024-01-14 12:48:49 +00:00
erew123 d52dcf86d5 Update README.md 2024-01-13 23:43:15 +00:00
erew123 ad0eab1224 Update atsetup.sh
added cutlet and unidic-lite
2024-01-13 22:45:01 +00:00
erew123 62d1cc05d3 Added cutlet and unidic-lite for Japanese 2024-01-13 22:43:41 +00:00
erew123 b8292da92f Update README.md 2024-01-13 21:47:49 +00:00
erew123 180adb45dd Merge pull request #68 from erew123/dev
Update to Main
2024-01-13 21:28:59 +00:00
erew123 5c0f08d49e Update README.md 2024-01-13 21:23:47 +00:00
erew123 571872dbe2 Update README.md 2024-01-13 21:16:01 +00:00
erew123 467bfbea55 Applied UUID to API generated TTS
To avoid over-writing if 2x generations happen quickly enough.
2024-01-13 21:07:18 +00:00
erew123 5a3cbb6366 Update README.md 2024-01-13 20:22:10 +00:00
erew123 2351e418fd Changed demo endpoint 2024-01-13 20:13:38 +00:00
erew123 b987ff38a7 Update README.md 2024-01-13 20:07:22 +00:00
erew123 43899028e3 Update README.md 2024-01-13 19:59:10 +00:00
erew123 2c1ca8b2a3 Update README.md 2024-01-13 19:56:31 +00:00
erew123 139162c4e6 Update README.md 2024-01-13 19:55:24 +00:00
erew123 7da78ec045 Add files via upload 2024-01-13 19:39:58 +00:00
erew123 11c70c7432 Tidied console messages 2024-01-13 19:03:26 +00:00
erew123 c2822edb1b Add files via upload 2024-01-13 18:53:12 +00:00
erew123 cba7ed7b88 Update README.md 2024-01-13 18:38:21 +00:00
erew123 471a26f2a4 Update README.md 2024-01-13 18:23:48 +00:00
erew123 34d1b81ae4 Update README.md 2024-01-13 18:20:35 +00:00
erew123 f1b4d4b8b6 Update README.md 2024-01-13 16:41:30 +00:00
erew123 c05237143b Update README.md 2024-01-13 15:28:45 +00:00
erew123 c5846b832a Update README.md 2024-01-13 14:59:38 +00:00
erew123 7a38730c56 Update README.md 2024-01-13 14:48:06 +00:00
erew123 0b1e6f8711 Update README.md 2024-01-13 14:47:05 +00:00
erew123 8c38e925dd Update README.md 2024-01-13 14:46:04 +00:00
erew123 df70481934 Update README.md 2024-01-13 14:43:19 +00:00
erew123 e43c58a56e Delete atstart.sh 2024-01-13 13:09:20 +00:00
erew123 8dc9304a4c Update tts_server.py - _combined path
corrected _combined on narrated without timestamp
2024-01-13 11:37:23 +00:00
erew123 102424669b Update tts_server.py - URL file path no timestamp 2024-01-13 11:31:22 +00:00
erew123 5210d075c1 added an additional note to finetune. 2024-01-13 00:31:14 +00:00
erew123 30db974439 Update README.md 2024-01-12 16:17:55 +00:00
erew123 c2a558110b Update README.md 2024-01-12 16:13:11 +00:00
erew123 83ac18b83f Update README.md 2024-01-12 16:12:54 +00:00
erew123 6e36415746 Update README.md 2024-01-12 16:09:41 +00:00
erew123 fe7ffb535c Delete atstart.sh 2024-01-12 15:31:45 +00:00
erew123 80b7fccb50 alltalk.sh adds env file. 2024-01-12 15:30:26 +00:00
erew123 2790ee9860 added environment routine to atsetup.bat 2024-01-12 14:42:31 +00:00
erew123 74ce2584cc Update README.md 2024-01-12 14:27:53 +00:00
erew123 8dd11541b4 Update README.md 2024-01-12 14:05:44 +00:00
erew123 d1317b49f0 Merge pull request #64 from q5sys/patch-1
Update README.md
2024-01-12 13:51:24 +00:00
erew123 a50d5a5028 Merge branch 'dev' into patch-1 2024-01-12 13:51:17 +00:00
erew123 33264554cd Update README.md 2024-01-12 13:46:02 +00:00
erew123 4a116e359a updated atsetup.bat 2024-01-12 12:21:07 +00:00
erew123 36bfb17eda Updated atsetup.sh 2024-01-12 11:30:12 +00:00
erew123 697fb098c3 Rename atstart.sh to atsetup.sh 2024-01-12 09:56:05 +00:00
q5sys (JT) 51a8e93df7 Update README.md
Add specific section for deepspeed installation on linux for standalone app. 
Related to https://github.com/erew123/alltalk_tts/issues/62
2024-01-11 21:21:30 -05:00
erew123 257fa59e70 Linux atstart script 2024-01-11 23:26:59 +00:00
erew123 7dbad85fc3 Linux atstart script 2024-01-11 23:26:14 +00:00
erew123 510894c793 Delete start_standalone.bat 2024-01-11 22:21:06 +00:00
erew123 a85058a3ac updated diagnostics 2024-01-11 20:47:13 +00:00
erew123 e54c7e4362 atsetup.bat
first version of a simple setup file.
2024-01-11 20:13:28 +00:00
erew123 1f2ad303a0 Corrected ST setting TTS options 2024-01-11 20:05:16 +00:00
erew123 d4a04096c8 Made Server address more visible on startup 2024-01-10 18:28:55 +00:00
erew123 dd45008e88 Merge pull request #60 from S95Sedan/main
Gui Overhaul
2024-01-10 18:13:06 +00:00
erew123 e9d9f54de6 Update script.py 2024-01-10 18:10:42 +00:00
erew123 3230397a82 Standalone installer script 2024-01-10 18:07:01 +00:00
S95Sedan 840889ac9a Update script.py
- Changed non_quoted_text_is_gr from "Char" to "Character"
2024-01-10 16:08:51 +01:00
S95Sedan d3e061b127 Update script.py
- GUI overhaul/cleanup.
- Temperature and Repetition penalty in GUI (disabled) but not yet parsed to API
2024-01-10 15:35:13 +01:00
erew123 a428f67a2e SillyTavern Support files.
Just kept here for safe keeping.
2024-01-10 14:09:31 +00:00
erew123 b223e7b247 ST Documentation added 2024-01-10 14:04:25 +00:00
erew123 9296843508 Update README.md 2024-01-10 12:48:56 +00:00
erew123 f0c9e3e6bb Update README.md 2024-01-10 12:40:20 +00:00
erew123 22de1bf0c6 Update README.md 2024-01-10 12:39:39 +00:00
erew123 621f5434a7 Update README.md 2024-01-10 12:38:59 +00:00
erew123 81c8354cf8 Update README.md 2024-01-10 11:53:49 +00:00
erew123 3bc55a91e5 Added streaming API & Current settings endpoint 2024-01-10 11:50:35 +00:00
erew123 fc857f464c Merge pull request #59 from erew123/main
merge main to dev
2024-01-10 11:49:34 +00:00
erew123 50aa6de96c Uploading the correct version!! 2024-01-08 18:57:00 +00:00
erew123 10299194f8 Update README.md 2024-01-08 14:33:16 +00:00
erew123 d80d1ace3c Update README.md 2024-01-08 13:31:40 +00:00
erew123 f19f4e9a29 Update README.md 2024-01-08 13:19:16 +00:00
erew123 7e4ceef0e8 Update README.md 2024-01-08 13:00:48 +00:00
erew123 c1bc1f26cd Export split setting
Avoids the 1GB file limit imposed by browsers and also lowers memory requirements per exported block.
2024-01-08 12:54:14 +00:00
erew123 70d385133d JSON import pagination 2024-01-08 01:13:36 +00:00
erew123 13b2eb5fe3 Update README.md 2024-01-08 01:03:06 +00:00
erew123 ff4b9d9e99 Updates to reduce browser load
Pagination of files list.
No Playback option
Better clearing of played back audio from memory
2024-01-08 00:56:36 +00:00
erew123 a22830f700 Update tts_chunk_player.html
bumped sentence splitting
2024-01-07 21:33:33 +00:00
erew123 374c794fa9 Merge pull request #51 from nicobubulle/fix
Fix greedy option for regex in HTML files
2024-01-07 20:59:13 +00:00
nicobubulle d2adbd9c1e Fix greedy option for regex in HTML files 2024-01-07 18:06:32 +01:00
erew123 1dc4b8bf50 Add $ to demo page regex 2024-01-07 08:38:39 +00:00
erew123 0eba72fc47 Merge pull request #50 from nicobubulle/fix
Fix greedy option for regex
2024-01-07 08:32:24 +00:00
nicobubulle f2c87dcdab Fix greedy option for regex 2024-01-07 09:25:52 +01:00
erew123 4a727ce14a Update README.md 2024-01-06 22:32:19 +00:00
erew123 6e15d43e63 Update README.md 2024-01-06 22:21:22 +00:00
erew123 dedc13b3b6 Update README.md 2024-01-06 22:05:10 +00:00
erew123 7cb206e531 Update README.md 2024-01-06 21:19:25 +00:00
erew123 4f80b39cd0 Update README.md 2024-01-06 20:49:58 +00:00
erew123 d5fa6bb46d Merge pull request #49 from erew123/main
merge main
2024-01-06 20:28:20 +00:00
erew123 332582baea AllTalk TTS Generator 2024-01-06 20:26:05 +00:00
erew123 2bd7ebc514 Delete templates/TTS_Input_Proof_of_concept.html 2024-01-06 20:24:20 +00:00
erew123 e5acc8bdbd Merge pull request #48 from erew123/main
main to dev pull
2024-01-05 13:31:31 +00:00
erew123 7718bfd3ea Update admin.html
Added Hungarian characters
2024-01-05 13:27:49 +00:00
erew123 002c5ad9db Update tts_server.py
Added Hungarian characters
2024-01-05 13:26:15 +00:00
erew123 2c14847708 Update script.py
added Hungarian characters
2024-01-05 13:24:20 +00:00
erew123 3647d69007 Update README.md 2024-01-05 13:18:02 +00:00
erew123 56a7ea1d8f Update README.md 2024-01-05 13:17:38 +00:00
erew123 863a7cd841 Update README.md 2024-01-05 13:08:45 +00:00
erew123 2e1709ab58 Update README.md 2024-01-05 13:06:10 +00:00
erew123 9c4efdc135 Update README.md 2024-01-05 13:03:49 +00:00
erew123 28675c976c Update README.md 2024-01-05 13:02:28 +00:00
erew123 afe3b9fe0b Update README.md 2024-01-05 12:58:16 +00:00
erew123 2e4d52170d Update README.md 2024-01-05 12:53:13 +00:00
erew123 0e2cc25571 Merge pull request #47 from erew123/main
pull from main
2024-01-05 11:44:52 +00:00
erew123 abaa56e8f4 Update admin.html
Additional European and Cyrillic characters
2024-01-04 12:17:23 +00:00
erew123 d0dc9f3212 Update tts_server.py
Additional European language & Cyrillic characters
2024-01-04 12:16:21 +00:00
erew123 67dcc411ad Update script.py
Extend allowed characters, additional European & Cyrillic characters
2024-01-04 12:13:38 +00:00
erew123 b11a087dc8 Update tts_server.py
# Start Uvicorn Webserver
host_parameter = params["ip_address"]
port_parameter = int(params["port_number"])

Corrected format
2024-01-03 20:57:21 +00:00
erew123 e068115eef Merge pull request #43 from nicobubulle/improvement
Regex improvement for text_filtering
2024-01-03 17:54:15 +00:00
nicobubulle 0ec580539a Regex improvement
Add greedy option to avoid apostrophe being removed
Add accentuated character for foreign language
2024-01-03 16:54:25 +01:00
erew123 e9feae12ad path corrected for word_addin 2024-01-03 10:50:22 +00:00
erew123 e183e3a7bb Filtering Demo page
removed some of the demo filtering as it was stripping too much from the text.
2024-01-03 09:36:33 +00:00
erew123 8a2b669da9 Merge pull request #42 from erew123/main
main to dev
2024-01-03 02:31:58 +00:00
erew123 67d2b1c5ea Word-Add-in Proof of concept 2024-01-03 01:29:57 +00:00
erew123 f3b44424ef Update for word add-in 2024-01-03 01:28:56 +00:00
erew123 3b5c4b9b68 added an extra replace for % to percent 2024-01-02 20:37:27 +00:00
erew123 e452a926f2 adding params to demo generate
params.ip_address  &  params.port_number
2024-01-02 20:30:16 +00:00
erew123 b65291d44d Merge pull request #40 from erew123/main
merge main to dev
2024-01-02 00:59:37 +00:00
erew123 b28ecaf43e added pause button 2024-01-01 21:43:23 +00:00
erew123 ba1328311c Update README.md 2024-01-01 20:47:32 +00:00
erew123 9e6b9396bc Corrected Spelling mistakes 2024-01-01 20:30:18 +00:00
erew123 2e40db5fe5 Merge pull request #39 from erew123/dev
Dev
2024-01-01 20:05:09 +00:00
erew123 720bf8697f Merge branch 'main' into dev 2024-01-01 20:05:00 +00:00
erew123 1893d1a130 remove unused style.css file 2024-01-01 19:55:38 +00:00
erew123 8472baf031 Delete style.css 2024-01-01 19:51:23 +00:00
erew123 6cab618706 Update README.md 2024-01-01 18:45:41 +00:00
erew123 ebf3b362f7 Add files via upload 2024-01-01 18:20:44 +00:00
erew123 2dd303f53c Add files via upload 2024-01-01 18:10:14 +00:00
erew123 df69fb0b07 Merge pull request #36 from rbruels/feature/add-streaming-tts
Feature: Add streaming TTS, using the new inference_stream() function from CoquiTTS
2024-01-01 16:58:33 +00:00
erew123 a0d9771fa6 Add files via upload 2024-01-01 16:20:58 +00:00
erew123 a71c46bb98 Merge pull request #35 from rbruels/enhancement/templatize-tts-server-html
Enhancement: Templatize tts-server html for ease of editing
2024-01-01 12:41:08 +00:00
erew123 995f317b4f Merge pull request #37 from erew123/main
sync main to dev
2024-01-01 12:36:36 +00:00
Ryan 6ef2de2923 Support streaming of model inference to lower time to first token for long passages. Uses the new CoquiTTS inference_stream() function 2024-01-01 00:27:11 -08:00
Ryan 37c4e86566 Merge branch 'main' into enhancement/templatize-tts-server-html 2023-12-31 15:09:11 -08:00
Ryan 11071b279b Templatize the tts-server HTML for ease of editing 2023-12-31 15:06:39 -08:00
erew123 5ab7463f35 More narrator shenanigans 2023-12-31 21:35:23 +00:00
erew123 74c9238e3a Update README.md 2023-12-30 22:15:30 +00:00
erew123 e874e46304 Update README.md 2023-12-30 15:26:02 +00:00
erew123 b32df6ac15 Additional note in finetune re multiple GPU support 2023-12-30 14:45:42 +00:00
erew123 b76dd3561f Merge pull request #34 from erew123/dev
Dev
2023-12-30 14:23:22 +00:00
erew123 60bfbdcabd Update README.md 2023-12-30 14:12:41 +00:00
erew123 c128d0851b Updated Finetune 2023-12-30 14:00:36 +00:00
erew123 2f3b7762e4 Update README.md 2023-12-30 13:31:41 +00:00
erew123 0e594f5098 Update .gitignore 2023-12-30 13:30:16 +00:00
erew123 14151d4dda Update README.md 2023-12-30 11:27:20 +00:00
erew123 94ab21fb15 Update README.md 2023-12-30 11:26:29 +00:00
erew123 1acac3d6c6 Update README.md 2023-12-30 11:23:59 +00:00
erew123 95ec2dc9d2 Merge pull request #32 from erew123/main
merge main to dev
2023-12-30 11:11:11 +00:00
erew123 6b93eb6c1e Update README.md 2023-12-29 23:38:38 +00:00
erew123 838578a042 Update README.md 2023-12-29 23:28:47 +00:00
erew123 2f689f0438 Model loader for Finetuned models
Adds a detection routine and additional loader for a finetuned model. 
Model has to be in /models/trainedmodel/
2023-12-29 23:15:15 +00:00
erew123 022025ded6 Update README.md 2023-12-29 20:57:28 +00:00
erew123 320a7a6aba Update README.md 2023-12-29 20:51:45 +00:00
erew123 fa82870883 Merge pull request #31 from erew123/dev
3x new API endpoints & Play audio at command prompt/terminal
2023-12-29 20:37:20 +00:00
erew123 a094d4f9da Completed autoplay at command line
Added additional requirement.
Lowered the repetition on the start-up warning when its taking a while for the model to load.
2023-12-29 20:31:49 +00:00
erew123 bb028af694 Update README.md 2023-12-29 10:54:02 +00:00
erew123 aeb225ec7c Update README.md 2023-12-29 10:51:06 +00:00
erew123 06a632459e Update README.md 2023-12-29 10:44:39 +00:00
erew123 221efbddb4 Supports playback at the command line prompt
Added sounddevice as its currently well supported. Allows playback at the terminal/command prompt. 
Added speakers_xtts.pth to the modeldownload.json as it will be needed for finetuning in future updates of TTS 0.22.0+
2023-12-29 10:42:35 +00:00
erew123 e81a88938a Completed built-in documentation update
For the new API endpoints
2023-12-29 10:11:01 +00:00
erew123 65e257077c 3x new API endpoints
/api/voices/
/api/previewvoice/
/api/ready/
2023-12-29 09:56:51 +00:00
erew123 95659d5b7a Update README.md 2023-12-29 09:55:23 +00:00
erew123 ff57270286 Update README.md 2023-12-29 09:53:02 +00:00
erew123 4fc61ba99a Merge pull request #30 from erew123/main
merge main to dev
2023-12-29 09:08:07 +00:00
erew123 3cd22081f4 Update script.py 2023-12-28 21:05:59 +00:00
erew123 d20ee95e67 Delete finetune/put-voice-samples-in-here/compact.py 2023-12-28 20:38:33 +00:00
erew123 cd47f6b123 Add files via upload 2023-12-28 20:38:12 +00:00
erew123 53a2d0a65e Update README.md 2023-12-28 19:25:59 +00:00
erew123 13318243e4 Merge pull request #27 from rbruels/patch-1
A few changes/clarifications in the fine-tuning sections
2023-12-28 18:41:06 +00:00
erew123 acc457436a updated narrator splitting function
Improved over what was before. 
Still more work to do in future though.
2023-12-28 18:39:01 +00:00
erew123 8d80151889 New version of Finetune
Simplified the final stages of finetuning.
Added model compaction. 
Added cleaning routines to tidy up after training.
2023-12-28 18:36:51 +00:00
erew123 8b0ade5b9f compact routine - separate to finetune
a mini compact routine for anyone who wants to compact their existing model. This is built into the new version of finetune anyway, but is here just to capture those outlier instances.
2023-12-28 18:34:49 +00:00
Ryan Bruels 9f033e4654 A few changes/clarifications in the fine-tuning sections 2023-12-28 10:28:20 -08:00
erew123 1a2b8571d0 Updated diagnostics to include Path
Now includes both Python and environment variables PATH search locations.
2023-12-28 12:05:46 +00:00
erew123 9ab20be294 Update README.md
updated a screenshot
2023-12-27 06:49:46 +00:00
erew123 a34cbfdd55 Made Settings link more visble
Updated the visibility of the settings & documentation page within Text-gen-webui interface.
Minor built in documentation update.
2023-12-27 06:43:28 +00:00
erew123 94f5b781cc Update Standalone API - race condition fix
Applies the same race condition fix for narrator/character that potentially existed, but for the standalone mode API. Will have zero effect for anyone not using the API
2023-12-27 06:08:10 +00:00
erew123 f83e7c3b4e Update README.md 2023-12-27 06:00:30 +00:00
erew123 607dc89be5 Update README.md
Added a section on Running AllTalk as a standalone
2023-12-27 04:44:44 +00:00
erew123 47758c4aeb Updated diagnostics
Pulls Conda and Python environment details.
2023-12-26 18:58:06 +00:00
erew123 26414d4925 Update README.md 2023-12-26 17:30:40 +00:00
erew123 7ad92e7f5d Update README.md 2023-12-26 17:28:28 +00:00
erew123 e775cef5bd Update README.md 2023-12-26 17:19:21 +00:00
erew123 ac9ce144a0 Update README.md 2023-12-26 16:47:24 +00:00
erew123 f181c06f89 Update README.md
Added a video link to show people how to install AllTalk.
2023-12-26 10:02:17 +00:00
erew123 9fae4692e3 Update README.md 2023-12-26 08:03:24 +00:00
erew123 97f0d6441a Improved links in Documentation
Added links to the minor bugs/known issues on gthub
2023-12-26 07:30:30 +00:00
erew123 2ea6cb6304 Update README.md 2023-12-26 06:23:26 +00:00
erew123 5bed68a963 minor update to standard voice naming. 2023-12-25 21:53:40 +00:00
erew123 be9862d0b0 Update README.md 2023-12-25 21:15:54 +00:00
erew123 f5a811f0f8 Update README.md 2023-12-25 21:11:02 +00:00
erew123 dc9d343115 Update uuid to avoid possible race condition
file naming on short sentences could possibly have a race condition. set uuid as opposed to timestamp to avoid this outcome.
2023-12-25 21:09:39 +00:00
erew123 c92aa435e5 Update README.md 2023-12-25 09:37:39 +00:00
erew123 1f425e6bac Update README.md 2023-12-25 06:04:35 +00:00
erew123 0854544a47 Update README.md 2023-12-25 05:45:05 +00:00
erew123 52a7922e98 Add files via upload 2023-12-25 02:05:05 +00:00
erew123 558583b16f Update README.md 2023-12-24 20:37:59 +00:00
erew123 993d065368 Few minor updates
Couple of documentation spelling mistakes
Set environment variable
2023-12-24 18:01:27 +00:00
erew123 d7376fa8ef Update README.md 2023-12-24 17:01:33 +00:00
erew123 2b175b13c4 update to find mp3 and flac
Forgot it was only looking for wav's!
2023-12-24 15:56:44 +00:00
erew123 da0445489e Update requirements_other.txt 2023-12-24 14:17:07 +00:00
erew123 e4eaa760b9 Update requirements_nvidia.txt 2023-12-24 14:16:46 +00:00
erew123 de4017f385 Update README.md 2023-12-24 14:07:22 +00:00
erew123 f2119aa0f7 Merge pull request #14 from erew123/dev
New Finetuning of your models
New API endpoint
Full documentation (online and built in)
A couple of minor file updates.
Small bug fix on file generation in instruct mode with no character name available (thanks to @danielwburch)
2023-12-24 13:10:18 +00:00
erew123 bb81f3f874 Update README.md 2023-12-24 13:03:26 +00:00
erew123 fae15eecb1 minor spelling mistake
updating minor spelling mistake.
2023-12-24 12:54:08 +00:00
erew123 6edcc2125b create finetune directory 2023-12-24 12:35:02 +00:00
erew123 d26909a1d6 All the updates for Finetuning
Additional files to download
Updated documentation
Updated requirements files
2023-12-24 12:32:10 +00:00
erew123 3be6b842c4 Update README.md 2023-12-24 10:24:03 +00:00
erew123 e10dc700c3 Update README.md 2023-12-24 10:20:03 +00:00
erew123 e8e21f949c Update README.md
Detail API Suite
2023-12-24 10:00:08 +00:00
erew123 e68a7d72f2 Update README.md 2023-12-24 08:49:14 +00:00
erew123 fd26db8e8a Updated model + added finetuning requirements file
Updated modeldownload.json with finetuning requirements inside. 
New requirements_finetune.txt file.
2023-12-24 08:35:33 +00:00
erew123 396f1290e7 Update README.md 2023-12-24 08:30:32 +00:00
erew123 5bc7dd8692 Update README.md
added finetuning details
2023-12-24 08:29:06 +00:00
erew123 b5b68ad51f Update script.py
updated timeout
2023-12-23 00:16:38 +00:00
erew123 e49ceed40c Merge pull request #13 from danielwburch/refactor_output_filename_2
Refactor output file naming in script.py
2023-12-21 18:03:32 +00:00
Daniel Burch 598aec7f52 Refactor output file naming in script.py 2023-12-21 10:17:41 -06:00
erew123 f25d2627cd updated timeout to 80 seconds
Much older systems with low system ram are taking 70 seconds to start up (so Im told). Ive added an extra 20 seconds onto the 60 seconds for subprocess start-up.

documentation updated too.
2023-12-21 12:47:53 +00:00
erew123 3e6f1bace3 Update README.md
updated docs based on 80 second timeout for older systems
2023-12-21 12:45:58 +00:00
erew123 fb851ff3f0 Update README.md 2023-12-21 12:32:52 +00:00
erew123 92bf8f5de8 Update README.md 2023-12-21 12:31:56 +00:00
erew123 8f318892c2 New API endpoint
adds the /api/tts-generation endpoint & documentation.
2023-12-21 11:32:59 +00:00
erew123 28a62ed39a Merge pull request #12 from erew123/revert-9-refactor_output_filename_setting
Revert "Refactor output file naming in script.py"
2023-12-21 06:27:23 +00:00
erew123 4c08927ed9 Revert "Refactor output file naming in script.py" 2023-12-21 06:26:32 +00:00
erew123 a93da39711 Merge pull request #9 from danielwburch/refactor_output_filename_setting
Refactor output file naming in script.py
2023-12-21 06:14:03 +00:00
Daniel Burch 557f4b80b6 Refactor output file naming in script.py 2023-12-20 15:07:28 -06:00
erew123 c657a2aac6 Capture wildcards in requirements 2023-12-20 08:52:00 +00:00
erew123 af99748441 Update issue templates 2023-12-20 08:38:15 +00:00
erew123 db87427e7c Update README.md
Added diagnostics details.
2023-12-20 08:13:03 +00:00
erew123 c9b82034f0 diagnostics
added colour identifiers to the output on screen.
2023-12-20 02:18:43 +00:00
erew123 96aef2c1be Updating docs CURL
Curl command rendered incorrectly in HTML, so corrected
2023-12-20 01:12:45 +00:00
91 changed files with 14327 additions and 6224 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
ko_fi: erew123
@@ -1,17 +1,16 @@
---
name: Bug report/Support request
name: Support request OR Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
🔴 If you have installed AllTalk in a custom Python environment, I will only be able to provide limited assistance/support. AllTalk draws on a variety of scripts and libraries that are not written or managed by myself, and they may fail, error or give strange results in custom built python environments.
Please run the diagnostics and upload the diagnostics.log file. To do this, start Text-generation-webui's Python environment with "cmd_windows.bat" OR "./cmd_linux.sh" OR "cmd_macos.sh" OR "cmd_wsl.bat" and then go into the \extensions\alltalk_tts\ folder and run:
🔴 Please generate a diagnostics report and upload the "diagnostics.log" as this helps me understand your configuration.
python diagnostics.py
Which will both output to the screen and create a "diagnostics.log" file.
https://github.com/erew123/alltalk_tts/tree/main?#-how-to-make-a-diagnostics-report-file
**Describe the bug**
A clear and concise description of what the bug is.
+67
View File
@@ -0,0 +1,67 @@
name: Publish Docker image
on:
push:
branches: [main]
release:
types: [published]
workflow_dispatch:
jobs:
build_and_push:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- dockerfile: "Dockerfile"
platforms: "linux/amd64"
tag_name: "cpu"
- dockerfile: "nvidia.Dockerfile"
platforms: "linux/amd64"
tag_name: "cuda"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Lowercase Actor and Extract Repo Name
run: |
echo "ACTOR_LOWER=$(echo ${{ github.actor }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
echo "REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f 2)" >> $GITHUB_ENV
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.ACTOR_LOWER }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./${{ matrix.dockerfile }}
platforms: ${{ matrix.platforms }}
push: true
tags: |
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }}
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:latest
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }}
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v3.4.2
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}
+1
View File
@@ -1,6 +1,7 @@
voices/*.*
models/*.*
outputs/*.*
finetune/*.*
config.json
confignew.json
models.json
+9
View File
@@ -0,0 +1,9 @@
{
"files.associations": {
"*.html": "jinja-html"
},
"emmet.includeLanguages": {
"jinja-html": "html",
"jinja2": "html"
},
}
@@ -1,285 +0,0 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0
// DeepSpeed Team
#include <ATen/cuda/CUDAContext.h>
#include <torch/extension.h>
#include <cassert>
#include <vector>
#include "quantization.h"
template <typename T>
at::Tensor ds_quantize(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
launch_fake_quantize_kernel(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_sr_quantize(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if (((size / groups) / 4 / 1024) <= 256) {
launch_sr_fake_quantize_kernel(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_quantize_asym(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
launch_fake_quantize_kernel_asym(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_sr_quantize_asym(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if (((size / groups) / 4 / 1024) <= 256) {
launch_sr_fake_quantize_kernel_asym(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
std::vector<at::Tensor> quantize_kernel(at::Tensor& input_vals,
int groups,
int numBits,
quantize::Type quantType)
{
auto dtype = at::kFloat;
auto params_options = at::TensorOptions()
.dtype(dtype)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int param_elems = (quantize::requires_offset(quantType)) ? 2 : 1;
auto params = torch::empty({groups, param_elems}, params_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
auto output_sizes = input_vals.sizes().vec();
output_sizes[output_sizes.size() - 1] /= numBits == 8 ? 1 : 2;
auto output = torch::empty(output_sizes, output_options);
const int elems_per_group = at::numel(input_vals) / groups;
launch_quant((int8_t*)output.data_ptr(),
(float*)params.data_ptr(),
(__half*)input_vals.data_ptr(),
groups,
elems_per_group,
numBits,
quantType,
at::cuda::getCurrentCUDAStream());
return {output, params};
}
template <typename T>
at::Tensor dequantize(at::Tensor& quantized_data,
at::Tensor& params,
int groups,
int num_bits,
quantize::Type quant_type)
{
auto dtype = (std::is_same<T, float>::value) ? torch::kFloat32 : torch::kFloat16;
auto output_options = at::TensorOptions()
.dtype(dtype)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
auto output_sizes = quantized_data.sizes().vec();
output_sizes[output_sizes.size() - 1] *= num_bits == 8 ? 1 : 2;
auto output = torch::empty(output_sizes, output_options);
const int total_elems = at::numel(output);
const int elems_per_group = total_elems / groups;
launch_dequantize_kernel((T*)output.data_ptr(),
(const int8_t*)quantized_data.data_ptr(),
(const float*)params.data_ptr(),
quant_type,
num_bits,
elems_per_group,
total_elems,
at::cuda::getCurrentCUDAStream());
return output;
}
at::Tensor dequantize_int4_to_half_experimental(at::Tensor& data_in,
at::Tensor& scale_buffer,
at::Tensor& min_val_buffer,
int num_group,
int group_size)
{
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
auto output = torch::empty({num_group, group_size}, output_options);
launch_dequantize_int4_to_half_experimental((uint8_t*)data_in.data_ptr(),
(half*)output.data_ptr(),
(half*)scale_buffer.data_ptr(),
(half*)min_val_buffer.data_ptr(),
num_group,
group_size,
at::cuda::getCurrentCUDAStream());
return output;
}
std::vector<at::Tensor> ds_swizzle_quant(at::Tensor& input_vals,
int groups,
int num_bits,
quantize::Type quant_type,
int pipeline_size,
int nodes,
int devices_per_node)
{
auto scales_options = at::TensorOptions()
.dtype(at::kFloat)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
auto scales = torch::empty({groups, scales_elems}, scales_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int quantization_scalar = 8 / num_bits;
const int compressed_vals = at::numel(input_vals) / quantization_scalar;
auto output = torch::empty({compressed_vals}, output_options);
const int elems_per_group = at::numel(input_vals) / groups;
launch_swizzled_quant((int8_t*)output.data_ptr(),
(float*)scales.data_ptr(),
(__half*)input_vals.data_ptr(),
num_bits,
quant_type,
groups,
elems_per_group,
pipeline_size,
nodes,
devices_per_node,
at::cuda::getCurrentCUDAStream());
return {output, scales};
}
std::vector<at::Tensor> quantized_reduction(at::Tensor& input_vals,
at::Tensor& input_scales,
int in_groups,
int out_groups,
int num_bits,
quantize::Type quant_type,
int devices_per_node)
{
auto scales_options = at::TensorOptions()
.dtype(at::kFloat)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
auto scales = torch::empty({out_groups, scales_elems}, scales_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
std::vector<int64_t> sz_vector(input_vals.sizes().begin(), input_vals.sizes().end());
sz_vector[sz_vector.size() - 1] = sz_vector.back() / devices_per_node; // num of GPU per nodes
at::IntArrayRef sz(sz_vector);
auto output = torch::empty(sz, output_options);
const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
const int elems_per_out_group = elems_per_in_tensor / out_groups;
// old code:
// std::vector<long int> sz(input_vals.sizes().begin(), input_vals.sizes().end());
// sz[sz.size() - 1] = sz.back() / devices_per_node; // num of GPU per nodes
// const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
// auto output = torch::empty(sz, output_options);
// const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
// const int elems_per_out_group = elems_per_in_tensor / out_groups;
launch_dequant_reduce((int8_t*)output.data_ptr(),
(float*)scales.data_ptr(),
(const int8_t*)input_vals.data_ptr(),
(const float*)input_scales.data_ptr(),
devices_per_node,
num_bits,
quant_type,
out_groups,
elems_per_out_group,
elems_per_in_tensor,
in_groups / devices_per_node,
elems_per_in_group,
at::cuda::getCurrentCUDAStream());
return {output, scales};
}
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
{
m.def("ds_quantize_fp32", &ds_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_quantize_fp16", &ds_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_sr_quantize_fp32", &ds_sr_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_sr_quantize_fp16", &ds_sr_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_quantize_asym_fp32", &ds_quantize_asym<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def(
"ds_quantize_asym_fp16", &ds_quantize_asym<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_sr_quantize_asym_fp32",
&ds_sr_quantize_asym<float>,
"DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_sr_quantize_asym_fp16",
&ds_sr_quantize_asym<__half>,
"DeepSpeed Quantize with fp16 (CUDA)");
pybind11::enum_<quantize::Type>(m, "QuantizationType")
.value("Symmetric", quantize::Type::Symmetric)
.value("Asymmetric", quantize::Type::Asymmetric)
.export_values();
m.def("quantize", &quantize_kernel);
m.def("dequantize", &dequantize<__half>);
m.def("dequantize_fp32", &dequantize<float>);
m.def("dequantize_int4_to_half_experimental",
&dequantize_int4_to_half_experimental,
"Dequantize int4 to half (experimental)");
m.def("swizzle_quant", &ds_swizzle_quant);
m.def("quantized_reduction", &quantized_reduction);
}
File diff suppressed because it is too large. Load diff
@@ -1,160 +0,0 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import os
import torch
import deepspeed
import subprocess
import argparse
import psutil
from .ops.op_builder.all_ops import ALL_OPS
from .git_version_info import installed_ops, torch_info
from deepspeed.accelerator import get_accelerator
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
END = '\033[0m'
SUCCESS = f"{GREEN} [SUCCESS] {END}"
OKAY = f"{GREEN}[OKAY]{END}"
WARNING = f"{YELLOW}[WARNING]{END}"
FAIL = f'{RED}[FAIL]{END}'
INFO = '[INFO]'
color_len = len(GREEN) + len(END)
okay = f"{GREEN}[OKAY]{END}"
warning = f"{YELLOW}[WARNING]{END}"
def op_report(verbose=True):
max_dots = 23
max_dots2 = 11
h = ["op name", "installed", "compatible"]
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("DeepSpeed C++/CUDA extension op report")
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("NOTE: Ops not installed will be just-in-time (JIT) compiled at\n"
" runtime if needed. Op compatibility means that your system\n"
" meet the required dependencies to JIT install the op.")
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("JIT compiled ops requires ninja")
ninja_status = OKAY if ninja_installed() else FAIL
print('ninja', "." * (max_dots - 5), ninja_status)
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print(h[0], "." * (max_dots - len(h[0])), h[1], "." * (max_dots2 - len(h[1])), h[2])
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
installed = f"{GREEN}[YES]{END}"
no = f"{YELLOW}[NO]{END}"
for op_name, builder in ALL_OPS.items():
dots = "." * (max_dots - len(op_name))
is_compatible = OKAY if builder.is_compatible(verbose) else no
is_installed = installed if installed_ops.get(op_name, False) else no
dots2 = '.' * ((len(h[1]) + (max_dots2 - len(h[1]))) - (len(is_installed) - color_len))
print(op_name, dots, is_installed, dots2, is_compatible)
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
def ninja_installed():
try:
import ninja # noqa: F401 # type: ignore
except ImportError:
return False
return True
def nvcc_version():
import torch.utils.cpp_extension
cuda_home = torch.utils.cpp_extension.CUDA_HOME
if cuda_home is None:
return f"{RED} [FAIL] cannot find CUDA_HOME via torch.utils.cpp_extension.CUDA_HOME={torch.utils.cpp_extension.CUDA_HOME} {END}"
try:
output = subprocess.check_output([cuda_home + "/bin/nvcc", "-V"], universal_newlines=True)
except FileNotFoundError:
return f"{RED} [FAIL] nvcc missing {END}"
output_split = output.split()
release_idx = output_split.index("release")
release = output_split[release_idx + 1].replace(',', '').split(".")
return ".".join(release)
def get_shm_size():
try:
temp_dir = os.getenv('TEMP') or os.getenv('TMP') or os.path.join(os.path.expanduser('~'), 'tmp')
shm_stats = psutil.disk_usage(temp_dir)
shm_size = shm_stats.total
shm_hbytes = human_readable_size(shm_size)
warn = []
if shm_size < 512 * 1024**2:
warn.append(
f" {YELLOW} [WARNING] Shared memory size might be too small, consider increasing it. {END}"
)
# Add additional warnings specific to your use case if needed.
return shm_hbytes, warn
except Exception as e:
return "UNKNOWN", [f"Error getting shared memory size: {e}"]
def human_readable_size(size):
units = ['B', 'KB', 'MB', 'GB', 'TB']
i = 0
while size >= 1024 and i < len(units) - 1:
size /= 1024
i += 1
return f'{size:.2f} {units[i]}'
def debug_report():
max_dots = 33
report = [("torch install path", torch.__path__), ("torch version", torch.__version__),
("deepspeed install path", deepspeed.__path__),
("deepspeed info", f"{deepspeed.__version__}, {deepspeed.__git_hash__}, {deepspeed.__git_branch__}")]
if get_accelerator().device_name() == 'cuda':
hip_version = getattr(torch.version, "hip", None)
report.extend([("torch cuda version", torch.version.cuda), ("torch hip version", hip_version),
("nvcc version", (None if hip_version else nvcc_version())),
("deepspeed wheel compiled w.", f"torch {torch_info['version']}, " +
(f"hip {torch_info['hip_version']}" if hip_version else f"cuda {torch_info['cuda_version']}"))
])
else:
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']} ")])
report.append(("shared memory (/dev/shm) size", get_shm_size()))
print("DeepSpeed general environment info:")
for name, value in report:
warns = []
if isinstance(value, tuple):
value, warns = value
print(name, "." * (max_dots - len(name)), value)
if warns:
for warn in warns:
print(warn)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--hide_operator_status',
action='store_true',
help='Suppress display of installation and compatibility statuses of DeepSpeed operators. ')
parser.add_argument('--hide_errors_and_warnings', action='store_true', help='Suppress warning and error messages.')
args = parser.parse_args()
return args
def main(hide_operator_status=False, hide_errors_and_warnings=False):
if not hide_operator_status:
op_report(verbose=not hide_errors_and_warnings)
debug_report()
def cli_main():
args = parse_arguments()
main(hide_operator_status=args.hide_operator_status, hide_errors_and_warnings=args.hide_errors_and_warnings)
if __name__ == "__main__":
main()
@@ -1,299 +0,0 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0
// DeepSpeed Team
#include <ATen/cuda/CUDAContext.h>
#include <torch/extension.h>
#include <cassert>
#include <vector>
#include "quantization.h"
template <typename T>
at::Tensor ds_quantize(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
launch_fake_quantize_kernel(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_sr_quantize(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if (((size / groups) / 4 / 1024) <= 256) {
launch_sr_fake_quantize_kernel(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_quantize_asym(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
launch_fake_quantize_kernel_asym(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
template <typename T>
at::Tensor ds_sr_quantize_asym(at::Tensor& vals, int groups, int bits)
{
auto t_size = vals.sizes();
int size = 1;
for (auto dim : t_size) size *= dim;
if (((size / groups) / 4 / 1024) <= 256) {
launch_sr_fake_quantize_kernel_asym(
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
}
return vals;
}
std::vector<at::Tensor> quantize_kernel(at::Tensor& input_vals,
int groups,
int numBits,
quantize::Type quantType)
{
auto dtype = at::kFloat;
auto params_options = at::TensorOptions()
.dtype(dtype)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int param_elems = (quantize::requires_offset(quantType)) ? 2 : 1;
auto params = torch::empty({groups, param_elems}, params_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
auto output_sizes = input_vals.sizes().vec();
output_sizes[output_sizes.size() - 1] /= numBits == 8 ? 1 : 2;
auto output = torch::empty(output_sizes, output_options);
const int elems_per_group = at::numel(input_vals) / groups;
launch_quant((int8_t*)output.data_ptr(),
(float*)params.data_ptr(),
(__half*)input_vals.data_ptr(),
groups,
elems_per_group,
numBits,
quantType,
at::cuda::getCurrentCUDAStream());
return {output, params};
}
template <typename T>
at::Tensor dequantize(at::Tensor& quantized_data,
at::Tensor& params,
int groups,
int num_bits,
quantize::Type quant_type)
{
auto dtype = (std::is_same<T, float>::value) ? torch::kFloat32 : torch::kFloat16;
auto output_options = at::TensorOptions()
.dtype(dtype)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
auto output_sizes = quantized_data.sizes().vec();
output_sizes[output_sizes.size() - 1] *= num_bits == 8 ? 1 : 2;
auto output = torch::empty(output_sizes, output_options);
const int total_elems = at::numel(output);
const int elems_per_group = total_elems / groups;
launch_dequantize_kernel((T*)output.data_ptr(),
(const int8_t*)quantized_data.data_ptr(),
(const float*)params.data_ptr(),
quant_type,
num_bits,
elems_per_group,
total_elems,
at::cuda::getCurrentCUDAStream());
return output;
}
at::Tensor dequantize_int4_to_half_experimental(at::Tensor& data_in,
at::Tensor& scale_buffer,
at::Tensor& min_val_buffer,
int num_group,
int group_size)
{
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
auto output = torch::empty({num_group, group_size}, output_options);
launch_dequantize_int4_to_half_experimental((uint8_t*)data_in.data_ptr(),
(half*)output.data_ptr(),
(half*)scale_buffer.data_ptr(),
(half*)min_val_buffer.data_ptr(),
num_group,
group_size,
at::cuda::getCurrentCUDAStream());
return output;
}
at::Tensor dequantize_int8_to_half_experimental(at::Tensor& data_in,
at::Tensor& scale_buffer,
at::Tensor& min_val_buffer,
int num_group,
int group_size)
{
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
auto output = torch::empty({num_group, group_size}, output_options);
launch_dequantize_int8_to_half_experimental((uint8_t*)data_in.data_ptr(),
(half*)output.data_ptr(),
(half*)scale_buffer.data_ptr(),
(half*)min_val_buffer.data_ptr(),
num_group,
group_size,
at::cuda::getCurrentCUDAStream());
return output;
}
std::vector<at::Tensor> ds_swizzle_quant(at::Tensor& input_vals,
int groups,
int num_bits,
quantize::Type quant_type,
int pipeline_size,
int nodes,
int devices_per_node)
{
auto scales_options = at::TensorOptions()
.dtype(at::kFloat)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
auto scales = torch::empty({groups, scales_elems}, scales_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int quantization_scalar = 8 / num_bits;
const int compressed_vals = at::numel(input_vals) / quantization_scalar;
auto output = torch::empty({compressed_vals}, output_options);
const int elems_per_group = at::numel(input_vals) / groups;
launch_swizzled_quant((int8_t*)output.data_ptr(),
(float*)scales.data_ptr(),
(__half*)input_vals.data_ptr(),
num_bits,
quant_type,
groups,
elems_per_group,
pipeline_size,
nodes,
devices_per_node,
at::cuda::getCurrentCUDAStream());
return {output, scales};
}
std::vector<at::Tensor> quantized_reduction(at::Tensor& input_vals,
at::Tensor& input_scales,
int in_groups,
int out_groups,
int num_bits,
quantize::Type quant_type,
int devices_per_node)
{
auto scales_options = at::TensorOptions()
.dtype(at::kFloat)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
auto scales = torch::empty({out_groups, scales_elems}, scales_options);
auto output_options = at::TensorOptions()
.dtype(at::kChar)
.layout(at::kStrided)
.device(at::kCUDA)
.requires_grad(false);
std::vector<int64_t> sz_vector(input_vals.sizes().begin(), input_vals.sizes().end());
sz_vector[sz_vector.size() - 1] = sz_vector.back() / devices_per_node; // num of GPU per nodes
at::IntArrayRef sz(sz_vector);
auto output = torch::empty(sz, output_options);
const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
const int elems_per_out_group = elems_per_in_tensor / out_groups;
launch_dequant_reduce((int8_t*)output.data_ptr(),
(float*)scales.data_ptr(),
(const int8_t*)input_vals.data_ptr(),
(const float*)input_scales.data_ptr(),
devices_per_node,
num_bits,
quant_type,
out_groups,
elems_per_out_group,
elems_per_in_tensor,
in_groups / devices_per_node,
elems_per_in_group,
at::cuda::getCurrentCUDAStream());
return {output, scales};
}
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
{
m.def("ds_quantize_fp32", &ds_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_quantize_fp16", &ds_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_sr_quantize_fp32", &ds_sr_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_sr_quantize_fp16", &ds_sr_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_quantize_asym_fp32", &ds_quantize_asym<float>, "DeepSpeed Quantize with fp32 (CUDA)");
m.def(
"ds_quantize_asym_fp16", &ds_quantize_asym<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
m.def("ds_sr_quantize_asym_fp32",
&ds_sr_quantize_asym<float>,
"DeepSpeed Quantize with fp32 (CUDA)");
m.def("ds_sr_quantize_asym_fp16",
&ds_sr_quantize_asym<__half>,
"DeepSpeed Quantize with fp16 (CUDA)");
pybind11::enum_<quantize::Type>(m, "QuantizationType")
.value("Symmetric", quantize::Type::Symmetric)
.value("Asymmetric", quantize::Type::Asymmetric)
.export_values();
m.def("quantize", &quantize_kernel);
m.def("dequantize", &dequantize<__half>);
m.def("dequantize_fp32", &dequantize<float>);
m.def("dequantize_int4_to_half_experimental",
&dequantize_int4_to_half_experimental,
"Dequantize int4 to half (experimental)");
m.def("dequantize_int8_to_half_experimental",
&dequantize_int8_to_half_experimental,
"Dequantize int8 to half (experimental)");
m.def("swizzle_quant", &ds_swizzle_quant);
m.def("quantized_reduction", &quantized_reduction);
}
File diff suppressed because it is too large. Load diff
@@ -1,161 +0,0 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import os
import torch
import deepspeed
import subprocess
import argparse
import psutil
from .ops.op_builder.all_ops import ALL_OPS
from .git_version_info import installed_ops, torch_info
from deepspeed.accelerator import get_accelerator
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
END = '\033[0m'
SUCCESS = f"{GREEN} [SUCCESS] {END}"
OKAY = f"{GREEN}[OKAY]{END}"
WARNING = f"{YELLOW}[WARNING]{END}"
FAIL = f'{RED}[FAIL]{END}'
INFO = '[INFO]'
color_len = len(GREEN) + len(END)
okay = f"{GREEN}[OKAY]{END}"
warning = f"{YELLOW}[WARNING]{END}"
def op_report(verbose=True):
max_dots = 23
max_dots2 = 11
h = ["op name", "installed", "compatible"]
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("DeepSpeed C++/CUDA extension op report")
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("NOTE: Ops not installed will be just-in-time (JIT) compiled at\n"
" runtime if needed. Op compatibility means that your system\n"
" meet the required dependencies to JIT install the op.")
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print("JIT compiled ops requires ninja")
ninja_status = OKAY if ninja_installed() else FAIL
print('ninja', "." * (max_dots - 5), ninja_status)
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
print(h[0], "." * (max_dots - len(h[0])), h[1], "." * (max_dots2 - len(h[1])), h[2])
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
installed = f"{GREEN}[YES]{END}"
no = f"{YELLOW}[NO]{END}"
for op_name, builder in ALL_OPS.items():
dots = "." * (max_dots - len(op_name))
is_compatible = OKAY if builder.is_compatible(verbose) else no
is_installed = installed if installed_ops.get(op_name, False) else no
dots2 = '.' * ((len(h[1]) + (max_dots2 - len(h[1]))) - (len(is_installed) - color_len))
print(op_name, dots, is_installed, dots2, is_compatible)
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
def ninja_installed():
try:
import ninja # noqa: F401 # type: ignore
except ImportError:
return False
return True
def nvcc_version():
import torch.utils.cpp_extension
cuda_home = torch.utils.cpp_extension.CUDA_HOME
if cuda_home is None:
return f"{RED} [FAIL] cannot find CUDA_HOME via torch.utils.cpp_extension.CUDA_HOME={torch.utils.cpp_extension.CUDA_HOME} {END}"
try:
output = subprocess.check_output([cuda_home + "/bin/nvcc", "-V"], universal_newlines=True)
except FileNotFoundError:
return f"{RED} [FAIL] nvcc missing {END}"
output_split = output.split()
release_idx = output_split.index("release")
release = output_split[release_idx + 1].replace(',', '').split(".")
return ".".join(release)
def get_shm_size():
try:
temp_dir = os.getenv('TEMP') or os.getenv('TMP') or os.path.join(os.path.expanduser('~'), 'tmp')
shm_stats = psutil.disk_usage(temp_dir)
shm_size = shm_stats.total
shm_hbytes = human_readable_size(shm_size)
warn = []
if shm_size < 512 * 1024**2:
warn.append(
f" {YELLOW} [WARNING] Shared memory size might be too small, consider increasing it. {END}"
)
# Add additional warnings specific to your use case if needed.
return shm_hbytes, warn
except Exception as e:
return "UNKNOWN", [f"Error getting shared memory size: {e}"]
def human_readable_size(size):
units = ['B', 'KB', 'MB', 'GB', 'TB']
i = 0
while size >= 1024 and i < len(units) - 1:
size /= 1024
i += 1
return f'{size:.2f} {units[i]}'
def debug_report():
max_dots = 33
report = [("torch install path", torch.__path__), ("torch version", torch.__version__),
("deepspeed install path", deepspeed.__path__),
("deepspeed info", f"{deepspeed.__version__}, {deepspeed.__git_hash__}, {deepspeed.__git_branch__}")]
if get_accelerator().device_name() == 'cuda':
hip_version = getattr(torch.version, "hip", None)
report.extend([("torch cuda version", torch.version.cuda), ("torch hip version", hip_version),
("nvcc version", (None if hip_version else nvcc_version())),
("deepspeed wheel compiled w.", f"torch {torch_info['version']}, " +
(f"hip {torch_info['hip_version']}" if hip_version else f"cuda {torch_info['cuda_version']}"))
])
else:
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']} ")])
report.append(("shared memory (/dev/shm) size", get_shm_size()))
print("DeepSpeed general environment info:")
for name, value in report:
warns = []
if isinstance(value, tuple):
value, warns = value
print(name, "." * (max_dots - len(name)), value)
if warns:
for warn in warns:
print(warn)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--hide_operator_status',
action='store_true',
help='Suppress display of installation and compatibility statuses of DeepSpeed operators. ')
parser.add_argument('--hide_errors_and_warnings', action='store_true', help='Suppress warning and error messages.')
args = parser.parse_args()
return args
def main(hide_operator_status=False, hide_errors_and_warnings=False):
if not hide_operator_status:
op_report(verbose=not hide_errors_and_warnings)
debug_report()
def cli_main():
args = parse_arguments()
main(hide_operator_status=args.hide_operator_status, hide_errors_and_warnings=args.hide_errors_and_warnings)
if __name__ == "__main__":
main()
-18
View File
@@ -1,18 +0,0 @@
These are the modified files you would need for a MANUAL build of DeepSpeed 11.1 or 11.2.
They were created by a mix of instructions from erew123 and S95Sedan.
- You still have to download the DeepSpeed v11.1 or v11.2 installation files from Microsoft to use these files.
https://github.com/microsoft/DeepSpeed/releases/tag/v0.11.2
- These files were provided by S95Sedan here:
https://github.com/S95Sedan/Deepspeed-Windows
- They are related to the manual build of DeepSpeed for AllTalk, which is linked here:
https://github.com/erew123/alltalk_tts/tree/main?tab=readme-ov-file#-option-2---a-bit-more-complicated
+12
View File
@@ -0,0 +1,12 @@
FROM ubuntu:22.04
ENV HOST 0.0.0.0
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y git build-essential portaudio19-dev \
python3 python3-pip gcc wget \
&& ln -s /usr/bin/python3 /usr/bin/python
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements_other.txt
EXPOSE 7851
RUN chmod +x launch.sh
ENTRYPOINT ["sh", "-c", "./launch.sh"]
+1248 -247
View File
File diff suppressed because it is too large. Load diff
+638
View File
@@ -0,0 +1,638 @@
@echo off
cd /D "%~dp0"
set PATH=%PATH%;%SystemRoot%\system32
:: Generate the ESC character
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
:: Standard Colors
set "BLACK=%ESC%[30m"
set "RED=%ESC%[31m"
set "GREEN=%ESC%[32m"
set "YELLOW=%ESC%[33m"
set "BLUE=%ESC%[34m"
set "MAGENTA=%ESC%[35m"
set "CYAN=%ESC%[36m"
set "WHITE=%ESC%[37m"
set "L_BLACK=%ESC%[90m"
set "L_RED=%ESC%[91m"
set "L_GREEN=%ESC%[92m"
set "L_YELLOW=%ESC%[93m"
set "L_BLUE=%ESC%[94m"
set "L_MAGENTA=%ESC%[95m"
set "L_CYAN=%ESC%[96m"
set "L_WHITE=%ESC%[97m"
set "RESET=%ESC%[0m"
@rem Check if curl is available
curl --version >nul 2>&1
if "%ERRORLEVEL%" NEQ "0" (
echo curl is not available on this system. Please install curl then re-run the script https://curl.se/
echo or perform a manual installation of a Conda Python environment.
goto end
)
:MainMenu
cls
echo.
echo %L_BLUE%ALLTALK WINDOWS SETUP UTILITY%RESET%
echo.
echo INSTALLATION TYPE
echo 1) I am using AllTalk as part of %L_GREEN%Text-generation-webui%RESET%
echo 2) I am using AllTalk as a %L_GREEN%Standalone Application%RESET%
echo.
echo 9) %L_RED%Exit/Quit%RESET%
echo.
set /p UserOption=" Enter your choice: "
if "%UserOption%"=="1" goto WebUIMenu
if "%UserOption%"=="2" goto StandaloneMenu
if "%UserOption%"=="9" goto End
goto MainMenu
:WebUIMenu
cls
echo.
echo %L_BLUE%TEXT-GENERATION-WEBUI SETUP%RESET%
echo.
echo Please ensure you have started your Text-generation-webui Python
echo environment. If you have NOT done this, please run %L_GREEN%cmd_windows.bat%RESET%
echo in the %L_GREEN%text-generation-webui%RESET% folder and then re-run this script.
echo.
echo BASE REQUIREMENTS
echo 1) Apply/Re-Apply the requirements for %L_GREEN%Text-generation-webui%RESET%.
echo.
echo OPTIONAL
echo 2) Git Pull the latest AllTalk updates from Github
echo.
echo DEEPSPEED FOR %L_YELLOW=%PyTorch 2.1.x%RESET%
echo 4) Install DeepSpeed v11.2 for CUDA %L_GREEN%11.8%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.1.x%RESET%.
echo 5) Install DeepSpeed v11.2 for CUDA %L_GREEN%12.1%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.1.x%RESET%.
echo.
echo DEEPSPEED FOR %L_YELLOW=%PyTorch 2.2.x%RESET% (March 2024 builds of Text-gen-webui and later)
echo 6) Install DeepSpeed v14.0 for CUDA %L_GREEN%12.1%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.2.x%RESET%.
echo 7) Install DeepSpeed v14.0 for CUDA %L_GREEN%11.8%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.2.x%RESET%.
echo.
echo U) Uninstall DeepSpeed.
echo.
echo. OTHER
echo 8) Generate a diagnostics file.
echo.
echo 9) %L_RED%Exit/Quit%RESET%
echo.
set /p WebUIOption="Enter your choice: "
if "%WebUIOption%"=="1" goto InstallNvidiaTextGen
if "%WebUIOption%"=="2" goto TGGitpull
if "%WebUIOption%"=="4" goto InstallDeepSpeed118TextGen
if "%WebUIOption%"=="5" goto InstallDeepSpeed121TextGen
if "%WebUIOption%"=="6" goto InstallDeepSpeed121TextGenPytorch221
if "%WebUIOption%"=="7" goto InstallDeepSpeed118TextGenPytorch221
if "%WebUIOption%"=="U" goto UnInstallDeepSpeed
if "%WebUIOption%"=="u" goto UnInstallDeepSpeed
if "%WebUIOption%"=="8" goto GenerateDiagsTextGen
if "%WebUIOption%"=="9" goto End
goto WebUIMenu
:StandaloneMenu
cls
echo.
echo %L_BLUE%ALLTALK STANDALONE APPLICATION SETUP%RESET%
echo.
echo BASE REQUIREMENTS
echo 1) Install AllTalk as a Standalone Application
echo.
echo OPTIONAL
echo 2) Git Pull the latest AllTalk updates from Github
echo 3) Re-Apply/Update the requirements file
echo 4) Delete AllTalk's custom Python environment
echo 5) Purge the PIP cache
echo.
echo. OTHER
echo 8) Generate a diagnostics file
echo.
echo 9) %L_RED%Exit/Quit%RESET%
echo.
set /p StandaloneOption="Enter your choice: "
if "%StandaloneOption%"=="1" goto InstallCustomStandalone
if "%StandaloneOption%"=="2" goto STGitpull
if "%StandaloneOption%"=="3" goto STReapplyrequirements
if "%StandaloneOption%"=="4" goto STDeleteCustomStandalone
if "%StandaloneOption%"=="5" goto STPurgepipcache
if "%StandaloneOption%"=="8" goto GenerateDiagsStandalone
if "%StandaloneOption%"=="9" goto End
goto StandaloneMenu
:InstallNvidiaTextGen
pip install -r system\requirements\requirements_textgen.txt
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error installing the requirements.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo Requirements installed successfully.
Echo.
pause
goto WebUIMenu
:TGGitpull
git pull
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error pulling from Github.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo AllTalk Updated from Github. Please re-apply
echo the latest requirements file. Option 1
Echo.
pause
goto WebUIMenu
:InstallDeepSpeed118TextGen
echo Downloading DeepSpeed...
curl -LO https://github.com/erew123/alltalk_tts/releases/download/deepspeed/deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to download DeepSpeed wheel file.
echo Please check your internet connection or try again later.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
echo DeepSpeed wheel file downloaded successfully.
echo Installing DeepSpeed...
pip install deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to install DeepSpeed.
echo Please check if the wheel file is compatible with your system.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo DeepSpeed installed successfully.
Echo.
del deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
pause
goto WebUIMenu
:InstallDeepSpeed121TextGen
echo Downloading DeepSpeed...
curl -LO https://github.com/erew123/alltalk_tts/releases/download/deepspeed/deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to download DeepSpeed wheel file.
echo Please check your internet connection or try again later.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
echo DeepSpeed wheel file downloaded successfully.
echo Installing DeepSpeed...
pip install deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to install DeepSpeed.
echo Please check if the wheel file is compatible with your system.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo DeepSpeed installed successfully.
Echo.
del deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
pause
goto WebUIMenu
:InstallDeepSpeed121TextGenPytorch221
echo Downloading DeepSpeed...
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to download DeepSpeed wheel file.
echo Please check your internet connection or try again later.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
echo DeepSpeed wheel file downloaded successfully.
echo Installing DeepSpeed...
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to install DeepSpeed.
echo Please check if the wheel file is compatible with your system.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo DeepSpeed installed successfully.
Echo.
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
pause
goto WebUIMenu
:InstallDeepSpeed118TextGenPytorch221
echo Downloading DeepSpeed...
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to download DeepSpeed wheel file.
echo Please check your internet connection or try again later.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
echo DeepSpeed wheel file downloaded successfully.
echo Installing DeepSpeed...
pip install deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to install DeepSpeed.
echo Please check if the wheel file is compatible with your system.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo DeepSpeed installed successfully.
Echo.
del deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
pause
goto WebUIMenu
:UnInstallDeepSpeed
pip uninstall deepspeed
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error uninstalling DeepSpeed.
echo Press any key to return to the menu.
echo.
pause
goto WebUIMenu
)
echo.
Echo DeepSpeed uninstalled successfully.
Echo.
pause
goto WebUIMenu
:GenerateDiagsTextGen
Python diagnostics.py
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error running diagnostics. Have you correctly started your
echo Text-generation-webui Python environment with %L_GREEN%cmd_windows.bat%RESET%?
echo.
pause
goto WebUIMenu
)
Echo.
echo.
Echo Diagnostics.log generated. Please scroll up to look over the log.
Echo.
pause
goto WebUIMenu
:InstallCustomStandalone
set PATH=%PATH%;%SystemRoot%\system32
@rem Check if curl is available
curl --version >nul 2>&1
if "%ERRORLEVEL%" NEQ "0" (
echo curl is not available on this system. Please install curl then re-run the script https://curl.se/
echo or perform a manual installation of a Conda Python environment.
goto end
)
echo "%CD%"| findstr /C:" " >nul && echo This script relies on Miniconda which can not be silently installed under a path with spaces. Please correct your folder names and re-try installation. && goto exit
@rem Check for special characters in installation path
set "SPCHARMESSAGE=WARNING: Special characters were detected in the installation path! This can cause the installation to fail!"
echo "%CD%"| findstr /R /C:"[!#\$%&()\*+,;<=>?@\[\]\^`{|}~]" >nul && (
call :PrintBigMessage %SPCHARMESSAGE%
)
set SPCHARMESSAGE=
@rem fix failed install when installing to a separate drive
set TMP=%cd%\alltalk_environment
set TEMP=%cd%\alltalk_environment
@rem deactivate existing conda envs as needed to avoid conflicts
(call conda deactivate && call conda deactivate && call conda deactivate) 2>nul
@rem config
set INSTALL_DIR=%cd%\alltalk_environment
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
set MINICONDA_DOWNLOAD_URL=https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Windows-x86_64.exe
set conda_exists=F
@rem figure out whether git and conda need to be installed
call "%CONDA_ROOT_PREFIX%\_conda.exe" --version >nul 2>&1
if "%ERRORLEVEL%" EQU "0" (
set conda_exists=T
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
goto RunScript
)
@rem download and install conda if not installed
echo Downloading Miniconda from %MINICONDA_DOWNLOAD_URL% to %INSTALL_DIR%\miniconda_installer.exe
mkdir "%INSTALL_DIR%"
call curl -Lk "%MINICONDA_DOWNLOAD_URL%" > "%INSTALL_DIR%\miniconda_installer.exe" || ( echo. && echo Miniconda failed to download. && goto end )
echo Installing Miniconda to %CONDA_ROOT_PREFIX%
start /wait "" "%INSTALL_DIR%\miniconda_installer.exe" /InstallationType=JustMe /NoShortcuts=1 /AddToPath=0 /RegisterPython=0 /NoRegistry=1 /S /D=%CONDA_ROOT_PREFIX%
echo Miniconda version:
call "%CONDA_ROOT_PREFIX%\_conda.exe" --version || ( echo. && echo Miniconda not found. && goto end )
@rem create the installer env
echo Packages to install: %PACKAGES_TO_INSTALL%
call "%CONDA_ROOT_PREFIX%\_conda.exe" create --no-shortcuts -y -k --prefix "%INSTALL_ENV_DIR%" python=3.11 || ( echo. && echo Conda environment creation failed. && goto end )
@rem check if conda environment was actually created
if not exist "%INSTALL_ENV_DIR%\python.exe" ( echo. && echo Conda environment is empty. && goto end )
@rem activate installer env
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" || ( echo. && echo Miniconda hook not found. && goto end )
echo.
echo Downloading and installing PyTorch. This step can take a long time
echo depending on your internet connection and hard drive speed. Please
echo be patient.
echo.
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --extra-index-url https://download.pytorch.org/whl/cu121
echo Installing other requirements.
echo.
pip install -r system\requirements\requirements_standalone.txt
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-12.7/deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
echo Installing DeepSpeed...
pip install deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
del deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
@rem Create start_environment.bat to run AllTalk environment
echo @echo off > start_environment.bat
echo cd /D "%~dp0" >> start_environment.bat
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_environment.bat
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_environment.bat
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_environment.bat
@rem Create start_alltalk.bat to run AllTalk
echo @echo off > start_alltalk.bat
echo cd /D "%~dp0" >> start_alltalk.bat
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_alltalk.bat
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_alltalk.bat
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_alltalk.bat
echo call python script.py >> start_alltalk.bat
@rem Create start_finetune.bat to run AllTalk
echo @echo off > start_finetune.bat
echo cd /D "%~dp0" >> start_finetune.bat
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_finetune.bat
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_finetune.bat
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_finetune.bat
echo call python finetune.py >> start_finetune.bat
Echo.
Echo Run %L_YELLOW%start_alltalk.bat%RESET% to start AllTalk.
Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning.
Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment.
Echo.
pause
goto StandaloneMenu
:STDeleteCustomStandalone
@rem Check if the alltalk_environment directory exists
if not exist "%cd%\alltalk_environment\" (
echo.
echo %L_GREEN%alltalk_environment%RESET% directory does not exist. No need to delete.
echo.
pause
goto StandaloneMenu
)
@rem Check if a Conda environment is active
if not defined CONDA_PREFIX goto NoCondaEnvDeleteCustomStandalone
@rem Deactivate Conda environment if it's active
Echo Exiting the Conda Environment. Please run %L_GREEN%atsetup.bat%RESET% again and delete the environment.
conda deactivate
:NoCondaEnvDeleteCustomStandalone
echo Deleting "alltalk_environment". Please wait.
rd /s /q "alltalk_environment"
del start_alltalk.bat
del start_environment.bat
if %ERRORLEVEL% neq 0 (
echo.
echo Failed to delete alltalk_environment folder.
echo Please make sure it is not in use and try again.
echo.
pause
goto StandaloneMenu
)
echo.
Echo.
echo Environment %L_GREEN%alltalk_environment%RESET% deleted. Please set up the environment again.
Echo.
pause
goto StandaloneMenu
:GenerateDiagsStandalone
cd /D "%~dp0"
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
@rem Check if the Conda environment exists
if not exist "%INSTALL_ENV_DIR%\python.exe" (
echo.
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
echo Please install the environment before proceeding.
echo.
pause
goto StandaloneMenu
)
@rem Attempt to activate the Conda environment
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
if errorlevel 1 (
echo.
echo Failed to activate the Conda environment.
echo Please check your installation and try again.
echo.
pause
goto StandaloneMenu
)
@rem Run diagnostics
Python diagnostics.py
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error running diagnostics.
echo Press any key to return to the menu.
echo.
pause
goto StandaloneMenu
)
Echo.
Echo.
Echo Diagnostics.log generated. Please scroll up to look over the log.
Echo.
pause
goto StandaloneMenu
:STReapplyrequirements
cd /D "%~dp0"
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
@rem Check if the Conda environment exists
if not exist "%INSTALL_ENV_DIR%\python.exe" (
echo.
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
echo Please install the environment before proceeding.
echo.
pause
goto StandaloneMenu
)
@rem Attempt to activate the Conda environment
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
if errorlevel 1 (
echo.
echo Failed to activate the Conda environment.
echo Please check your installation and try again.
echo.
pause
goto StandaloneMenu
)
@rem Run Reapply requirements
echo.
echo Downloading and installing PyTorch. This step can take a long time
echo depending on your internet connection and hard drive speed. Please
echo be patient.
echo.
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --extra-index-url https://download.pytorch.org/whl/cu121
echo Installing other requirements.
echo.
pip install -r system\requirements\requirements_standalone.txt
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-12.7/deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
echo Installing DeepSpeed...
pip install deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
del deepspeed-0.12.7+d058d4b-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error.
echo Press any key to return to the menu.
echo.
pause
goto StandaloneMenu
)
Echo.
Echo.
Echo Requirements have been re-applied/updated.
Echo.
pause
goto StandaloneMenu
:STPurgepipcache
cd /D "%~dp0"
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
@rem Check if the Conda environment exists
if not exist "%INSTALL_ENV_DIR%\python.exe" (
echo.
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
echo Please install the environment before proceeding.
echo.
pause
goto StandaloneMenu
)
@rem Attempt to activate the Conda environment
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
if errorlevel 1 (
echo.
echo Failed to activate the Conda environment.
echo Please check your installation and try again.
echo.
pause
goto StandaloneMenu
)
@rem Clear the PIP cache
echo.
echo Purging the PIP cache of downloaded files.
echo.
pip cache purge
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error.
echo Press any key to return to the menu.
echo.
pause
goto StandaloneMenu
)
Echo.
Echo The PIP cache has been purged.
Echo.
pause
goto StandaloneMenu
:STGitpull
cd /D "%~dp0"
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
@rem Check if the Conda environment exists
if not exist "%INSTALL_ENV_DIR%\python.exe" (
echo.
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
echo Please install the environment before proceeding.
echo.
pause
goto StandaloneMenu
)
@rem Attempt to activate the Conda environment
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
if errorlevel 1 (
echo.
echo Failed to activate the Conda environment.
echo Please check your installation and try again.
echo.
pause
goto StandaloneMenu
)
@rem Pull from Github
echo.
echo Pulling the latest updates. Please re-apply
echo the latest requirements file. Option 3
echo.
git pull
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error pulling from Github.
echo Press any key to return to the menu.
echo.
pause
goto StandaloneMenu
)
Echo.
echo AllTalk Updated from Github. Please re-apply
echo the latest requirements file. Option 3
Echo.
pause
goto StandaloneMenu
:End
echo Exiting AllTalk Setup Utility...
exit /b
+486
View File
@@ -0,0 +1,486 @@
#!/bin/bash
# ANSI color codes
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
MAGENTA='\033[1;35m'
WHITE='\033[1;37m'
L_RED='\033[1;91m'
L_GREEN='\033[1;92m'
L_YELLOW='\033[1;93m'
L_BLUE='\033[1;94m'
L_CYAN='\033[1;96m'
L_MAGENTA='\033[1;95m'
NC='\033[0m' # No Color
# Navigate to the script's directory
cd "$(dirname "$0")"
# Function to check if curl is installed
check_curl() {
if ! command -v curl &> /dev/null; then
echo "curl is not available on this system. Please install curl then re-run the script https://curl.se/"
echo "or perform a manual installation of a Conda Python environment."
exit 1
fi
}
# Main Menu
main_menu() {
while true; do
clear
echo
echo -e " ${L_BLUE}ALLTALK LINUX SETUP UTILITY${NC}"
echo
echo " INSTALLATION TYPE"
echo -e " 1) I am using AllTalk as part of ${L_GREEN}Text-generation-webui${NC}"
echo -e " 2) I am using AllTalk as a ${L_GREEN}Standalone Application${NC}"
echo
echo -e " 9)${L_RED} Exit/Quit${NC}"
echo
read -p " Enter your choice: " user_option
case $user_option in
1) webui_menu ;;
2) standalone_menu ;;
9) exit 0 ;;
*) echo "Invalid option"; sleep 2 ;;
esac
done
}
# Text-generation-webui Menu
webui_menu() {
while true; do
clear
echo
echo -e " ${L_BLUE}TEXT-GENERATION-WEBUI SETUP${NC}"
echo
echo -e " Please ensure you have started your Text-generation-webui Python"
echo -e " environment. If you have NOT done this, please run ${L_GREEN}/cmd_linux.sh${NC}"
echo -e " in the ${L_GREEN}text-generation-webui${NC} folder and then re-run this script."
echo
echo " BASE REQUIREMENTS"
echo -e " 1) Apply/Re-Apply the requirements for an ${L_GREEN}Text-generation-webui${NC}"
echo
echo " OPTIONAL"
echo " 2) Git Pull the latest AllTalk updates from Github"
echo
echo " DEEPSPEED"
echo " 4) Install DeepSpeed."
echo " 5) Uninstall DeepSpeed."
echo
echo " OTHER"
echo " 6) Generate a diagnostics file."
echo
echo -e " 9)${L_RED} Exit/Quit${NC}"
echo
read -p " Enter your choice: " webui_option
case $webui_option in
1) install_nvidia_textgen ;;
2) tg_gitpull ;;
4) install_deepspeed ;;
5) uninstall_deepspeed ;;
6) generate_diagnostics_textgen ;;
9) exit 0 ;;
*) echo "Invalid option"; sleep 2 ;;
esac
done
}
install_nvidia_textgen() {
local requirements_file="system/requirements/requirements_textgen.txt"
echo " Installing Requirements from $requirements_file..."
if ! pip install -r "$requirements_file"; then
echo
echo " There was an error pulling from Github."
echo " Please check the output for details."
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " Requirements installed successfully."
echo
echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional"
echo -e " steps required. Please see the Github or documentation on DeepSeed."
echo
read -p " Press any key to continue. " -n 1
echo
}
tg_gitpull() {
echo
if ! git pull; then
echo
echo " There was an error installing the requirements."
echo " Please check the output for details."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " AllTalk Updated from Github. Please re-apply"
echo " the latest requirements file. (Option 1)"
echo
read -p " Press any key to continue. " -n 1
echo
}
# Function to install DeepSpeed
install_deepspeed() {
clear
echo
echo -e " ${L_BLUE}DEEPSPEED INSTALLATION REQUIREMENTS${NC}"
echo
echo -e " - NVIDIA CUDA Toolkit must be installed from your ${L_GREEN}Linux package manager${NC}"
echo -e " or ${L_GREEN}https://developer.nvidia.com/cuda-toolkit-archive${NC}"
echo -e " - The environment variable ${L_GREEN}CUDA_HOME${NC} must be set in your Python env"
echo -e " e.g. export CUDA_HOME=/usr/local/cuda."
echo -e " - ${L_GREEN}libaio-dev${NC} must be installed."
echo
echo -e " See the following link for full instructions:"
echo -e " ${L_GREEN}https://github.com/erew123/alltalk_tts?#-deepspeed-installation-options${NC}"
echo
echo -e " ${L_BLUE}Please ${L_RED}confirm${L_BLUE} that you have completed these steps before continuing"
echo -e " with the DeepSpeed installation, or the install ${L_RED}will fail.${NC}"
echo
read -p " Have you completed all the above steps? (y/n): " confirm
if [ "$confirm" != "y" ]; then
echo -e " ${RED}DeepSpeed installation cannot proceed without completing the prerequisites.${NC}"
return
fi
echo -e "\n ${GREEN}Proceeding with DeepSpeed installation...${NC}"
pip install deepspeed
if [ $? -ne 0 ]; then
echo -e " ${RED}There was an error installing DeepSpeed.${NC}"
return
fi
echo -e " ${GREEN}DeepSpeed installed successfully.${NC}"
read -p " Press any key to continue. " -n 1
echo
}
uninstall_deepspeed() {
echo "Uninstalling DeepSpeed..."
pip uninstall -y deepspeed
if [ $? -ne 0 ]; then
echo
echo " There was an error uninstalling DeepSpeed."
echo
echo " Press any key to return to the menu."
read -n 1
return
fi
echo
echo " DeepSpeed uninstalled successfully."
echo
echo " Press any key to continue."
read -n 1
}
generate_diagnostics_textgen() {
# Run diagnostics
if ! python diagnostics.py; then
echo
echo " There was an error running diagnostics."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " Diagnostics log file generated successfully."
echo " Please see diagnostics.log"
echo
read -p " Press any key to continue. " -n 1
echo
}
# Standalone Menu
standalone_menu() {
while true; do
clear
echo
echo -e " ${L_BLUE}ALLTALK STANDALONE APPLICATION SETUP${NC}"
echo
echo " BASE REQUIREMENTS"
echo " 1) Install AllTalk as a Standalone Application"
echo
echo " OPTIONAL"
echo " 2) Git Pull the latest AllTalk updates from Github"
echo " 3) Re-Apply/Update the requirements file"
echo " 4) Delete AllTalk's custom Python environment"
echo " 5) Purge the PIP cache"
echo
echo " DEEPSPEED"
echo " 6) DeepSpeed Instructions/Install"
echo
echo " OTHER"
echo " 8) Generate a diagnostics file"
echo
echo -e " 9)${L_RED} Exit/Quit${NC}"
echo
read -p " Enter your choice: " standalone_option
case $standalone_option in
1) install_custom_standalone ;;
2) gitpull_standalone ;;
3) reapply_standalone ;;
4) delete_custom_standalone ;;
5) pippurge_standalone ;;
6) install_deepspeed ;;
8) generate_diagnostics_standalone ;;
9) exit 0 ;;
*) echo "Invalid option"; sleep 2 ;;
esac
done
}
install_custom_standalone() {
cd "$(dirname "${BASH_SOURCE[0]}")"
if [[ "$(pwd)" =~ " " ]]; then
echo "This script relies on Miniconda which can not be silently installed under a path with spaces."
exit
fi
# Deactivate existing conda envs as needed to avoid conflicts
{ conda deactivate && conda deactivate && conda deactivate; } 2> /dev/null
OS_ARCH=$(uname -m)
case "${OS_ARCH}" in
x86_64*) OS_ARCH="x86_64" ;;
arm64* | aarch64*) OS_ARCH="aarch64" ;;
*) echo "Unknown system architecture: $OS_ARCH! This script runs only on x86_64 or arm64" && exit ;;
esac
# Config
INSTALL_DIR="$(pwd)/alltalk_environment"
CONDA_ROOT_PREFIX="${INSTALL_DIR}/conda"
INSTALL_ENV_DIR="${INSTALL_DIR}/env"
MINICONDA_DOWNLOAD_URL="https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-${OS_ARCH}.sh"
if [ ! -x "${CONDA_ROOT_PREFIX}/bin/conda" ]; then
echo "Downloading Miniconda from $MINICONDA_DOWNLOAD_URL to ${INSTALL_DIR}/miniconda_installer.sh"
mkdir -p "${INSTALL_DIR}"
curl -L "${MINICONDA_DOWNLOAD_URL}" -o "${INSTALL_DIR}/miniconda_installer.sh"
chmod +x "${INSTALL_DIR}/miniconda_installer.sh"
bash "${INSTALL_DIR}/miniconda_installer.sh" -b -p "${CONDA_ROOT_PREFIX}"
echo "Miniconda installed."
fi
if [ ! -d "${INSTALL_ENV_DIR}" ]; then
"${CONDA_ROOT_PREFIX}/bin/conda" create -y --prefix "${INSTALL_ENV_DIR}" python=3.11
echo "Conda environment created at ${INSTALL_ENV_DIR}."
fi
# Activate the environment and install requirements
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}"
echo
echo " Downloading and installing PyTorch. This step can take a long time"
echo " depending on your internet connection and hard drive speed. Please"
echo " be patient."
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --extra-index-url https://download.pytorch.org/whl/cu121
echo
echo " Installing additional requirements."
echo
pip install -r system/requirements/requirements_standalone.txt
# Create start_environment.sh to run AllTalk
cat << EOF > start_environment.sh
#!/bin/bash
cd "$(dirname "${BASH_SOURCE[0]}")"
if [[ "$(pwd)" =~ " " ]]; then echo This script relies on Miniconda which can not be silently installed under a path with spaces. && exit; fi
# deactivate existing conda envs as needed to avoid conflicts
{ conda deactivate && conda deactivate && conda deactivate; } 2> /dev/null
# config
CONDA_ROOT_PREFIX="$(pwd)/alltalk_environment/conda"
INSTALL_ENV_DIR="$(pwd)/alltalk_environment/env"
# environment isolation
export PYTHONNOUSERSITE=1
unset PYTHONPATH
unset PYTHONHOME
export CUDA_PATH="$INSTALL_ENV_DIR"
export CUDA_HOME="$CUDA_PATH"
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
# activate env
bash --init-file <(echo "source \"$CONDA_ROOT_PREFIX/etc/profile.d/conda.sh\" && conda activate \"$INSTALL_ENV_DIR\"")
EOF
# Create start_alltalk.sh to run AllTalk
cat << EOF > start_alltalk.sh
#!/bin/bash
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}"
python script.py
EOF
# Create start_finetune.sh to run AllTalk
cat << EOF > start_finetune.sh
#!/bin/bash
export TRAINER_TELEMETRY=0
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}"
python finetune.py
EOF
chmod +x start_alltalk.sh
chmod +x start_environment.sh
chmod +x start_finetune.sh
echo
echo
echo -e " Run ${L_YELLOW}./start_alltalk.sh${NC} to start AllTalk."
echo -e " Run ${L_YELLOW}./start_finetune.sh${NC} to start Finetuning."
echo -e " Run ${L_YELLOW}./start_environment.sh${NC} to start the AllTalk Python environment."
echo
echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional"
echo -e " steps required. Please see the Github or documentation on DeepSeed."
echo
read -p " Press any key to continue. " -n 1
}
delete_custom_standalone() {
local env_dir="$PWD/alltalk_environment"
# Check if the alltalk_environment directory exists
if [ ! -d "$env_dir" ]; then
echo " \"$env_dir\" directory does not exist. No need to delete."
read -p " Press any key to continue. " -n 1
echo
return
fi
# Check if a Conda environment is active and deactivate it
if [ -n "$CONDA_PREFIX" ]; then
echo " Exiting the Conda environment. You may need to start ./atstart.sh again"
conda deactivate
fi
echo "Deleting \"$env_dir\". Please wait."
rm -rf "$env_dir"
if [ -d "$env_dir" ]; then
echo " Failed to delete \"$env_dir\" folder."
echo " Please make sure it is not in use and try again."
else
echo " Environment \"$env_dir\" deleted successfully."
fi
read -p " Press any key to continue. " -n 1
echo
}
generate_diagnostics_standalone() {
local env_dir="$PWD/alltalk_environment"
local conda_root_prefix="${env_dir}/conda"
local install_env_dir="${env_dir}/env"
if [ ! -d "${install_env_dir}" ]; then
echo
echo " The Conda environment at '${install_env_dir}' does not exist."
echo " Please install the environment before proceeding."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
source "${conda_root_prefix}/etc/profile.d/conda.sh"
conda activate "${install_env_dir}"
if ! python diagnostics.py; then
echo
echo " There was an error running diagnostics."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " Diagnostics completed successfully."
read -p " Press any key to continue. " -n 1
echo
}
gitpull_standalone() {
local env_dir="$PWD/alltalk_environment"
local conda_root_prefix="${env_dir}/conda"
local install_env_dir="${env_dir}/env"
if [ ! -d "${install_env_dir}" ]; then
echo
echo " The Conda environment at '${install_env_dir}' does not exist."
echo " Please install the environment before proceeding."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
source "${conda_root_prefix}/etc/profile.d/conda.sh"
conda activate "${install_env_dir}"
if ! git pull; then
echo
echo " There was an error pulling from Github."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " AllTalk Updated from Github. Please re-apply."
echo " the latest requirements file. (Option 3)"
echo
read -p " Press any key to continue. " -n 1
echo
}
pippurge_standalone() {
if ! pip cache purge; then
echo
echo " There was an error."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " The PIP cache has been purged."
echo
read -p " Press any key to continue. " -n 1
echo
}
reapply_standalone() {
local env_dir="$PWD/alltalk_environment"
local conda_root_prefix="${env_dir}/conda"
local install_env_dir="${env_dir}/env"
if [ ! -d "${install_env_dir}" ]; then
echo
echo " The Conda environment at '${install_env_dir}' does not exist."
echo " Please install the environment before proceeding."
echo
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
source "${conda_root_prefix}/etc/profile.d/conda.sh"
conda activate "${install_env_dir}"
echo
echo " Downloading and installing PyTorch. This step can take a long time"
echo " depending on your internet connection and hard drive speed. Please"
echo " be patient."
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --extra-index-url https://download.pytorch.org/whl/cu121
echo
echo " Installing additional requirements."
echo
pip install -r system/requirements/requirements_standalone.txt
echo
echo " Requirements have been re-applied/updated."
echo
read -p " Press any key to continue. " -n 1
echo
}
# Start the main menu
main_menu
+25 -1
View File
@@ -1 +1,25 @@
{"activate": true, "autoplay": true, "branding": "AllTalk ", "narrator_enabled": false, "deepspeed_activate": false, "delete_output_wavs": "Disabled", "ip_address": "127.0.0.1", "language": "English", "low_vram": false, "local_temperature": "0.7", "local_repetition_penalty": "10.0", "tts_model_loaded": true, "tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2", "narrator_voice": "female_01.wav", "output_folder_wav": "extensions/alltalk_tts/outputs/", "output_folder_wav_standalone": "outputs/", "port_number": "7851", "remove_trailing_dots": false, "show_text": true, "tts_method_api_local": false, "tts_method_api_tts": false, "tts_method_xtts_local": true, "voice": "female_01.wav"}
{
"activate": true,
"autoplay": true,
"branding": "AllTalk ",
"narrator_enabled": false,
"deepspeed_activate": false,
"delete_output_wavs": "Disabled",
"ip_address": "127.0.0.1",
"language": "English",
"low_vram": false,
"local_temperature": "0.7",
"local_repetition_penalty": "10.0",
"tts_model_loaded": true,
"tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2",
"narrator_voice": "female_01.wav",
"output_folder_wav": "extensions/alltalk_tts/outputs/",
"output_folder_wav_standalone": "outputs/",
"port_number": "7851",
"remove_trailing_dots": false,
"show_text": true,
"tts_method_api_local": false,
"tts_method_api_tts": false,
"tts_method_xtts_local": true,
"voice": "female_01.wav"
}
+242 -25
View File
@@ -2,16 +2,30 @@ try:
import platform
import subprocess
import logging
from importlib_metadata import distribution, distributions
from importlib_metadata import distributions
import torch
import os # Import the os module
import re
import sys
import glob
import site
import textwrap
import torch
import packaging.version
import packaging.specifiers
from packaging.specifiers import SpecifierSet
from packaging.specifiers import SpecifierSet
from packaging.version import parse as parse_version
from pathlib import Path
except ImportError as e:
print(f"\033[91mError importing module: {e}\033[0m\n")
print("\033[94mPlease ensure you started the Text-generation-webUI Python environment with either\033[0m")
print("\033[92mcmd_linux.sh\033[0m, \033[92mcmd_windows.bat\033[0m, \033[92mcmd_macos.sh\033[0m, or \033[92mcmd_wsl.bat\033[0m")
print("\033[94mand then try running the diagnostics again.\033[0m")
print("\033[94mfrom the text-generation-webui directory, and then try running the diagnostics again.\033[0m")
exit(1)
this_dir = Path(__file__).parent
try:
import psutil
except ImportError:
@@ -19,8 +33,31 @@ except ImportError:
subprocess.run(['pip', 'install', 'psutil'])
import psutil
# Additional import for torch
import torch
def get_requirements_file():
this_dir = Path(__file__).parent # Assuming 'this_dir' is defined as the script's directory
requirements_dir = this_dir / 'system' / 'requirements'
requirements_files = list(requirements_dir.glob('requirements*.txt')) # Using pathlib for globbing
if not requirements_files:
print("\033[91mNo requirements files found.\033[0m")
return None
print("\033[94m\nSelect a requirements file to check against (or press Enter for default 'requirements.txt'):\033[0m\n")
for i, file_path in enumerate(requirements_files, start=1):
print(f" {i}. {file_path.name}") # Only print the filename
choice = input("\nEnter the number of your choice: ")
try:
choice = int(choice) - 1
return str(requirements_files[choice]) # Return the full path as a string
except (ValueError, IndexError):
return str(requirements_dir / "requirements.txt") # Return the default path as a string
# Set up logging with filemode='w'
logging.basicConfig(filename='diagnostics.log',
filemode='w',
level=logging.INFO,
format='%(message)s') # Custom format
# Function to get GPU information using subprocess
def get_gpu_info():
@@ -29,6 +66,22 @@ def get_gpu_info():
return result.stdout
except FileNotFoundError:
return "NVIDIA GPU information not available"
def get_cpu_info():
cpu_info = {
'physical_cores': psutil.cpu_count(logical=False),
'total_cores': psutil.cpu_count(logical=True),
'max_frequency': psutil.cpu_freq().max
}
return cpu_info
def get_disk_info():
disk_info = []
partitions = psutil.disk_partitions()
for p in partitions:
usage = psutil.disk_usage(p.mountpoint)
disk_info.append(f" Drive: {p.device} | Total: {usage.total / (1024 ** 3):.2f} GB | Used: {usage.used / (1024 ** 3):.2f} GB | Free: {usage.free / (1024 ** 3):.2f} GB | Type: {p.fstype}")
return disk_info
# Function to check if a port is in use
def is_port_in_use(port):
@@ -37,6 +90,48 @@ def is_port_in_use(port):
return True
return False
def satisfies_wildcard(installed_version, required_version):
if '*' in required_version:
required_parts = required_version.split('.')
installed_parts = installed_version.split('.')
for req, inst in zip(required_parts, installed_parts):
if req != '*' and req != inst:
return False
return True
return False
def test_cuda():
cuda_available = torch.cuda.is_available()
if cuda_available:
try:
# Attempt to create a tensor on GPU
torch.tensor([1.0, 2.0]).cuda()
return "Success - CUDA is available and working."
except Exception as e:
return f"Fail - CUDA is available but not working. Error: {e}"
else:
return "Fail - CUDA is not available."
def find_files_in_path_with_wildcard(pattern):
# Get the site-packages directory of the current Python environment
site_packages_path = site.getsitepackages()
found_paths = []
# Adjust the sub-directory based on the operating system
sub_directory = "nvidia/cublas"
if platform.system() == "Linux":
sub_directory = os.path.join(sub_directory, "lib")
else:
sub_directory = os.path.join(sub_directory, "bin")
# Iterate over each site-packages directory (there can be more than one)
for directory in site_packages_path:
# Construct the search directory path
search_directory = os.path.join(directory, sub_directory)
# Use glob to find all files matching the pattern in this directory
for file_path in glob.glob(os.path.join(search_directory, pattern)):
if os.path.isfile(file_path): # Ensure it's a file
found_paths.append(file_path)
return found_paths
# Function to log and print system information
def log_system_info():
# System information
@@ -52,6 +147,9 @@ def log_system_info():
# Torch version
torch_version = torch.__version__
cuda_test_result = test_cuda()
cpu_info = get_cpu_info()
disk_info = get_disk_info()
# System RAM using psutil
try:
@@ -75,34 +173,153 @@ def log_system_info():
# Package versions using importlib_metadata
package_versions = {d.metadata['Name']: d.version for d in distributions()}
# Python environment information
python_executable = sys.executable
python_version_info = sys.version_info
python_virtual_env = os.environ.get('VIRTUAL_ENV', 'N/A')
# Conda environment information
conda_env = os.environ.get('CONDA_DEFAULT_ENV', 'N/A')
# Get Path environment information
search_path = sys.path
path_env = os.environ.get('PATH', 'N/A')
# Check for cublas
file_name = 'cublas64_11.*' if platform.system() == "Windows" else 'libcublas.so.11*'
found_paths = find_files_in_path_with_wildcard(file_name)
# Compare with requirements file
requirements_file = get_requirements_file()
if requirements_file:
required_packages = {}
installed_packages = {}
try:
with open(requirements_file, 'r') as req_file:
requirements = [line.strip() for line in req_file]
for req in requirements:
# Use regular expression to parse package name and version
match = re.match(r'([^\s>=]+)\s*([>=<]+)\s*([^,]+)', req)
if match:
package_name, operator, version_spec = match.groups()
installed_version = package_versions.get(package_name, 'Not installed')
if installed_version != 'Not installed':
required_packages[package_name] = (operator, version_spec)
installed_packages[package_name] = installed_version
except FileNotFoundError:
print(f"\n{requirements_file} not found. Skipping version checks.")
logging.info(f"NOTE {requirements_file} not found. Skipping version checks.")
# Log and print information
logging.info(f"OS Version: {os_version}")
logging.info(f"Note: Windows 11 does call itself 10")
logging.info(f"Python Version: {python_version}")
logging.info(f"Torch Version: {torch_version}")
logging.info(f"System RAM: {system_ram}")
logging.info(f"Total System RAM: {total_ram}")
logging.info(f"Available System RAM: {available_ram}")
logging.info(f"CUDA_HOME: {cuda_home}")
logging.info(f"\nPort Status: {port_status}")
logging.info(f"GPU Information:\n{gpu_info}")
logging.info("Package Versions:")
logging.info(f"OPERATING SYSTEM:")
logging.info(f" OS Version: {os_version}")
logging.info(f" Note: Windows 11 will list as build is 10.x.22xxx")
logging.info(f"\nHARDWARE ENVIRONMENT:")
logging.info(f" CPU: Physical Cores: {cpu_info['physical_cores']}, Total Cores: {cpu_info['total_cores']}, Max Frequency: {cpu_info['max_frequency']} MHz")
logging.info(f" System RAM: {system_ram}")
logging.info(f"\nGPU INFORMATION:{gpu_info}")
logging.info("DISK INFORMATION:")
for disk in disk_info:
logging.info(disk)
logging.info("\nNETWORK PORT:")
logging.info(f" Port Status: {port_status}")
logging.info("\nCUDA:")
logging.info(f" CUDA Working: {cuda_test_result}")
logging.info(f" CUDA_HOME: {cuda_home}")
if found_paths:
logging.info(f" Cublas64_11 Path: {', '.join(found_paths)}")
else:
logging.info(f" Cublas64_11 Path: Not found in any search path directories.")
logging.info("\nPYTHON & PYTORCH:")
logging.info(f" Torch Version: {torch_version}")
logging.info(f" Python Version: {platform.python_version()}")
logging.info(f" Python Version Info: {python_version_info}")
logging.info(f" Python Executable: {python_executable}")
logging.info(f" Python Virtual Environment: {python_virtual_env} (Should be N/A when in Text-generation-webui Conda Python environment)")
logging.info(f" Conda Environment: {conda_env}")
logging.info("\nPython Search Path:")
for path in search_path:
logging.info(f" {path}")
logging.info("\nOS SEARCHPATH ENVIRONMENT:")
for path in path_env.split(';'):
logging.info(f" {path}")
if required_packages: # Check if the dictionary is not empty
logging.info("\nPACKAGE VERSIONS vs REQUIREMENTS FILE:")
max_package_length = max(len(package) for package in required_packages.keys())
for package_name, (operator, required_version) in required_packages.items():
installed_version = installed_packages.get(package_name, 'Not installed')
logging.info(f" {package_name.ljust(max_package_length)} Required: {operator} {required_version.ljust(12)} Installed: {installed_version}")
logging.info("\nPYTHON PACKAGES:")
for package, version in package_versions.items():
logging.info(f"{package}>= {version}")
logging.info(f" {package}>= {version}")
# Print to screen
print(f"\033[94mOS Version:\033[0m \033[92m{os_version}\033[0m")
print(f"\033[94mNote:\033[0m \033[92mWindows 11 does call itself 10\033[0m")
print(f"\033[94mPython Version:\033[0m \033[92m{python_version}\033[0m")
print(f"\033[94mTorch Version:\033[0m \033[92m{torch_version}\033[0m")
print(f"\n\033[94mOS Version:\033[0m \033[92m{os_version}\033[0m")
print(f"\033[94mOS Ver note:\033[0m \033[92m(Windows 11 will say build is 10.x.22xxx)\033[0m")
print(f"\033[94mSystem RAM:\033[0m \033[92m{system_ram}\033[0m")
print(f"\033[94mTotal System RAM:\033[0m \033[92m{total_ram}\033[0m")
print(f"\033[94mAvailable System RAM:\033[0m \033[92m{available_ram}\033[0m")
for disk in disk_info:
print(f"\033[94mDisk:\033[0m \033[92m{disk}\033[0m")
print(f"\033[94m\nGPU Information:\033[0m {gpu_info}")
print(f"\033[94mPort Status:\033[0m \033[92m{port_status}\033[0m\n")
if "Fail" in cuda_test_result:
print(f"\033[91mCUDA Working:\033[0m \033[91m{cuda_test_result}\033[0m")
else:
print(f"\033[94mCUDA Working:\033[0m \033[92m{cuda_test_result}\033[0m")
print(f"\033[94mCUDA_HOME:\033[0m \033[92m{cuda_home}\033[0m")
print(f"\033[94mPort Status:\033[0m \033[92m{port_status}\033[0m")
if found_paths:
print(f"\033[94mCublas64_11 Path:\033[0m \033[92m{', '.join(found_paths)}\033[0m")
else:
print(f"\033[94mCublas64_11 Path:\033[0m \033[91mNot found in any search path directories.\033[0m")
print(f"\033[94m\nTorch Version:\033[0m \033[92m{torch_version}\033[0m")
print(f"\033[94mPython Version:\033[0m \033[92m{platform.python_version()}\033[0m")
print(f"\033[94mPython Executable:\033[0m \033[92m{python_executable}\033[0m")
print(f"\033[94mConda Environment:\033[0m \033[92m{conda_env}\033[0m")
print(f"\n\033[94mPython Search Path:\033[0m")
for path in search_path:
print(f" {path}")
if required_packages: # Check if the dictionary is not empty
print("\033[94m\nRequirements file package comparison:\033[0m")
max_package_length = max(len(package) for package in required_packages.keys())
for package_name, (operator, required_version) in required_packages.items():
installed_version = installed_packages.get(package_name, 'Not installed')
# Exclude build information (e.g., +cu118) before creating the SpecifierSet
required_version_no_build = required_version.split("+")[0]
if '*' in required_version:
condition_met = satisfies_wildcard(installed_version, required_version)
else:
# Compare versions using packaging.version
required_specifier = SpecifierSet(f"{operator}{required_version_no_build}")
installed_version = parse_version(installed_version)
condition_met = installed_version in required_specifier
color_required = "\033[92m" if condition_met else "\033[91m"
color_installed = "\033[92m" if condition_met else "\033[91m"
# Print colored output
print(f" {package_name.ljust(max_package_length)} Required: {color_required}{operator} {required_version.ljust(12)}\033[0m Installed: {color_installed}{installed_version}\033[0m")
print("\nOn Nvidia Graphics cards machines, if your \033[92mInstalled\033[0m version of \033[92mTorch\033[0m and \033[92mTorchaudio\033[0m does")
print("not have \033[92m+cu118\033[0m (Cuda 11.8) or \033[92m+cu121\033[0m (Cuda 12.1) listed after them, you do not have CUDA")
print("installed for Torch or Torchaudio in this Python environment. This will cause you problems")
print("with \033[94mAllTalk\033[0m and \033[94mFinetuning.\033[0m You may have to 'pip install' a new version of torch and")
print("torchaudio, using '\033[94m--upgrade --force-reinstall\033[0m' with the correct version of PyTorch for\033[0m")
print("your Python environment.\033[0m")
print("\033[94m\nRequirements file specifier meanings:\033[0m")
explanation = textwrap.dedent("""
== Exact version != Any version except < Less than
<= Less than or equal to > Greater than >= Greater than or equal to
~ Compatible release ; Environment marker AND Logical AND
OR Logical OR
""")
print(explanation.strip())
print("")
print(f"GPU Information:{gpu_info}")
print(f"\033[94mDiagnostic log created:\033[0m \033[92mdiagnostics.log\033[0m")
print(f"\033[94mDiagnostic log created:\033[0m \033[92mdiagnostics.log. \033[94mA brief summary of results is displayed above on\033[0m")
print(f"\033[94mscreen. Please see the log file for more detail.\033[0m")
print(f"\033[94m\nPlease upload the log file with any support ticket.\033[0m")
if __name__ == "__main__":
log_system_info()
+20
View File
@@ -0,0 +1,20 @@
version: '3.8'
services:
alltalk-tts:
image: erew123/alltalk_tts:cuda
restart: unless-stopped
ports:
- "7851:7851"
volumes:
- ./outputs:/app/outputs/
- ./models:/app/models/
- ./voices:/app/voices/
- ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here
- ./dockerconfig.json:/app/confignew.json
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [ gpu ]
+13
View File
@@ -0,0 +1,13 @@
version: '3.8'
services:
alltalk-tts:
image: erew123/alltalk_tts:cpu
restart: unless-stopped
ports:
- "7851:7851"
volumes:
- ./outputs:/app/outputs/
- ./models:/app/models/
- ./voices:/app/voices/
- ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here
- ./dockerconfig.json:/app/confignew.json
+25
View File
@@ -0,0 +1,25 @@
{
"activate": true,
"autoplay": true,
"branding": "AllTalk ",
"narrator_enabled": false,
"deepspeed_activate": true,
"delete_output_wavs": "Disabled",
"ip_address": "127.0.0.1",
"language": "English",
"low_vram": false,
"local_temperature": "0.7",
"local_repetition_penalty": "10.0",
"tts_model_loaded": true,
"tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2",
"narrator_voice": "female_01.wav",
"output_folder_wav": "extensions/alltalk_tts/outputs/",
"output_folder_wav_standalone": "outputs/",
"port_number": "7851",
"remove_trailing_dots": false,
"show_text": true,
"tts_method_api_local": false,
"tts_method_api_tts": false,
"tts_method_xtts_local": true,
"voice": "female_01.wav"
}
+1726
View File
File diff suppressed because it is too large. Load diff
Whitespace-only changes.
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
python modeldownload.py
uvicorn tts_server:app --host 0.0.0.0 --port 7851 --workers 1 --proxy-headers &
sleep 5
python script.py
+4 -1
View File
@@ -6,6 +6,9 @@
"README.md": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/README.md?download=true",
"config.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/config.json?download=true",
"model.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/model.pth?download=true",
"dvae.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/dvae.pth?download=true",
"mel_stats.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/mel_stats.pth?download=true",
"speakers_xtts.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/speakers_xtts.pth?download=true",
"vocab.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/vocab.json?download=true"
}
}
}
+4 -4
View File
@@ -45,18 +45,18 @@ else:
)
# Read the version specifier from requirements_nvidia.txt
with open(this_dir / "requirements_nvidia.txt", "r") as req_file:
with open(this_dir / "system" / "requirements" / "requirements_standalone.txt", "r") as req_file:
requirements = req_file.readlines()
tts_version_required = None
for req in requirements:
if req.startswith("TTS>="):
tts_version_required = req.strip().split(">=")[1]
if req.startswith("TTS=="):
tts_version_required = req.strip().split("==")[1]
break
if tts_version_required is None:
raise ValueError(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements_nvidia.txt"
f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements file"
)
+20
View File
@@ -0,0 +1,20 @@
FROM nvidia/cuda:12.1.1-devel-ubuntu22.04
ENV HOST 0.0.0.0
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y git build-essential portaudio19-dev \
python3 python3-pip gcc wget \
ocl-icd-opencl-dev opencl-headers clinfo \
libclblast-dev libopenblas-dev \
&& mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd \
&& ln -s /usr/bin/python3 /usr/bin/python
WORKDIR /app
COPY . .
ENV CUDA_DOCKER_ARCH=all
RUN pip install --no-cache-dir -r requirements_nvidia.txt && \
pip install --no-cache-dir -r requirements_finetune.txt && \
pip install --no-cache-dir -r requirements_other.txt && \
pip install --no-cache-dir deepspeed
EXPOSE 7851
RUN chmod +x launch.sh
ENTRYPOINT ["sh", "-c", "./launch.sh"]
-12
View File
@@ -1,12 +0,0 @@
numpy>=1.22.0
soundfile>=0.12.1
uvicorn>=0.24.0.post1
TTS>=0.22.0
torch>=2.1.0+cu118
torchaudio>=2.1.0+cu118
fastapi>=0.104.1
Jinja2>=3.1.2
requests>=2.31.0
tqdm>=4.66.1
importlib-metadata>=4.8.1
packaging>=23.2
-12
View File
@@ -1,12 +0,0 @@
numpy>=1.22.0
soundfile>=0.12.1
uvicorn>=0.24.0.post1
TTS>=0.22.0
torch>=2.1.0
torchaudio>=2.1.0
fastapi>=0.104.1
Jinja2>=3.1.2
requests>=2.31.0
tqdm>=4.66.1
importlib-metadata>=4.8.1
packaging>=23.2
+392 -210
View File
@@ -16,18 +16,28 @@ import numpy as np
import soundfile as sf
import uuid
######################################
#### ALLTALK ALLOWED STARTUP TIME ####
######################################
startup_wait_time = 120
# You can change the above setting to a larger number to allow AllTAlk more time to start up. The default setting is 120 seconds (2 minutes).
# On some older systems you may need to allow AllTalk more time. So you could set it to 240 (4 minutes) which will give AllTalk more to load.
#################################################################
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
#################################################################
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
this_dir = Path(__file__).parent.resolve()
# load config file in and get settings
def load_config(file_path):
with open(file_path, "r") as config_file:
config = json.load(config_file)
return config
config_file_path = this_dir / "confignew.json"
# Load the params dictionary from the confignew.json file
params = load_config(config_file_path)
@@ -39,8 +49,8 @@ try:
except ModuleNotFoundError:
logger.error(
f"[{params['branding']}]\033[91mWarning\033[0m Could not find the TTS module. Make sure to install the requirements for the {params['branding']} extension."
f"[{params['branding']}]\033[91mWarning\033[0m Linux / Mac:\npip install -r extensions/alltalk_tts/requirements.txt\n"
f"[{params['branding']}]\033[91mWarning\033[0m Windows:\npip install -r extensions\\alltalk_tts\\requirements.txt\n"
f"[{params['branding']}]\033[91mWarning\033[0m Linux / Mac:\npip install -r /alltalk_tts/requirements.txt\n"
f"[{params['branding']}]\033[91mWarning\033[0m Windows:\npip install -r \\alltalk_tts\\requirements.txt\n"
f"[{params['branding']}]\033[91mWarning\033[0m If you used the one-click installer, paste the command above in the terminal window launched after running the cmd_ script. On Windows, that's cmd_windows.bat."
)
raise
@@ -48,6 +58,7 @@ except ModuleNotFoundError:
# IMPORT - Attempt Importing DeepSpeed (required for displaying Deepspeed checkbox in gradio)
try:
import deepspeed
deepspeed_installed = True
except ImportError:
deepspeed_installed = False
@@ -60,9 +71,12 @@ try:
from modules.logging_colors import logger
from modules.ui import create_refresh_button
from modules.utils import gradio
# This is set to check if the script is being run within text generation webui or as a standalone script. False is running as part of text gen web ui or a gradio interface
running_in_standalone = False
output_folder_wav = params["output_folder_wav"]
except ModuleNotFoundError:
output_folder_wav = params["output_folder_wav_standalone"]
print(f"[{params['branding']}Startup] Running script.py in standalone mode")
# This is set to check if the script is being run within text generation webui or as a standalone script. true means standalone
running_in_standalone = True
@@ -71,15 +85,19 @@ except ModuleNotFoundError:
#### STARTUP VARIABLES ####
###########################
# STARTUP VARIABLE - Import languges file for Gradio to be able to display them in the interface
with open(this_dir / "languages.json", encoding="utf8") as f:
with open(this_dir / "system" / "config" / "languages.json", encoding="utf8") as f:
languages = json.load(f)
# Create a global lock
process_lock = threading.Lock()
# Base setting for a possible FineTuned model existing and the loader being available
tts_method_xtts_ft = False
# Gather the voice files
def get_available_voices():
return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")])
#########################
#### LICENSE DISPLAY ####
#########################
@@ -108,7 +126,6 @@ def delete_old_files(folder_path, days_to_keep):
# Extract settings using params dictionary
delete_output_wavs_setting = params["delete_output_wavs"]
output_folder_wav = params["output_folder_wav"]
output_folder_wav = os.path.normpath(output_folder_wav)
# Check and perform file deletion
@@ -142,6 +159,22 @@ def check_required_files():
# STARTUP Call Check routine
check_required_files()
##################################################
#### Check to see if a finetuned model exists ####
##################################################
# Set the path to the directory
trained_model_directory = this_dir / "models" / "trainedmodel"
# Check if the directory "trainedmodel" exists
finetuned_model = trained_model_directory.exists()
# If the directory exists, check for the existence of the required files
# If true, this will add a extra option in the Gradio interface for loading Xttsv2 FT
if finetuned_model:
required_files = ["model.pth", "config.json", "vocab.json"]
finetuned_model = all(
(trained_model_directory / file).exists() for file in required_files
)
if finetuned_model:
print(f"[{params['branding']}Startup] Finetuned model \033[93mDetected\033[0m")
####################################################
#### SET GRADIO BUTTONS BASED ON confignew.json ####
@@ -157,6 +190,7 @@ elif params["tts_method_xtts_local"] == True:
# Set the default for Narrated text without asterisk or quotes to be Narrator
non_quoted_text_is = True
######################
#### GRADIO STUFF ####
######################
@@ -214,68 +248,88 @@ def signal_handler(sig, frame):
# Attach the signal handler to the SIGINT signal (Ctrl+C)
signal.signal(signal.SIGINT, signal_handler)
# Start the subprocess
process = subprocess.Popen(["python", script_path])
# Check if the subprocess has started successfully
if process.poll() is None:
print(f"[{params['branding']}Startup] TTS Subprocess starting")
# Check if we're running in docker
if os.path.isfile("/.dockerenv"):
print(
f"[{params['branding']}Startup] Readme available here:",
f"http://{params['ip_address']}:{params['port_number']}",
f"[{params['branding']}Startup] \033[94mRunning in Docker. Please wait.\033[0m"
)
else:
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:",
params["port_number"],
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1)
timeout = 60 # Adjust the timeout as needed
# Introduce a delay before starting the check loop
time.sleep(25) # Wait 25 secs before checking if the tts_server.py has started up.
start_time = time.time()
while time.time() - start_time < timeout:
try:
response = requests.get(f"{base_url}/ready")
if response.status_code == 200:
break
except requests.RequestException as e:
# Print the exception for debugging purposes
# Start the subprocess
process = subprocess.Popen(["python", script_path])
# Check if the subprocess has started successfully
if process.poll() is None:
print(f"[{params['branding']}Startup] TTS Subprocess starting")
print(f"[{params['branding']}Startup]")
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for 60 seconds maximum. Please wait."
f"[{params['branding']}Startup] \033[94m {params['branding']}Settings & Documentation:\033[00m",
f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m",
)
time.sleep(1)
else:
print(
f"[{params['branding']}Startup] Startup timed out. Check the server logs for more information."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1)
print(f"[{params['branding']}Startup]")
else:
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:",
params["port_number"],
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1)
timeout = startup_wait_time # Gather timeout setting from startup_wait_time
# Introduce a delay before starting the check loop
time.sleep(26) # Wait 26 secs before checking if the tts_server.py has started up.
start_time = time.time()
while time.time() - start_time < timeout:
try:
response = requests.get(f"{base_url}/ready")
if response.status_code == 200:
break
except requests.RequestException as e:
# Print the exception for debugging purposes
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait."
)
time.sleep(5)
else:
print(
f"\n[{params['branding']}Startup] Startup timed out. Full help available here \033[92mhttps://github.com/erew123/alltalk_tts#-help-with-problems\033[0m"
)
print(
f"[{params['branding']}Startup] On older system you may wish to open and edit \033[94mscript.py\033[0m with a text editor and changing the"
)
print(
f"[{params['branding']}Startup] \033[94mstartup_wait_time = 120\033[0m setting to something like \033[94mstartup_wait_time = 240\033[0m as this will allow"
)
print(
f"[{params['branding']}Startup] AllTalk more time to try load the model into your VRAM. Otherise please visit the Github for"
)
print(
f"[{params['branding']}Startup] a list of other possible troubleshooting options."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1)
#####################################
#### MODEL LOADING AND UNLOADING ####
#####################################
# MODEL - Swap model based on Gradio selection API TTS, API Local, XTTSv2 Local
def send_reload_request(tts_method):
global tts_method_xtts_ft
try:
params["tts_model_loaded"] = False
url = f"{base_url}/api/reload"
@@ -293,18 +347,27 @@ def send_reload_request(tts_method):
params["tts_method_xtts_local"] = False
params["tts_method_api_tts"] = True
params["deepspeed_activate"] = False
audio_path = this_dir / "templates" / "apitts.wav"
audio_path = this_dir / "system" / "at_sounds" / "apitts.wav"
tts_method_xtts_ft = False
elif tts_method == "API Local":
params["tts_method_api_tts"] = False
params["tts_method_xtts_local"] = False
params["tts_method_api_local"] = True
params["deepspeed_activate"] = False
audio_path = this_dir / "templates" / "apilocal.wav"
audio_path = this_dir / "system" / "at_sounds" / "apilocal.wav"
tts_method_xtts_ft = False
elif tts_method == "XTTSv2 Local":
params["tts_method_api_tts"] = False
params["tts_method_api_local"] = False
params["tts_method_xtts_local"] = True
audio_path = this_dir / "templates" / "xttslocal.wav"
audio_path = this_dir / "system" / "at_sounds" / "xttslocal.wav"
tts_method_xtts_ft = False
elif tts_method == "XTTSv2 FT":
params["tts_method_api_tts"] = False
params["tts_method_api_local"] = False
params["tts_method_xtts_local"] = False
audio_path = this_dir / "system" / "at_sounds" / "xttsfinetuned.wav"
tts_method_xtts_ft = True
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
except requests.exceptions.RequestException as e:
# Handle the HTTP request error
@@ -313,6 +376,7 @@ def send_reload_request(tts_method):
)
return {"status": "error", "message": str(e)}
##################
#### LOW VRAM ####
##################
@@ -321,9 +385,9 @@ def send_lowvram_request(low_vram):
try:
params["tts_model_loaded"] = False
if low_vram:
audio_path = this_dir / "templates" / "lowvramenabled.wav"
audio_path = this_dir / "system" / "at_sounds" / "lowvramenabled.wav"
else:
audio_path = this_dir / "templates" / "lowvramdisabled.wav"
audio_path = this_dir / "system" / "at_sounds" / "lowvramdisabled.wav"
url = f"{base_url}/api/lowvramsetting?new_low_vram_value={low_vram}"
headers = {"Content-Type": "application/json"}
response = requests.post(url, headers=headers)
@@ -350,10 +414,10 @@ def send_deepspeed_request(deepspeed_param):
try:
params["tts_model_loaded"] = False
if deepspeed_param:
audio_path = this_dir / "templates" / "deepspeedenabled.wav"
audio_path = this_dir / "system" / "at_sounds" / "deepspeedenabled.wav"
else:
audio_path = this_dir / "templates" / "deepspeeddisabled.wav"
audio_path = this_dir / "system" / "at_sounds" / "deepspeeddisabled.wav"
url = f"{base_url}/api/deepspeed?new_deepspeed_value={deepspeed_param}"
headers = {"Content-Type": "application/json"}
response = requests.post(url, headers=headers)
@@ -427,9 +491,13 @@ def combine(audio_files, output_folder, state):
# Save the combined audio to a file with a specified sample rate
if "character_menu" in state:
output_file_path = os.path.join(output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav')
output_file_path = os.path.join(
output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav'
)
else:
output_file_path = os.path.join(output_folder, f'TTSOUT_{int(time.time())}_combined.wav')
output_file_path = os.path.join(
output_folder, f"TTSOUT_{int(time.time())}_combined.wav"
)
sf.write(output_file_path, audio, samplerate=sample_rate)
# Clean up unnecessary files
for audio_file in audio_files:
@@ -443,7 +511,7 @@ def combine(audio_files, output_folder, state):
################################
# PREVIEW VOICE - Generate Random Sentence if Voice Preview box is empty
def random_sentence():
with open(this_dir / "harvard_sentences.txt") as f:
with open(this_dir / "system" / "config" / "harvard_sentences.txt") as f:
return random.choice(list(f))
@@ -460,12 +528,19 @@ def voice_preview(string):
output_file = Path(params["output_folder_wav"]) / "voice_preview.wav"
# Generate the audio
language_code = languages.get(params["language"])
temperature = params["local_temperature"]
repetition_penalty = params["local_repetition_penalty"]
# Convert the WindowsPath object to a string before using it in JSON payload
output_file_str = output_file.as_posix()
# Lock before making the generate request
with process_lock:
generate_response = send_generate_request(
string, params["voice"], language_code, output_file_str
string,
params["voice"],
language_code,
temperature,
repetition_penalty,
output_file_str,
)
# Check if lock is already acquired
if process_lock.locked():
@@ -482,6 +557,83 @@ def voice_preview(string):
return f"[{params['branding']}Server] Audio generation failed. Status: {generate_response.get('status')}"
#######################
#### TEXT CLEANING ####
#######################
def process_text(text):
# Normalize HTML encoded quotes
text = html.unescape(text)
# Replace ellipsis with a single dot
text = re.sub(r"\.{3,}", ".", text)
# Pattern to identify combined narrator and character speech
combined_pattern = r'(\*[^*"]+\*|"[^"*]+")'
# List to hold parts of speech along with their type
ordered_parts = []
# Track the start of the next segment
start = 0
# Find all matches
for match in re.finditer(combined_pattern, text):
# Add the text before the match, if any, as ambiguous
if start < match.start():
ambiguous_text = text[start : match.start()].strip()
if ambiguous_text:
ordered_parts.append(("ambiguous", ambiguous_text))
# Add the matched part as either narrator or character
matched_text = match.group(0)
if matched_text.startswith("*") and matched_text.endswith("*"):
ordered_parts.append(("narrator", matched_text.strip("*").strip()))
elif matched_text.startswith('"') and matched_text.endswith('"'):
ordered_parts.append(("character", matched_text.strip('"').strip()))
else:
# In case of mixed or improperly formatted parts
if "*" in matched_text:
ordered_parts.append(("narrator", matched_text.strip("*").strip('"')))
else:
ordered_parts.append(("character", matched_text.strip('"').strip("*")))
# Update the start of the next segment
start = match.end()
# Add any remaining text after the last match as ambiguous
if start < len(text):
ambiguous_text = text[start:].strip()
if ambiguous_text:
ordered_parts.append(("ambiguous", ambiguous_text))
return ordered_parts
########################
#### IMAGE CLEANING ####
########################
img_pattern = r'<img[^>]*src\s*=\s*["\'][^"\'>]+["\'][^>]*>'
def extract_and_remove_images(text):
"""
Extracts all image data from the text and removes it for clean TTS processing.
Returns the cleaned text and the extracted image data.
"""
img_matches = re.findall(img_pattern, text)
img_info = "\n".join(img_matches) # Store extracted image data
cleaned_text = re.sub(img_pattern, '', text) # Remove images from text
return cleaned_text, img_info
def reinsert_images(text, img_info):
"""
Reinserts the previously extracted image data back into the text.
"""
if img_info: # Check if there are images to reinsert
text += f"\n\n{img_info}"
return text
#################################
#### TTS STANDARD GENERATION ####
#################################
@@ -489,105 +641,104 @@ def voice_preview(string):
def output_modifier(string, state):
if not params["activate"]:
return string
original_string = string
cleaned_string = before_audio_generation(string, params)
img_info = ""
cleaned_text, img_info = extract_and_remove_images(string)
# print("Cleaned STRING IS:", cleaned_text)
cleaned_string = before_audio_generation(cleaned_text, params)
if cleaned_string is None:
return
string = cleaned_string
language_code = languages.get(params["language"])
temperature = params["local_temperature"]
repetition_penalty = params["local_repetition_penalty"]
# Create a list to store generated audio paths
audio_files = []
if process_lock.acquire(blocking=False):
try:
if params["narrator_enabled"]:
# print(original_string)
# Do Some basic stripping and remove any double CR's
processed_string = (
original_string
.replace("***", "*")
.replace("**", "*")
.replace("\n\n", "\n")
)
# Clean up two asterisks (narrators) being made between a newline, making it one sentence.
processed_string = re.sub(r'\.\*\n\*', '. ', processed_string)
# Clean up a few other bits.
processed_string = (
processed_string
.replace("&#x27;", "'")
.replace("\n", " ")
# Add special characters to the quote so that we can use it to identify things later after its been split
.replace('&quot;', '&quot;<')
# Capture new conversations which wont have things like &quote in them
.replace('"', '&quot;<')
)
#capturing another outlier in inital character paragraph
# print("processed string 1 is:", processed_string)
processed_string = processed_string.replace('&quot;<. *', '&quot;< *"')
processed_string = processed_string.replace('< *"', '< *')
processed_string = processed_string.replace('. *', '< *')
# print("processed string 2 is:", processed_string)
# Set up a tracking of the individual wav files.
processed_parts = process_text(cleaned_string)
audio_files_all_paragraphs = []
# Split the line using &quot; and ".* " (so end of sentences, leaving special characters added to the start of all OTHER sentences, bar possibly the first one if its starting with a *
parts = re.split(r'&quot;|\.\*', processed_string)
audio_files_paragraph = []
for i, part in enumerate(parts):
for part_type, part in processed_parts:
# Skip parts that are too short
if len(part.strip()) <= 1:
if len(part.strip()) <= 3:
continue
# Figure out which type of line it is, then replace characters as necessary to avoid TTS trying to pronunce them, htmlunescape after.
# Character will always be a < with a letter immediately after it
if '<' in part and '< *' not in part and '<*' not in part and '< *' not in part and '< ' not in part and '< ' not in part:
cleaned_part = html.unescape(part.replace('<', ''))
voice_to_use = params["voice"]
#Narrator will always be an * or < with an * a position or two after it.
elif '<*' in part or '< *' in part or '< *' in part or '*' in part:
cleaned_part = html.unescape(part.replace('<*', '').replace('< *', '').replace('< *', '').replace('*', ''))
# Determine the voice to use based on the part type
if part_type == "narrator":
voice_to_use = params["narrator_voice"]
#If the other two dont capture it, aka, the AI gave no * or &quot; on the line, use non_quoted_text_is aka user interface, user can choose Char or Narrator
elif non_quoted_text_is:
cleaned_part = html.unescape(part.replace('< ', '').replace('< ', '').replace('< ', ''))
print(
f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m"
) # Green
elif part_type == "character":
voice_to_use = params["voice"]
print(
f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m"
) # Yellow
else:
cleaned_part = html.unescape(part.replace('< ', '').replace('< ', '').replace('< ', ''))
voice_to_use = params["narrator_voice"]
# Check if character name exists and if not, just call it TTSOUT_
if "character_menu" in state:
output_file = Path(f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}_{i}.wav')
else:
output_file = Path(f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}_{i}.wav')
# Generate that TTS and output to a file
output_file_str = output_file.as_posix()
# Handle ambiguous parts based on user preference
voice_to_use = (
params["voice"]
if non_quoted_text_is
else params["narrator_voice"]
)
voice_description = (
"\033[36mCharacter (Text-not-inside)\033[0m"
if non_quoted_text_is
else "\033[92mNarrator (Text-not-inside)\033[0m"
)
print(f"[{params['branding']}TTSGen] {voice_description}")
# Replace multiple exclamation marks, question marks, or other punctuation with a single instance
cleaned_part = re.sub(r"([!?.])\1+", r"\1", part)
# Further clean to remove any other unwanted characters
cleaned_part = re.sub(r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0100-\u017F\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\u4E00-\u9FFF\u3400-\u4DBF\u20000-\u2A6DF\u3000-\u303F\$]', '', cleaned_part)
# Remove all newline characters (single or multiple)
cleaned_part = re.sub(r"\n+", " ", cleaned_part)
# Generate TTS and output to a file
output_filename = get_output_filename(state)
generate_response = send_generate_request(
cleaned_part, voice_to_use, language_code, output_file_str
cleaned_part,
voice_to_use,
language_code,
temperature,
repetition_penalty,
output_filename,
)
audio_path = generate_response.get("data", {}).get("audio_path")
audio_files_paragraph.append(audio_path)
# Accumulate audio files within the paragraph
audio_files_all_paragraphs.extend(audio_files_paragraph)
audio_files_all_paragraphs.append(audio_path)
# Combine audio files across paragraphs
final_output_file = combine(
audio_files_all_paragraphs, params["output_folder_wav"], state
)
else:
processed_string = (
original_string
.replace("***", "")
.replace("**", "")
.replace("*", "")
.replace("\n\n", "\n")
.replace("&#x27;", "'")
)
cleaned_part = html.unescape(processed_string)
# Decode HTML entities first
cleaned_part = html.unescape(cleaned_string)
# Replace multiple instances of certain punctuation marks with a single instance
cleaned_part = re.sub(r"([!?.])\1+", r"\1", cleaned_part)
# Further clean to remove any other unwanted characters
cleaned_part = re.sub(r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0100-\u017F\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\u4E00-\u9FFF\u3400-\u4DBF\u20000-\u2A6DF\u3000-\u303F\$]', '', cleaned_part)
# Remove all newline characters (single or multiple)
cleaned_part = re.sub(r"\n+", " ", cleaned_part)
# Process the part and give it a non-character name if being used vai API or standalone.
if "character_menu" in state:
output_file = Path(f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}.wav')
output_file = Path(
f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}.wav'
)
else:
output_file = Path(f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}.wav')
output_file = Path(
f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}.wav'
)
output_file_str = output_file.as_posix()
output_file = get_output_filename(state)
generate_response = send_generate_request(
cleaned_part, params["voice"], language_code, output_file_str
cleaned_part,
params["voice"],
language_code,
temperature,
repetition_penalty,
output_file_str,
)
audio_path = generate_response.get("data", {}).get("audio_path")
final_output_file = audio_path
@@ -606,41 +757,40 @@ def output_modifier(string, state):
if audio_path:
# Handle Gradio and playback
autoplay = "autoplay" if params["autoplay"] else ""
string = (
f'<audio src="file/{final_output_file}" controls {autoplay}></audio>'
)
string = (f'<audio src="file/{final_output_file}" controls {autoplay}></audio>')
if params["show_text"]:
string += f"\n\n{original_string}"
string += reinsert_images(cleaned_string, img_info)
shared.processing_message = "*Is typing...*"
return string
else:
print(
f"[{params['branding']}Server] \033[91mWarning\033[0m No audio path in the response."
)
print(f"[{params['branding']}Server] \033[91mWarning\033[0m No audio path in the response.")
else:
print(
f"[{params['branding']}Server] \033[91mWarning\033[0m Audio generation failed. Status:",
generate_response.get("message"),
)
print(f"[{params['branding']}Server] \033[91mWarning\033[0m Audio generation failed. Status:", generate_response.get("message"),)
def get_output_filename(state):
return Path(
f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav'
).as_posix()
if "character_menu" in state:
return Path(
f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav'
).as_posix()
else:
return Path(
f'{params["output_folder_wav"]}/TTSOUT_{str(uuid.uuid4())[:8]}.wav'
).as_posix()
###############################################
#### SEND GENERATION REQUEST TO TTS ENGINE ####
###############################################
def send_generate_request(text, voice, language, output_file):
def send_generate_request(
text, voice, language, temperature, repetition_penalty, output_file
):
url = f"{base_url}/api/generate"
payload = {
"text": text,
"voice": voice,
"language": language,
"temperature": temperature,
"repetition_penalty": repetition_penalty,
"output_file": output_file,
}
headers = {"Content-Type": "application/json"}
@@ -665,12 +815,14 @@ def state_modifier(state):
state["stream"] = False
return state
def update_narrator_enabled(value):
if value == "Enabled":
params["narrator_enabled"] = True
elif value == "Disabled":
params["narrator_enabled"] = False
def update_non_quoted_text_is(value):
global non_quoted_text_is
if value == "Narrator":
@@ -678,6 +830,7 @@ def update_non_quoted_text_is(value):
elif value == "Char":
non_quoted_text_is = True
def input_modifier(string, state):
if not params["activate"]:
return string
@@ -685,42 +838,56 @@ def input_modifier(string, state):
shared.processing_message = "*Is recording a voice message...*"
return string
def custom_css():
path_to_css = Path(f"{this_dir}/style.css")
return open(path_to_css, "r").read()
def ui():
with gr.Accordion(params["branding"] + " TTS (XTTSv2)"):
# Activate alltalk_tts, Enable autoplay, Show text
with gr.Row():
activate = gr.Checkbox(value=params["activate"], label="Activate TTS")
autoplay = gr.Checkbox(
value=params["autoplay"], label="Play TTS automatically"
)
activate = gr.Checkbox(value=params["activate"], label="Enable TTS")
autoplay = gr.Checkbox(value=params["autoplay"], label="Autoplay TTS")
show_text = gr.Checkbox(value=params["show_text"], label="Show Text")
# Low vram enable, Deepspeed enable, Remove trailing dots
with gr.Row():
show_text = gr.Checkbox(
value=params["show_text"], label="Show message text under audio player"
low_vram = gr.Checkbox(
value=params["low_vram"], label="Enable Low VRAM Mode"
)
low_vram_play = gr.HTML(visible=False)
deepspeed_checkbox = gr.Checkbox(
value=params["deepspeed_activate"],
label="Enable DeepSpeed",
visible=deepspeed_installed,
)
deepspeed_checkbox_play = gr.HTML(visible=False)
remove_trailing_dots = gr.Checkbox(
value=params["remove_trailing_dots"],
label='Remove trailing "." from text segments before generation',
value=params["remove_trailing_dots"], label='Remove trailing "."'
)
# TTS method, Character voice selection
with gr.Row():
model_loader_choices = ["API TTS", "API Local", "XTTSv2 Local"]
if finetuned_model:
model_loader_choices.append("XTTSv2 FT")
tts_radio_buttons = gr.Radio(
choices=model_loader_choices,
label="TTS Method (Each method sounds slightly different)",
value=gr_modelchoice, # Set the default value
)
tts_radio_buttons_play = gr.HTML(visible=False)
with gr.Row():
available_voices = get_available_voices()
default_voice = params["voice"]
# Check if the default voice is in the list of available voices
default_voice = params[
"voice"
] # Check if the default voice is in the list of available voices
if default_voice not in available_voices:
# Handle the case where the default voice is not in the list (choose a default value or update it)
default_voice = available_voices[
0
] # Choose the first available voice as the default
# Add allow_custom_value=True to the Dropdown
voice = gr.Dropdown(
available_voices,
label="Default Voice",
label="Character Voice",
value=default_voice,
allow_custom_value=True,
)
@@ -734,14 +901,11 @@ def ui():
"refresh-button",
)
language = gr.Dropdown(
languages.keys(),
label="Language",
allow_custom_value=True,
value=params["language"],
)
# Language, Narrator voice
with gr.Row():
language = gr.Dropdown(
languages.keys(), label="Language", value=params["language"]
)
with gr.Row():
narrator_voice_gr = gr.Dropdown(
get_available_voices(),
@@ -758,40 +922,42 @@ def ui():
},
"refresh-button",
)
# Temperature, Repetition Penalty
with gr.Row():
local_temperature_gr = gr.Slider(
minimum=0.05,
maximum=1,
step=0.05,
label="Temperature",
value=params["local_temperature"],
)
local_repetition_penalty_gr = gr.Slider(
minimum=0.5,
maximum=20,
step=0.5,
label="Repetition Penalty",
value=params["local_repetition_penalty"],
)
# Narrator enable, Non quoted text, Explanation text
with gr.Row():
with gr.Row():
narrator_enabled_gr = gr.Radio(
choices={"Enabled": "true", "Disabled": "false"},
label="Narrator Activation",
label="Narrator",
value="Enabled" if params.get("narrator_enabled") else "Disabled",
)
non_quoted_text_is_gr = gr.Radio(
choices={"Char": "true", "Narrator": "false"},
label='Text NOT inside of * or " is',
value="Char" if non_quoted_text_is else "Narrator",
choices={"Character": "true", "Narrator": "false"},
label='Unmarked text NOT inside of * or " is',
value="Character" if non_quoted_text_is else "Narrator",
)
explanation_text = gr.HTML(
f"<p>⚙️ <a href='http://{params['ip_address']}:{params['port_number']}'>Settings and Documentation Page</a><a href='http://{params['ip_address']}:{params['port_number']}'></a>⚙️<br>- Low VRAM Mode and Deepspeed take 15 seconds to be enabled or disabled.<br>- The DeepSpeed checkbox is only visible if DeepSpeed is present.</p>"
)
with gr.Row():
low_vram = gr.Checkbox(
value=params["low_vram"], label="Low VRAM mode (Read NOTE)"
)
low_vram_play = gr.HTML(visible=False)
deepspeed_checkbox = gr.Checkbox(
value=params["deepspeed_activate"],
label="Activate DeepSpeed (Read NOTE)",
visible=deepspeed_installed,
)
deepspeed_checkbox_play = gr.HTML(visible=False)
with gr.Row():
tts_radio_buttons = gr.Radio(
choices=["API TTS", "API Local", "XTTSv2 Local"],
label="Select TTS Generation Method (Read NOTE)",
value=gr_modelchoice, # Set the default value
)
tts_radio_buttons_play = gr.HTML(visible=False)
explanation_text = gr.HTML(
f"<p>NOTE: Switching Model Type, Low VRAM & DeepSpeed, each takes 15 seconds. Each TTS generation method has a slightly different sound. DeepSpeed checkbox is only visible if DeepSpeed is present. Readme & Settings: <a href='http://{params['ip_address']}:{params['port_number']}'>http://{params['ip_address']}:{params['port_number']}</a>"
)
# Preview speech
with gr.Row():
preview_text = gr.Text(
show_label=False,
@@ -861,18 +1027,34 @@ def ui():
autoplay.change(lambda x: params.update({"autoplay": x}), autoplay, None)
low_vram.change(lambda x: params.update({"low_vram": x}), low_vram, None)
low_vram.change(lambda x: send_lowvram_request(x), low_vram, low_vram_play, None)
tts_radio_buttons.change(send_reload_request, tts_radio_buttons, tts_radio_buttons_play, None)
deepspeed_checkbox.change(send_deepspeed_request, deepspeed_checkbox, deepspeed_checkbox_play, None)
tts_radio_buttons.change(
send_reload_request, tts_radio_buttons, tts_radio_buttons_play, None
)
deepspeed_checkbox.change(
send_deepspeed_request, deepspeed_checkbox, deepspeed_checkbox_play, None
)
remove_trailing_dots.change(
lambda x: params.update({"remove_trailing_dots": x}), remove_trailing_dots, None
)
voice.change(lambda x: params.update({"voice": x}), voice, None)
language.change(lambda x: params.update({"language": x}), language, None)
# TSS Settings
local_temperature_gr.change(
lambda x: params.update({"local_temperature": x}), local_temperature_gr, None
)
local_repetition_penalty_gr.change(
lambda x: params.update({"local_repetition_penalty": x}),
local_repetition_penalty_gr,
None,
)
# Narrator selection actions
narrator_enabled_gr.change(update_narrator_enabled, narrator_enabled_gr, None)
non_quoted_text_is_gr.change(update_non_quoted_text_is, non_quoted_text_is_gr, None)
narrator_voice_gr.change(lambda x: params.update({"narrator_voice": x}), narrator_voice_gr, None)
narrator_voice_gr.change(
lambda x: params.update({"narrator_voice": x}), narrator_voice_gr, None
)
# Play preview
preview_text.submit(voice_preview, preview_text, preview_audio)
@@ -888,4 +1070,4 @@ if running_in_standalone:
try:
time.sleep(1) # Add a small delay to avoid high CPU usage
except KeyboardInterrupt:
break # Allow graceful exit on Ctrl+C
break # Allow graceful exit on Ctrl+C
-8
View File
@@ -1,8 +0,0 @@
.SDAP .hires_opts input[type="number"] {
width: 6em !important;
}
/* silero_tts preview */
.form:has(> #silero_preview_text) {
min-width: 75%
}
+2614
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -89,25 +89,25 @@
<h3>AllTalk Startup Settings</h3><br>
<form action="/update-settings" method="post">
<label for="activate" style="color: #33cc33;">Activate TTS:</label>
<label for="activate" style="color: #b273fa;">TG-webui Activate TTS:</label>
<select id="activate" name="activate" required="">
<option {% if data.activate %}selected{% endif %} value="true">True</option>
<option {% if not data.activate %}selected{% endif %} value="false">False</option>
</select>
<label for="autoplay" style="color: #33cc33;">&nbsp; &nbsp; Autoplay TTS output:</label>
<label for="autoplay" style="color: #b273fa;">&nbsp; &nbsp; TG-webui Autoplay TTS:</label>
<select id="autoplay" name="autoplay" required="">
<option {% if data.autoplay %}selected{% endif %} value="true">True</option>
<option {% if not data.autoplay %}selected{% endif %} value="false">False</option>
</select>
<label for="show_text" style="color: #33cc33;"> Show Text on generation:</label>
<label for="show_text" style="color: #b273fa;">TG-webui Show Text:</label>
<select id="show_text" name="show_text" required="">
<option {% if data.show_text %}selected{% endif %} value="true">True</option>
<option {% if not data.show_text %}selected{% endif %} value="false">False</option>
</select>
<label for="voice" style="color: #33cc33;">&nbsp; &nbsp; Default voice:</label>
<label for="voice" style="color: #b273fa;">&nbsp; &nbsp; TG-webui Default voice:</label>
<select id="voice" name="voice" required="">
{% for file in wav_files %}
<option value="{{ file }}" {% if data.voice==file %}selected{% endif %}>{{ file }}</option>
@@ -115,7 +115,7 @@
</select>
<label for="language" style="color: #33cc33;">Default Language:</label>
<label for="language" style="color: #b273fa;">TG-webui Default Language:</label>
<select id="language" name="language" required="">
<option value="Arabic" {% if data.language=='Arabic' %}selected{% endif %}>Arabic</option>
<option value="Chinese" {% if data.language=='Chinese' %}selected{% endif %}>Chinese</option>
@@ -135,20 +135,20 @@
<option value="Turkish" {% if data.language=='Turkish' %}selected{% endif %}>Turkish</option>
</select>
<label for="narrator_voice" style="color: #33cc33;">&nbsp; &nbsp; Narrator voice:</label>
<label for="narrator_voice" style="color: #b273fa;">&nbsp; &nbsp; TG-webui Narrator voice:</label>
<select id="narrator_voice" name="narrator_voice" required="">
{% for file in wav_files %}
<option value="{{ file }}" {% if data.narrator_voice==file %}selected{% endif %}>{{ file }}</option>
{% endfor %}
</select>
<label for="remove_trailing_dots" style="color: #33cc33;"> Remove Trailing Dots:</label>
<label for="remove_trailing_dots" style="color: #b273fa;">TG-webui Remove Trailing Dots:</label>
<select id="remove_trailing_dots" name="remove_trailing_dots" required="">
<option {% if data.remove_trailing_dots %}selected{% endif %} value="true">True</option>
<option {% if not data.remove_trailing_dots %}selected{% endif %} value="false">False</option>
</select>
<label for="narrator_enabled" style="color: #33cc33;">&nbsp; &nbsp; Narrator enabled:</label>
<label for="narrator_enabled" style="color: #b273fa;">&nbsp; &nbsp; TG-webui Narrator enabled:</label>
<select id="narrator_enabled" name="narrator_enabled" required="">
<option {% if data.narrator_enabled %}selected{% endif %} value="true">True</option>
<option {% if not data.narrator_enabled %}selected{% endif %} value="false">False</option>
Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 476 KiB

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 156 KiB

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+869
View File
@@ -0,0 +1,869 @@
import os
import re
import textwrap
from functools import cached_property
import pypinyin
import torch
from hangul_romanize import Transliter
from hangul_romanize.rule import academic
from num2words import num2words
from spacy.lang.ar import Arabic
from spacy.lang.en import English
from spacy.lang.es import Spanish
from spacy.lang.ja import Japanese
from spacy.lang.zh import Chinese
from tokenizers import Tokenizer
from TTS.tts.layers.xtts.zh_num2words import TextNorm as zh_num2words
def get_spacy_lang(lang):
if lang == "zh":
return Chinese()
elif lang == "ja":
return Japanese()
elif lang == "ar":
return Arabic()
elif lang == "es":
return Spanish()
else:
# For most languages, Enlish does the job
return English()
def split_sentence(text, lang, text_split_length=250):
"""Preprocess the input text"""
text_splits = []
if text_split_length is not None and len(text) >= text_split_length:
text_splits.append("")
nlp = get_spacy_lang(lang)
nlp.add_pipe("sentencizer")
doc = nlp(text)
for sentence in doc.sents:
if len(text_splits[-1]) + len(str(sentence)) <= text_split_length:
# if the last sentence + the current sentence is less than the text_split_length
# then add the current sentence to the last sentence
text_splits[-1] += " " + str(sentence)
text_splits[-1] = text_splits[-1].lstrip()
elif len(str(sentence)) > text_split_length:
# if the current sentence is greater than the text_split_length
for line in textwrap.wrap(
str(sentence),
width=text_split_length,
drop_whitespace=True,
break_on_hyphens=False,
tabsize=1,
):
text_splits.append(str(line))
else:
text_splits.append(str(sentence))
if len(text_splits) > 1:
if text_splits[0] == "":
del text_splits[0]
else:
text_splits = [text.lstrip()]
return text_splits
_whitespace_re = re.compile(r"\s+")
# List of (regular expression, replacement) pairs for abbreviations:
_abbreviations = {
"en": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("mrs", "misess"),
("mr", "mister"),
("dr", "doctor"),
("st", "saint"),
("co", "company"),
("jr", "junior"),
("maj", "major"),
("gen", "general"),
("drs", "doctors"),
("rev", "reverend"),
("lt", "lieutenant"),
("hon", "honorable"),
("sgt", "sergeant"),
("capt", "captain"),
("esq", "esquire"),
("ltd", "limited"),
("col", "colonel"),
("ft", "fort"),
]
],
"es": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("sra", "señora"),
("sr", "señor"),
("dr", "doctor"),
("dra", "doctora"),
("st", "santo"),
("co", "compañía"),
("jr", "junior"),
("ltd", "limitada"),
]
],
"fr": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("mme", "madame"),
("mr", "monsieur"),
("dr", "docteur"),
("st", "saint"),
("co", "compagnie"),
("jr", "junior"),
("ltd", "limitée"),
]
],
"de": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("fr", "frau"),
("dr", "doktor"),
("st", "sankt"),
("co", "firma"),
("jr", "junior"),
]
],
"pt": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("sra", "senhora"),
("sr", "senhor"),
("dr", "doutor"),
("dra", "doutora"),
("st", "santo"),
("co", "companhia"),
("jr", "júnior"),
("ltd", "limitada"),
]
],
"it": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
# ("sig.ra", "signora"),
("sig", "signore"),
("dr", "dottore"),
("st", "santo"),
("co", "compagnia"),
("jr", "junior"),
("ltd", "limitata"),
]
],
"pl": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("p", "pani"),
("m", "pan"),
("dr", "doktor"),
("sw", "święty"),
("jr", "junior"),
]
],
"ar": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
# There are not many common abbreviations in Arabic as in English.
]
],
"zh": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
# Chinese doesn't typically use abbreviations in the same way as Latin-based scripts.
]
],
"cs": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("dr", "doktor"), # doctor
("ing", "inženýr"), # engineer
("p", "pan"), # Could also map to pani for woman but no easy way to do it
# Other abbreviations would be specialized and not as common.
]
],
"ru": [
(re.compile("\\b%s\\b" % x[0], re.IGNORECASE), x[1])
for x in [
("г-жа", "госпожа"), # Mrs.
("г-н", "господин"), # Mr.
("д-р", "доктор"), # doctor
# Other abbreviations are less common or specialized.
]
],
"nl": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("dhr", "de heer"), # Mr.
("mevr", "mevrouw"), # Mrs.
("dr", "dokter"), # doctor
("jhr", "jonkheer"), # young lord or nobleman
# Dutch uses more abbreviations, but these are the most common ones.
]
],
"tr": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("b", "bay"), # Mr.
("byk", "büyük"), # büyük
("dr", "doktor"), # doctor
# Add other Turkish abbreviations here if needed.
]
],
"hu": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
("dr", "doktor"), # doctor
("b", "bácsi"), # Mr.
("nőv", "nővér"), # nurse
# Add other Hungarian abbreviations here if needed.
]
],
"ko": [
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
for x in [
# Korean doesn't typically use abbreviations in the same way as Latin-based scripts.
]
],
"ja": [
(re.compile("\\b%s\\b" % x[0]), x[1])
for x in [
("氏", "さん"), # Mr.
("夫人", "おんなのひと"), # Mrs.
("博士", "はかせ"), # Doctor or PhD
("株", "株式会社"), # Corporation
("有", "有限会社"), # Limited company
("大学", "だいがく"), # University
("先生", "せんせい"), # Teacher/Professor/Master
("君", "くん") # Used at the end of boys' names to express familiarity or affection.
]
],
}
def expand_abbreviations_multilingual(text, lang="en"):
for regex, replacement in _abbreviations[lang]:
text = re.sub(regex, replacement, text)
return text
_symbols_multilingual = {
"en": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " and "),
("@", " at "),
("%", " percent "),
("#", " hash "),
("$", " dollar "),
("£", " pound "),
("°", " degree "),
]
],
"es": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " y "),
("@", " arroba "),
("%", " por ciento "),
("#", " numeral "),
("$", " dolar "),
("£", " libra "),
("°", " grados "),
]
],
"fr": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " et "),
("@", " arobase "),
("%", " pour cent "),
("#", " dièse "),
("$", " dollar "),
("£", " livre "),
("°", " degrés "),
]
],
"de": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " und "),
("@", " at "),
("%", " prozent "),
("#", " raute "),
("$", " dollar "),
("£", " pfund "),
("°", " grad "),
]
],
"pt": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " e "),
("@", " arroba "),
("%", " por cento "),
("#", " cardinal "),
("$", " dólar "),
("£", " libra "),
("°", " graus "),
]
],
"it": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " e "),
("@", " chiocciola "),
("%", " per cento "),
("#", " cancelletto "),
("$", " dollaro "),
("£", " sterlina "),
("°", " gradi "),
]
],
"pl": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " i "),
("@", " małpa "),
("%", " procent "),
("#", " krzyżyk "),
("$", " dolar "),
("£", " funt "),
("°", " stopnie "),
]
],
"ar": [
# Arabic
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " و "),
("@", " على "),
("%", " في المئة "),
("#", " رقم "),
("$", " دولار "),
("£", " جنيه "),
("°", " درجة "),
]
],
"zh": [
# Chinese
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " 和 "),
("@", " 在 "),
("%", " 百分之 "),
("#", " 号 "),
("$", " 美元 "),
("£", " 英镑 "),
("°", " 度 "),
]
],
"cs": [
# Czech
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " a "),
("@", " na "),
("%", " procento "),
("#", " křížek "),
("$", " dolar "),
("£", " libra "),
("°", " stupně "),
]
],
"ru": [
# Russian
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " и "),
("@", " собака "),
("%", " процентов "),
("#", " номер "),
("$", " доллар "),
("£", " фунт "),
("°", " градус "),
]
],
"nl": [
# Dutch
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " en "),
("@", " bij "),
("%", " procent "),
("#", " hekje "),
("$", " dollar "),
("£", " pond "),
("°", " graden "),
]
],
"tr": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " ve "),
("@", " at "),
("%", " yüzde "),
("#", " diyez "),
("$", " dolar "),
("£", " sterlin "),
("°", " derece "),
]
],
"hu": [
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " és "),
("@", " kukac "),
("%", " százalék "),
("#", " kettőskereszt "),
("$", " dollár "),
("£", " font "),
("°", " fok "),
]
],
"ko": [
# Korean
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
for x in [
("&", " 그리고 "),
("@", " 에 "),
("%", " 퍼센트 "),
("#", " 번호 "),
("$", " 달러 "),
("£", " 파운드 "),
("°", " 도 "),
]
],
"ja": [
(re.compile(r"%s" % re.escape(x[0])), x[1])
for x in [
("&", " と "),
("@", " アットマーク "),
("%", " パーセント "),
("#", " ナンバー "),
("$", " ドル "),
("£", " ポンド "),
("°", " 度"),
]
],
}
def expand_symbols_multilingual(text, lang="en"):
for regex, replacement in _symbols_multilingual[lang]:
text = re.sub(regex, replacement, text)
text = text.replace(" ", " ") # Ensure there are no double spaces
return text.strip()
_ordinal_re = {
"en": re.compile(r"([0-9]+)(st|nd|rd|th)"),
"es": re.compile(r"([0-9]+)(º|ª|er|o|a|os|as)"),
"fr": re.compile(r"([0-9]+)(º|ª|er|re|e|ème)"),
"de": re.compile(r"([0-9]+)(st|nd|rd|th|º|ª|\.(?=\s|$))"),
"pt": re.compile(r"([0-9]+)(º|ª|o|a|os|as)"),
"it": re.compile(r"([0-9]+)(º|°|ª|o|a|i|e)"),
"pl": re.compile(r"([0-9]+)(º|ª|st|nd|rd|th)"),
"ar": re.compile(r"([0-9]+)(ون|ين|ث|ر|ى)"),
"cs": re.compile(r"([0-9]+)\.(?=\s|$)"), # In Czech, a dot is often used after the number to indicate ordinals.
"ru": re.compile(r"([0-9]+)(-й|-я|-е|-ое|-ье|-го)"),
"nl": re.compile(r"([0-9]+)(de|ste|e)"),
"tr": re.compile(r"([0-9]+)(\.|inci|nci|uncu|üncü|\.)"),
"hu": re.compile(r"([0-9]+)(\.|adik|edik|odik|edik|ödik|ödike|ik)"),
"ko": re.compile(r"([0-9]+)(번째|번|차|째)"),
"ja": re.compile(r"([0-9]+)(番|回|つ|目|等|位)")
}
_number_re = re.compile(r"[0-9]+")
_currency_re = {
"USD": re.compile(r"((\$[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+\$))"),
"GBP": re.compile(r"((£[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+£))"),
"EUR": re.compile(r"(([0-9\.\,]*[0-9]+€)|((€[0-9\.\,]*[0-9]+)))"),
}
_comma_number_re = re.compile(r"\b\d{1,3}(,\d{3})*(\.\d+)?\b")
_dot_number_re = re.compile(r"\b\d{1,3}(.\d{3})*(\,\d+)?\b")
_decimal_number_re = re.compile(r"([0-9]+[.,][0-9]+)")
def _remove_commas(m):
text = m.group(0)
if "," in text:
text = text.replace(",", "")
return text
def _remove_dots(m):
text = m.group(0)
if "." in text:
text = text.replace(".", "")
return text
def _expand_decimal_point(m, lang="en"):
amount = m.group(1).replace(",", ".")
return num2words(float(amount), lang=lang if lang != "cs" else "cz")
def _expand_currency(m, lang="en", currency="USD"):
amount = float((re.sub(r"[^\d.]", "", m.group(0).replace(",", "."))))
full_amount = num2words(amount, to="currency", currency=currency, lang=lang if lang != "cs" else "cz")
and_equivalents = {
"en": ", ",
"es": " con ",
"fr": " et ",
"de": " und ",
"pt": " e ",
"it": " e ",
"pl": ", ",
"cs": ", ",
"ru": ", ",
"nl": ", ",
"ar": ", ",
"tr": ", ",
"hu": ", ",
"ko": ", ",
}
if amount.is_integer():
last_and = full_amount.rfind(and_equivalents[lang])
if last_and != -1:
full_amount = full_amount[:last_and]
return full_amount
def _expand_ordinal(m, lang="en"):
return num2words(int(m.group(1)), ordinal=True, lang=lang if lang != "cs" else "cz")
def _expand_number(m, lang="en"):
return num2words(int(m.group(0)), lang=lang if lang != "cs" else "cz")
def expand_numbers_multilingual(text, lang="en"):
if lang == "zh":
text = zh_num2words()(text)
else:
if lang in ["en", "ru"]:
text = re.sub(_comma_number_re, _remove_commas, text)
else:
text = re.sub(_dot_number_re, _remove_dots, text)
try:
text = re.sub(_currency_re["GBP"], lambda m: _expand_currency(m, lang, "GBP"), text)
text = re.sub(_currency_re["USD"], lambda m: _expand_currency(m, lang, "USD"), text)
text = re.sub(_currency_re["EUR"], lambda m: _expand_currency(m, lang, "EUR"), text)
except:
pass
if lang != "tr":
text = re.sub(_decimal_number_re, lambda m: _expand_decimal_point(m, lang), text)
text = re.sub(_ordinal_re[lang], lambda m: _expand_ordinal(m, lang), text)
text = re.sub(_number_re, lambda m: _expand_number(m, lang), text)
return text
def lowercase(text):
return text.lower()
def collapse_whitespace(text):
return re.sub(_whitespace_re, " ", text)
def multilingual_cleaners(text, lang):
text = text.replace('"', "")
if lang == "tr":
text = text.replace("İ", "i")
text = text.replace("Ö", "ö")
text = text.replace("Ü", "ü")
text = lowercase(text)
text = expand_numbers_multilingual(text, lang)
text = expand_abbreviations_multilingual(text, lang)
text = expand_symbols_multilingual(text, lang=lang)
text = collapse_whitespace(text)
return text
def basic_cleaners(text):
"""Basic pipeline that lowercases and collapses whitespace without transliteration."""
text = lowercase(text)
text = collapse_whitespace(text)
return text
def chinese_transliterate(text):
return "".join(
[p[0] for p in pypinyin.pinyin(text, style=pypinyin.Style.TONE3, heteronym=False, neutral_tone_with_five=True)]
)
def japanese_cleaners(text, katsu):
text = katsu.romaji(text)
text = lowercase(text)
return text
def korean_transliterate(text):
r = Transliter(academic)
return r.translit(text)
DEFAULT_VOCAB_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/tokenizer.json")
class VoiceBpeTokenizer:
def __init__(self, vocab_file=None):
self.tokenizer = None
if vocab_file is not None:
self.tokenizer = Tokenizer.from_file(vocab_file)
self.char_limits = {
"en": 250,
"de": 253,
"fr": 273,
"es": 239,
"it": 213,
"pt": 203,
"pl": 224,
"zh": 82,
"ar": 166,
"cs": 186,
"ru": 182,
"nl": 251,
"tr": 226,
"ja": 71,
"hu": 224,
"ko": 95,
}
@cached_property
def katsu(self):
import cutlet
return cutlet.Cutlet()
def check_input_length(self, txt, lang):
lang = lang.split("-")[0] # remove the region
limit = self.char_limits.get(lang, 250)
if len(txt) > limit:
print(
f"[!] Warning: The text length exceeds the character limit of {limit} for language '{lang}', this might cause truncated audio."
)
def preprocess_text(self, txt, lang):
if lang in {"ar", "cs", "de", "en", "es", "fr", "hu", "it", "nl", "pl", "pt", "ru", "tr", "zh", "ko"}:
txt = multilingual_cleaners(txt, lang)
if lang == "zh":
txt = chinese_transliterate(txt)
if lang == "ko":
txt = korean_transliterate(txt)
elif lang == "ja":
txt = japanese_cleaners(txt, self.katsu)
elif lang == "hi":
# @manmay will implement this
txt = basic_cleaners(txt)
else:
raise NotImplementedError(f"Language '{lang}' is not supported.")
return txt
def encode(self, txt, lang):
lang = lang.split("-")[0] # remove the region
self.check_input_length(txt, lang)
txt = self.preprocess_text(txt, lang)
lang = "zh-cn" if lang == "zh" else lang
txt = f"[{lang}]{txt}"
txt = txt.replace(" ", "[SPACE]")
return self.tokenizer.encode(txt).ids
def decode(self, seq):
if isinstance(seq, torch.Tensor):
seq = seq.cpu().numpy()
txt = self.tokenizer.decode(seq, skip_special_tokens=False).replace(" ", "")
txt = txt.replace("[SPACE]", " ")
txt = txt.replace("[STOP]", "")
txt = txt.replace("[UNK]", "")
return txt
def __len__(self):
return self.tokenizer.get_vocab_size()
def get_number_tokens(self):
return max(self.tokenizer.get_vocab().values()) + 1
def test_expand_numbers_multilingual():
test_cases = [
# English
("In 12.5 seconds.", "In twelve point five seconds.", "en"),
("There were 50 soldiers.", "There were fifty soldiers.", "en"),
("This is a 1st test", "This is a first test", "en"),
("That will be $20 sir.", "That will be twenty dollars sir.", "en"),
("That will be 20€ sir.", "That will be twenty euro sir.", "en"),
("That will be 20.15€ sir.", "That will be twenty euro, fifteen cents sir.", "en"),
("That's 100,000.5.", "That's one hundred thousand point five.", "en"),
# French
("En 12,5 secondes.", "En douze virgule cinq secondes.", "fr"),
("Il y avait 50 soldats.", "Il y avait cinquante soldats.", "fr"),
("Ceci est un 1er test", "Ceci est un premier test", "fr"),
("Cela vous fera $20 monsieur.", "Cela vous fera vingt dollars monsieur.", "fr"),
("Cela vous fera 20€ monsieur.", "Cela vous fera vingt euros monsieur.", "fr"),
("Cela vous fera 20,15€ monsieur.", "Cela vous fera vingt euros et quinze centimes monsieur.", "fr"),
("Ce sera 100.000,5.", "Ce sera cent mille virgule cinq.", "fr"),
# German
("In 12,5 Sekunden.", "In zwölf Komma fünf Sekunden.", "de"),
("Es gab 50 Soldaten.", "Es gab fünfzig Soldaten.", "de"),
("Dies ist ein 1. Test", "Dies ist ein erste Test", "de"), # Issue with gender
("Das macht $20 Herr.", "Das macht zwanzig Dollar Herr.", "de"),
("Das macht 20€ Herr.", "Das macht zwanzig Euro Herr.", "de"),
("Das macht 20,15€ Herr.", "Das macht zwanzig Euro und fünfzehn Cent Herr.", "de"),
# Spanish
("En 12,5 segundos.", "En doce punto cinco segundos.", "es"),
("Había 50 soldados.", "Había cincuenta soldados.", "es"),
("Este es un 1er test", "Este es un primero test", "es"),
("Eso le costará $20 señor.", "Eso le costará veinte dólares señor.", "es"),
("Eso le costará 20€ señor.", "Eso le costará veinte euros señor.", "es"),
("Eso le costará 20,15€ señor.", "Eso le costará veinte euros con quince céntimos señor.", "es"),
# Italian
("In 12,5 secondi.", "In dodici virgola cinque secondi.", "it"),
("C'erano 50 soldati.", "C'erano cinquanta soldati.", "it"),
("Questo è un 1° test", "Questo è un primo test", "it"),
("Ti costerà $20 signore.", "Ti costerà venti dollari signore.", "it"),
("Ti costerà 20€ signore.", "Ti costerà venti euro signore.", "it"),
("Ti costerà 20,15€ signore.", "Ti costerà venti euro e quindici centesimi signore.", "it"),
# Portuguese
("Em 12,5 segundos.", "Em doze vírgula cinco segundos.", "pt"),
("Havia 50 soldados.", "Havia cinquenta soldados.", "pt"),
("Este é um 1º teste", "Este é um primeiro teste", "pt"),
("Isso custará $20 senhor.", "Isso custará vinte dólares senhor.", "pt"),
("Isso custará 20€ senhor.", "Isso custará vinte euros senhor.", "pt"),
(
"Isso custará 20,15€ senhor.",
"Isso custará vinte euros e quinze cêntimos senhor.",
"pt",
), # "cêntimos" should be "centavos" num2words issue
# Polish
("W 12,5 sekundy.", "W dwanaście przecinek pięć sekundy.", "pl"),
("Było 50 żołnierzy.", "Było pięćdziesiąt żołnierzy.", "pl"),
("To będzie kosztować 20€ panie.", "To będzie kosztować dwadzieścia euro panie.", "pl"),
("To będzie kosztować 20,15€ panie.", "To będzie kosztować dwadzieścia euro, piętnaście centów panie.", "pl"),
# Arabic
("في الـ 12,5 ثانية.", "في الـ اثنا عشر , خمسون ثانية.", "ar"),
("كان هناك 50 جنديًا.", "كان هناك خمسون جنديًا.", "ar"),
# ("ستكون النتيجة $20 يا سيد.", 'ستكون النتيجة عشرون دولار يا سيد.', 'ar'), # $ and € are mising from num2words
# ("ستكون النتيجة 20€ يا سيد.", 'ستكون النتيجة عشرون يورو يا سيد.', 'ar'),
# Czech
("Za 12,5 vteřiny.", "Za dvanáct celá pět vteřiny.", "cs"),
("Bylo tam 50 vojáků.", "Bylo tam padesát vojáků.", "cs"),
("To bude stát 20€ pane.", "To bude stát dvacet euro pane.", "cs"),
("To bude 20.15€ pane.", "To bude dvacet euro, patnáct centů pane.", "cs"),
# Russian
("Через 12.5 секунды.", "Через двенадцать запятая пять секунды.", "ru"),
("Там было 50 солдат.", "Там было пятьдесят солдат.", "ru"),
("Это будет 20.15€ сэр.", "Это будет двадцать евро, пятнадцать центов сэр.", "ru"),
("Это будет стоить 20€ господин.", "Это будет стоить двадцать евро господин.", "ru"),
# Dutch
("In 12,5 seconden.", "In twaalf komma vijf seconden.", "nl"),
("Er waren 50 soldaten.", "Er waren vijftig soldaten.", "nl"),
("Dat wordt dan $20 meneer.", "Dat wordt dan twintig dollar meneer.", "nl"),
("Dat wordt dan 20€ meneer.", "Dat wordt dan twintig euro meneer.", "nl"),
# Chinese (Simplified)
("在12.5秒内", "在十二点五秒内", "zh"),
("有50名士兵", "有五十名士兵", "zh"),
# ("那将是$20先生", '那将是二十美元先生', 'zh'), currency doesn't work
# ("那将是20€先生", '那将是二十欧元先生', 'zh'),
# Turkish
# ("12,5 saniye içinde.", 'On iki virgül beş saniye içinde.', 'tr'), # decimal doesn't work for TR
("50 asker vardı.", "elli asker vardı.", "tr"),
("Bu 1. test", "Bu birinci test", "tr"),
# ("Bu 100.000,5.", 'Bu yüz bin virgül beş.', 'tr'),
# Hungarian
("12,5 másodperc alatt.", "tizenkettő egész öt tized másodperc alatt.", "hu"),
("50 katona volt.", "ötven katona volt.", "hu"),
("Ez az 1. teszt", "Ez az első teszt", "hu"),
# Korean
("12.5 초 안에.", "십이 점 다섯 초 안에.", "ko"),
("50 명의 병사가 있었다.", "오십 명의 병사가 있었다.", "ko"),
("이것은 1 번째 테스트입니다", "이것은 첫 번째 테스트입니다", "ko"),
]
for a, b, lang in test_cases:
out = expand_numbers_multilingual(a, lang=lang)
assert out == b, f"'{out}' vs '{b}'"
def test_abbreviations_multilingual():
test_cases = [
# English
("Hello Mr. Smith.", "Hello mister Smith.", "en"),
("Dr. Jones is here.", "doctor Jones is here.", "en"),
# Spanish
("Hola Sr. Garcia.", "Hola señor Garcia.", "es"),
("La Dra. Martinez es muy buena.", "La doctora Martinez es muy buena.", "es"),
# French
("Bonjour Mr. Dupond.", "Bonjour monsieur Dupond.", "fr"),
("Mme. Moreau est absente aujourd'hui.", "madame Moreau est absente aujourd'hui.", "fr"),
# German
("Frau Dr. Müller ist sehr klug.", "Frau doktor Müller ist sehr klug.", "de"),
# Portuguese
("Olá Sr. Silva.", "Olá senhor Silva.", "pt"),
("Dra. Costa, você está disponível?", "doutora Costa, você está disponível?", "pt"),
# Italian
("Buongiorno, Sig. Rossi.", "Buongiorno, signore Rossi.", "it"),
# ("Sig.ra Bianchi, posso aiutarti?", 'signora Bianchi, posso aiutarti?', 'it'), # Issue with matching that pattern
# Polish
("Dzień dobry, P. Kowalski.", "Dzień dobry, pani Kowalski.", "pl"),
("M. Nowak, czy mogę zadać pytanie?", "pan Nowak, czy mogę zadać pytanie?", "pl"),
# Czech
("P. Novák", "pan Novák", "cs"),
("Dr. Vojtěch", "doktor Vojtěch", "cs"),
# Dutch
("Dhr. Jansen", "de heer Jansen", "nl"),
("Mevr. de Vries", "mevrouw de Vries", "nl"),
# Russian
("Здравствуйте Г-н Иванов.", "Здравствуйте господин Иванов.", "ru"),
("Д-р Смирнов здесь, чтобы увидеть вас.", "доктор Смирнов здесь, чтобы увидеть вас.", "ru"),
# Turkish
("Merhaba B. Yılmaz.", "Merhaba bay Yılmaz.", "tr"),
("Dr. Ayşe burada.", "doktor Ayşe burada.", "tr"),
# Hungarian
("Dr. Szabó itt van.", "doktor Szabó itt van.", "hu"),
]
for a, b, lang in test_cases:
out = expand_abbreviations_multilingual(a, lang=lang)
assert out == b, f"'{out}' vs '{b}'"
def test_symbols_multilingual():
test_cases = [
("I have 14% battery", "I have 14 percent battery", "en"),
("Te veo @ la fiesta", "Te veo arroba la fiesta", "es"),
("J'ai 14° de fièvre", "J'ai 14 degrés de fièvre", "fr"),
("Die Rechnung beträgt £ 20", "Die Rechnung beträgt pfund 20", "de"),
("O meu email é ana&joao@gmail.com", "O meu email é ana e joao arroba gmail.com", "pt"),
("linguaggio di programmazione C#", "linguaggio di programmazione C cancelletto", "it"),
("Moja temperatura to 36.6°", "Moja temperatura to 36.6 stopnie", "pl"),
("Mám 14% baterie", "Mám 14 procento baterie", "cs"),
("Těším se na tebe @ party", "Těším se na tebe na party", "cs"),
("У меня 14% заряда", "У меня 14 процентов заряда", "ru"),
("Я буду @ дома", "Я буду собака дома", "ru"),
("Ik heb 14% batterij", "Ik heb 14 procent batterij", "nl"),
("Ik zie je @ het feest", "Ik zie je bij het feest", "nl"),
("لدي 14% في البطارية", "لدي 14 في المئة في البطارية", "ar"),
("我的电量为 14%", "我的电量为 14 百分之", "zh"),
("Pilim %14 dolu.", "Pilim yüzde 14 dolu.", "tr"),
("Az akkumulátorom töltöttsége 14%", "Az akkumulátorom töltöttsége 14 százalék", "hu"),
("배터리 잔량이 14%입니다.", "배터리 잔량이 14 퍼센트입니다.", "ko"),
]
for a, b, lang in test_cases:
out = expand_symbols_multilingual(a, lang=lang)
assert out == b, f"'{out}' vs '{b}'"
if __name__ == "__main__":
test_expand_numbers_multilingual()
test_abbreviations_multilingual()
test_symbols_multilingual()
@@ -0,0 +1,172 @@
absl-py==2.1.0
aiofiles==23.2.1
aiohttp==3.9.3
aiosignal==1.3.1
altair==5.2.0
annotated-types==0.6.0
anyascii==0.3.2
anyio==4.3.0
attrs==23.2.0
audioread==3.0.1
av==11.0.0
Babel==2.14.0
bangla==0.0.2
blinker==1.7.0
blis==0.7.11
bnnumerizer==0.0.2
bnunicodenormalizer==0.1.6
catalogue==2.0.10
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cloudpathlib==0.16.0
colorama==0.4.6
coloredlogs==15.0.1
confection==0.1.4
contourpy==1.2.0
coqpit==0.0.17
ctranslate2==4.1.0
cutlet==0.4.0
cycler==0.12.1
cymem==2.0.8
Cython==3.0.9
dateparser==1.1.8
decorator==5.1.1
docopt==0.6.2
einops==0.7.0
encodec==0.1.1
fastapi==0.110.0
faster-whisper==1.0.1
ffmpy==0.3.2
filelock==3.13.3
Flask==3.0.2
flatbuffers==24.3.25
fonttools==4.50.0
frozenlist==1.4.1
fsspec==2024.3.1
fugashi==1.3.1
fuzzywuzzy>=0.18.0
g2pkk==0.1.2
gradio==3.50.2
gradio_client==0.6.1
grpcio==1.62.1
gruut==2.2.3
gruut-ipa==0.13.0
gruut-lang-de==2.0.0
gruut-lang-en==2.0.0
gruut-lang-es==2.0.0
gruut-lang-fr==2.0.2
h11==0.14.0
hangul-romanize==0.1.0
httpcore==1.0.4
httpx==0.27.0
huggingface-hub==0.22.1
humanfriendly==10.0
idna==3.6
importlib_metadata==7.1.0
importlib_resources==6.4.0
inflect==7.0.0
itsdangerous==2.1.2
jaconv==0.3.4
jamo==0.4.1
jieba==0.42.1
Jinja2==3.1.3
joblib==1.3.2
jsonlines==1.2.0
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
kiwisolver==1.4.5
langcodes==3.3.0
lazy_loader==0.3
librosa==0.10.1
llvmlite==0.42.0
Markdown==3.6
MarkupSafe==2.1.5
matplotlib==3.8.3
mojimoji==0.0.13
mpmath==1.3.0
msgpack==1.0.8
multidict==6.0.5
murmurhash==1.0.10
networkx==2.8.8
nltk==3.8.1
num2words==0.5.13
numba==0.59.1
numpy==1.26.4
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
onnxruntime==1.17.1
orjson==3.9.15
packaging==24.0
pandas==1.5.3
pillow==10.2.0
platformdirs==4.2.0
pooch==1.8.1
preshed==3.0.9
protobuf==5.26.0
psutil==5.9.8
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
pydub==0.25.1
pynndescent==0.5.11
pyparsing==3.1.2
pypinyin==0.51.0
pyreadline3==3.4.1
pysbd==0.3.4
python-crfsuite==0.9.10
python-dateutil==2.9.0.post0
python-Levenshtein>=0.25.0
python-multipart==0.0.9
pytz==2024.1
PyYAML==6.0.1
referencing==0.34.0
regex==2023.12.25
requests==2.31.0
rpds-py==0.18.0
safetensors==0.4.2
scikit-learn==1.4.1.post1
scipy==1.12.0
semantic-version==2.10.0
six==1.16.0
smart-open==6.4.0
sniffio==1.3.1
sounddevice==0.4.6
soundfile==0.12.1
soxr==0.3.7
spacy==3.7.4
spacy-legacy==3.0.12
spacy-loggers==1.0.5
srsly==2.4.8
starlette==0.36.3
SudachiDict-core==20240109
SudachiPy==0.6.8
sympy==1.12
tensorboard==2.16.2
tensorboard-data-server==0.7.2
thinc==8.2.3
threadpoolctl==3.4.0
tokenizers==0.15.2
toolz==0.12.1
torch>=2.2.0
torchaudio>=2.2.0
tqdm==4.66.2
trainer==0.0.36
transformers==4.39.1
TTS==0.22.0
typer==0.9.4
typing_extensions==4.10.0
tzdata==2024.1
tzlocal==5.2
umap-learn==0.5.5
Unidecode==1.3.8
unidic-lite==1.0.8
urllib3==2.2.1
uvicorn==0.29.0
wasabi==1.1.2
weasel==0.3.4
websockets==11.0.3
Werkzeug==3.0.1
yarl==1.9.4
zipp==3.18.1
@@ -0,0 +1,24 @@
numpy>=1.22.0
soundfile>=0.12.1
uvicorn>=0.24.0.post1
transformers>=4.37.1
TTS>=0.22.0
torch>=2.1.0+cu118
torchaudio>=2.1.0+cu118
fastapi>=0.104.1
Jinja2>=3.1.2
requests>=2.31.0
tqdm>=4.66.1
importlib-metadata>=4.8.1
packaging>=23.2
pydantic>=1.10.13
sounddevice>=0.4.6
python-multipart>=0.0.6
cutlet>=0.3.0
unidic-lite>=1.0.8
faster-whisper>=0.10.0
pandas>=1.5.0
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
fuzzywuzzy>=0.18.0
python-Levenshtein>=0.25.0
+833
View File
@@ -0,0 +1,833 @@
import { doExtrasFetch, getApiUrl, modules } from '../../extensions.js';
import { saveTtsProviderSettings } from './index.js';
export { AllTalkTtsProvider };
class AllTalkTtsProvider {
//########//
// Config //
//########//
settings = {};
constructor() {
// Initialize with default settings if they are not already set
this.settings = {
provider_endpoint: this.settings.provider_endpoint || 'http://localhost:7851',
language: this.settings.language || 'en',
voiceMap: this.settings.voiceMap || {},
at_generation_method: this.settings.at_generation_method || 'standard_generation',
narrator_enabled: this.settings.narrator_enabled || 'false',
at_narrator_text_not_inside: this.settings.at_narrator_text_not_inside || 'narrator',
narrator_voice_gen: this.settings.narrator_voice_gen || 'female_01.wav',
finetuned_model: this.settings.finetuned_model || 'false'
};
// Separate property for dynamically updated settings from the server
this.dynamicSettings = {
modelsAvailable: [],
currentModel: '',
deepspeed_available: false,
deepSpeedEnabled: false,
lowVramEnabled: false,
};
}
ready = false;
voices = [];
separator = '. ';
audioElement = document.createElement('audio');
languageLabels = {
'Arabic': 'ar',
'Brazilian Portuguese': 'pt',
'Chinese': 'zh-cn',
'Czech': 'cs',
'Dutch': 'nl',
'English': 'en',
'French': 'fr',
'German': 'de',
'Italian': 'it',
'Polish': 'pl',
'Russian': 'ru',
'Spanish': 'es',
'Turkish': 'tr',
'Japanese': 'ja',
'Korean': 'ko',
'Hungarian': 'hu',
'Hindi': 'hi',
};
get settingsHtml() {
let html = `<div class="at-settings-separator">AllTalk Settings</div>`;
html += `<div class="at-settings-row">
<div class="at-settings-option">
<label for="at_generation_method">AllTalk TTS Generation Method</label>
<select id="at_generation_method">
<option value="standard_generation">Standard Audio Generation (AT Narrator - Optional)</option>
<option value="streaming_enabled">Streaming Audio Generation (AT Narrator - Disabled)</option>
</select>
</div>
</div>`;
html += `<div class="at-settings-row">
<div class="at-settings-option">
<label for="at_narrator_enabled">AT Narrator</label>
<select id="at_narrator_enabled">
<option value="true">Enabled</option>
<option value="false">Disabled</option>
</select>
</div>
<div class="at-settings-option">
<label for="at_narrator_text_not_inside">Text Not Inside * or " is</label>
<select id="at_narrator_text_not_inside">
<option value="narrator">Narrator</option>
<option value="character">Character</option>
</select>
</div>
</div>`;
html += `<div class="at-settings-row">
<div class="at-settings-option">
<label for="narrator_voice">Narrator Voice</label>
<select id="narrator_voice">`;
if (this.voices) {
for (let voice of this.voices) {
html += `<option value="${voice.voice_id}">${voice.name}</option>`;
}
}
html += `</select>
</div>
<div class="at-settings-option">
<label for="language_options">Language</label>
<select id="language_options">`;
for (let language in this.languageLabels) {
html += `<option value="${this.languageLabels[language]}" ${this.languageLabels[language] === this.settings?.language ? 'selected="selected"' : ''}>${language}</option>`;
}
html += `</select>
</div>
</div>`;
html += `<div class="at-model-endpoint-row">
<div class="at-model-option">
<label for="switch_model">Switch Model</label>
<select id="switch_model">
<option value="api_tts">API TTS</option>
<option value="api_local">API Local</option>
<option value="xttsv2_local">XTTSv2 Local</option>
</select>
</div>
<div class="at-endpoint-option">
<label for="at_server">AllTalk Endpoint:</label>
<input id="at_server" type="text" class="text_pole" maxlength="80" value="${this.settings.provider_endpoint}"/>
</div>
</div>`;
html += `<div class="at-model-endpoint-row">
<div class="at-settings-option">
<label for="low_vram">Low VRAM</label>
<input id="low_vram" type="checkbox"/>
</div>
<div class="at-settings-option">
<label for="deepspeed">DeepSpeed</label>
<input id="deepspeed" type="checkbox"/>
</div>
<div class="at-settings-option status-option">
<span>Status: <span id="status_info">Ready</span></span>
</div>
<div class="at-settings-option empty-option">
<!-- This div remains empty for spacing -->
</div>
</div>`;
html += `<div class="at-website-row">
<div class="at-website-option">
<span>AllTalk <a target="_blank" href="${this.settings.provider_endpoint}">Config & Docs</a>.</span>
</div>
<div class="at-website-option">
<span>AllTalk <a target="_blank" href="https://github.com/erew123/alltalk_tts/">Website</a>.</span>
</div>
</div>`;
html += `<div class="at-website-row">
<div class="at-website-option">
<span><strong>Text-generation-webui</strong> users - Uncheck <strong>Enable TTS</strong> in Text-generation-webui.</span>
</div>
</div>`;
return html;
}
//#################//
// Startup ST & AT //
//#################//
async loadSettings(settings) {
updateStatus('Offline');
if (Object.keys(settings).length === 0) {
console.info('Using default AllTalk TTS Provider settings');
} else {
// Populate settings with provided values, ignoring server-provided settings
for (const key in settings) {
if (key in this.settings) {
this.settings[key] = settings[key];
} else {
console.debug(`Ignoring non-user-configurable setting: ${key}`);
}
}
}
// Update UI elements to reflect the loaded settings
$('#at_server').val(this.settings.provider_endpoint);
$('#language_options').val(this.settings.language);
//$('#voicemap').val(this.settings.voiceMap);
$('#at_generation_method').val(this.settings.at_generation_method);
$('#at_narrator_enabled').val(this.settings.narrator_enabled);
$('#at_narrator_text_not_inside').val(this.settings.at_narrator_text_not_inside);
$('#narrator_voice').val(this.settings.narrator_voice_gen);
console.debug('AllTalkTTS: Settings loaded');
try {
// Check if TTS provider is ready
await this.checkReady();
await this.updateSettingsFromServer(); // Fetch dynamic settings from the TTS server
await this.fetchTtsVoiceObjects(); // Fetch voices only if service is ready
this.updateNarratorVoicesDropdown();
this.updateLanguageDropdown();
this.setupEventListeners();
this.applySettingsToHTML();
updateStatus('Ready');
} catch (error) {
console.error("Error loading settings:", error);
updateStatus('Offline');
}
}
applySettingsToHTML() {
// Apply loaded settings or use defaults
const narratorVoiceSelect = document.getElementById('narrator_voice');
const atNarratorSelect = document.getElementById('at_narrator_enabled');
const textNotInsideSelect = document.getElementById('at_narrator_text_not_inside');
const generationMethodSelect = document.getElementById('at_generation_method');
this.settings.narrator_voice = this.settings.narrator_voice_gen;
// Apply settings to Narrator Voice dropdown
if (narratorVoiceSelect && this.settings.narrator_voice) {
narratorVoiceSelect.value = this.settings.narrator_voice.replace('.wav', '');
}
// Apply settings to AT Narrator Enabled dropdown
if (atNarratorSelect) {
// Sync the state with the checkbox in index.js
const ttsPassAsterisksCheckbox = document.getElementById('tts_pass_asterisks'); // Access the checkbox from index.js
const ttsNarrateQuotedCheckbox = document.getElementById('tts_narrate_quoted'); // Access the checkbox from index.js
const ttsNarrateDialoguesCheckbox = document.getElementById('tts_narrate_dialogues'); // Access the checkbox from index.js
// Sync the state with the checkbox in index.js
if (this.settings.narrator_enabled) {
ttsPassAsterisksCheckbox.checked = false;
$('#tts_pass_asterisks').click(); // Simulate a click event
$('#tts_pass_asterisks').trigger('change');
}
if (!this.settings.narrator_enabled) {
ttsPassAsterisksCheckbox.checked = true;
$('#tts_pass_asterisks').click(); // Simulate a click event
$('#tts_pass_asterisks').trigger('change');
}
// Uncheck and set tts_narrate_quoted to false if narrator is enabled
if (this.settings.narrator_enabledd) {
ttsNarrateQuotedCheckbox.checked = true;
ttsNarrateDialoguesCheckbox.checked = true;
// Trigger click events instead of change events
$('#tts_narrate_quoted').click();
$('#tts_narrate_quoted').trigger('change');
$('#tts_narrate_dialogues').click();
$('#tts_narrate_dialogues').trigger('change');
}
atNarratorSelect.value = this.settings.narrator_enabled.toString();
this.settings.narrator_enabled = this.settings.narrator_enabled.toString();
}
// Apply settings to the Language dropdown
const languageSelect = document.getElementById('language_options');
if (languageSelect && this.settings.language) {
languageSelect.value = this.settings.language;
}
// Apply settings to Text Not Inside dropdown
if (textNotInsideSelect && this.settings.text_not_inside) {
textNotInsideSelect.value = this.settings.text_not_inside;
this.settings.at_narrator_text_not_inside = this.settings.text_not_inside;
}
// Apply settings to Generation Method dropdown
if (generationMethodSelect && this.settings.at_generation_method) {
generationMethodSelect.value = this.settings.at_generation_method;
}
// Additional logic to disable/enable dropdowns based on the selected generation method
const isStreamingEnabled = this.settings.at_generation_method === 'streaming_enabled';
if (isStreamingEnabled) {
// Disable certain dropdowns when streaming is enabled
if (atNarratorSelect) atNarratorSelect.disabled = true;
if (textNotInsideSelect) textNotInsideSelect.disabled = true;
if (narratorVoiceSelect) narratorVoiceSelect.disabled = true;
} else {
// Enable dropdowns for standard generation
if (atNarratorSelect) atNarratorSelect.disabled = false;
if (textNotInsideSelect) textNotInsideSelect.disabled = !this.settings.narrator_enabled;
if (narratorVoiceSelect) narratorVoiceSelect.disabled = !this.settings.narrator_enabled;
}
const modelSelect = document.getElementById('switch_model');
if (this.settings.finetuned_model === 'true') {
const ftOption = document.createElement('option');
ftOption.value = 'XTTSv2 FT';
ftOption.textContent = 'XTTSv2 FT';
modelSelect.appendChild(ftOption);
}
}
//##############################//
// Check AT Server is Available //
//##############################//
async checkReady() {
try {
const response = await fetch(`${this.settings.provider_endpoint}/api/ready`);
// Check if the HTTP request was successful
if (!response.ok) {
throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
}
const statusText = await response.text();
// Check if the response is 'Ready'
if (statusText === 'Ready') {
this.ready = true; // Set the ready flag to true
console.log('TTS service is ready.');
} else {
this.ready = false;
console.log('TTS service is not ready.');
}
} catch (error) {
console.error('Error checking TTS service readiness:', error);
this.ready = false; // Ensure ready flag is set to false in case of error
}
}
//######################//
// Get Available Voices //
//######################//
async fetchTtsVoiceObjects() {
const response = await fetch(`${this.settings.provider_endpoint}/api/voices`);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
const data = await response.json();
const voices = data.voices.map(filename => {
const voiceName = filename.replace('.wav', '');
return {
name: voiceName,
voice_id: voiceName,
preview_url: null, // Preview URL will be dynamically generated
lang: 'en' // Default language
};
});
this.voices = voices; // Assign to the class property
return voices; // Also return this list
}
//##########################################//
// Get Current AT Server Config & Update ST //
//##########################################//
async updateSettingsFromServer() {
try {
// Fetch current settings
const response = await fetch(`${this.settings.provider_endpoint}/api/currentsettings`);
if (!response.ok) {
throw new Error(`Failed to fetch current settings: ${response.statusText}`);
}
const currentSettings = await response.json();
// Update internal settings
this.settings.modelsAvailable = currentSettings.models_available;
this.settings.currentModel = currentSettings.current_model_loaded;
this.settings.deepspeed_available = currentSettings.deepspeed_available;
this.settings.deepSpeedEnabled = currentSettings.deepspeed_status;
this.settings.lowVramEnabled = currentSettings.low_vram_status;
this.settings.finetuned_model = currentSettings.finetuned_model
// Update HTML elements
this.updateModelDropdown();
this.updateCheckboxes();
} catch (error) {
console.error(`Error updating settings from server: ${error}`);
}
}
//###################################################//
// Get Current AT Server Config & Update ST (Models) //
//###################################################//
updateModelDropdown() {
const modelSelect = document.getElementById('switch_model');
if (modelSelect) {
modelSelect.innerHTML = ''; // Clear existing options
this.settings.modelsAvailable.forEach(model => {
const option = document.createElement('option');
option.value = model.model_name;
option.textContent = model.model_name; // Use model_name instead of name
option.selected = model.model_name === this.settings.currentModel;
modelSelect.appendChild(option);
});
}
}
//#######################################################//
// Get Current AT Server Config & Update ST (DS and LVR) //
//#######################################################//
updateCheckboxes() {
const deepspeedCheckbox = document.getElementById('deepspeed');
const lowVramCheckbox = document.getElementById('low_vram');
if (lowVramCheckbox) lowVramCheckbox.checked = this.settings.lowVramEnabled;
if (deepspeedCheckbox) {
deepspeedCheckbox.checked = this.settings.deepSpeedEnabled;
deepspeedCheckbox.disabled = !this.settings.deepspeed_available; // Disable checkbox if deepspeed is not available
}
}
//###############################################################//
// Get Current AT Server Config & Update ST (AT Narrator Voices) //
//###############################################################//
updateNarratorVoicesDropdown() {
const narratorVoiceSelect = document.getElementById('narrator_voice');
if (narratorVoiceSelect && this.voices) {
// Clear existing options
narratorVoiceSelect.innerHTML = '';
// Add new options
for (let voice of this.voices) {
const option = document.createElement('option');
option.value = voice.voice_id;
option.textContent = voice.name;
narratorVoiceSelect.appendChild(option);
}
}
}
//######################################################//
// Get Current AT Server Config & Update ST (Languages) //
//######################################################//
updateLanguageDropdown() {
const languageSelect = document.getElementById('language_options');
if (languageSelect) {
// Ensure default language is set
this.settings.language = this.settings.language;
languageSelect.innerHTML = '';
for (let language in this.languageLabels) {
const option = document.createElement('option');
option.value = this.languageLabels[language];
option.textContent = language;
if (this.languageLabels[language] === this.settings.language) {
option.selected = true;
}
languageSelect.appendChild(option);
}
}
}
//########################################//
// Start AT TTS extenstion page listeners //
//########################################//
setupEventListeners() {
let debounceTimeout;
const debounceDelay = 500; // Milliseconds
// Define the event handler function
const onModelSelectChange = async (event) => {
console.log("Model select change event triggered"); // Debugging statement
const selectedModel = event.target.value;
console.log(`Selected model: ${selectedModel}`); // Debugging statement
// Set status to Processing
updateStatus('Processing');
try {
const response = await fetch(`${this.settings.provider_endpoint}/api/reload?tts_method=${encodeURIComponent(selectedModel)}`, {
method: 'POST'
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
console.log("POST response data:", data); // Debugging statement
// Set status to Ready if successful
updateStatus('Ready');
} catch (error) {
console.error("POST request error:", error); // Debugging statement
// Set status to Error in case of failure
updateStatus('Error');
}
// Handle response or error
};
const debouncedModelSelectChange = (event) => {
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(() => {
onModelSelectChange(event);
}, debounceDelay);
};
// Switch Model Listener
const modelSelect = document.getElementById('switch_model');
if (modelSelect) {
// Remove the event listener if it was previously added
modelSelect.removeEventListener('change', debouncedModelSelectChange);
// Add the debounced event listener
modelSelect.addEventListener('change', debouncedModelSelectChange);
}
// DeepSpeed Listener
const deepspeedCheckbox = document.getElementById('deepspeed');
if (deepspeedCheckbox) {
deepspeedCheckbox.addEventListener('change', async (event) => {
const deepSpeedValue = event.target.checked ? 'True' : 'False';
// Set status to Processing
updateStatus('Processing');
try {
const response = await fetch(`${this.settings.provider_endpoint}/api/deepspeed?new_deepspeed_value=${deepSpeedValue}`, {
method: 'POST'
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
console.log("POST response data:", data); // Debugging statement
// Set status to Ready if successful
updateStatus('Ready');
} catch (error) {
console.error("POST request error:", error); // Debugging statement
// Set status to Error in case of failure
updateStatus('Error');
}
});
}
// Low VRAM Listener
const lowVramCheckbox = document.getElementById('low_vram');
if (lowVramCheckbox) {
lowVramCheckbox.addEventListener('change', async (event) => {
const lowVramValue = event.target.checked ? 'True' : 'False';
// Set status to Processing
updateStatus('Processing');
try {
const response = await fetch(`${this.settings.provider_endpoint}/api/lowvramsetting?new_low_vram_value=${lowVramValue}`, {
method: 'POST'
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
console.log("POST response data:", data); // Debugging statement
// Set status to Ready if successful
updateStatus('Ready');
} catch (error) {
console.error("POST request error:", error); // Debugging statement
// Set status to Error in case of failure
updateStatus('Error');
}
});
}
// Narrator Voice Dropdown Listener
const narratorVoiceSelect = document.getElementById('narrator_voice');
if (narratorVoiceSelect) {
narratorVoiceSelect.addEventListener('change', (event) => {
this.settings.narrator_voice_gen = `${event.target.value}.wav`;
this.onSettingsChange(); // Save the settings after change
});
}
const textNotInsideSelect = document.getElementById('at_narrator_text_not_inside');
if (textNotInsideSelect) {
textNotInsideSelect.addEventListener('change', (event) => {
this.settings.text_not_inside = event.target.value;
this.onSettingsChange(); // Save the settings after change
});
}
// AT Narrator Dropdown Listener
const atNarratorSelect = document.getElementById('at_narrator_enabled');
const ttsPassAsterisksCheckbox = document.getElementById('tts_pass_asterisks'); // Access the checkbox from index.js
const ttsNarrateQuotedCheckbox = document.getElementById('tts_narrate_quoted'); // Access the checkbox from index.js
const ttsNarrateDialoguesCheckbox = document.getElementById('tts_narrate_dialogues'); // Access the checkbox from index.js
if (atNarratorSelect && textNotInsideSelect && narratorVoiceSelect) {
atNarratorSelect.addEventListener('change', (event) => {
const isNarratorEnabled = event.target.value === 'true';
this.settings.narrator_enabled = isNarratorEnabled; // Update the setting here
textNotInsideSelect.disabled = !isNarratorEnabled;
narratorVoiceSelect.disabled = !isNarratorEnabled;
// Sync the state with the checkbox in index.js
if (isNarratorEnabled) {
ttsPassAsterisksCheckbox.checked = false;
$('#tts_pass_asterisks').click(); // Simulate a click event
$('#tts_pass_asterisks').trigger('change');
}
if (!isNarratorEnabled) {
ttsPassAsterisksCheckbox.checked = true;
$('#tts_pass_asterisks').click(); // Simulate a click event
$('#tts_pass_asterisks').trigger('change');
}
// Uncheck and set tts_narrate_quoted to false if narrator is enabled
if (isNarratorEnabled) {
ttsNarrateQuotedCheckbox.checked = true;
ttsNarrateDialoguesCheckbox.checked = true;
// Trigger click events instead of change events
$('#tts_narrate_quoted').click();
$('#tts_narrate_quoted').trigger('change');
$('#tts_narrate_dialogues').click();
$('#tts_narrate_dialogues').trigger('change');
}
this.onSettingsChange(); // Save the settings after change
});
}
// Event Listener for AT Generation Method Dropdown
const atGenerationMethodSelect = document.getElementById('at_generation_method');
const atNarratorEnabledSelect = document.getElementById('at_narrator_enabled');
if (atGenerationMethodSelect) {
atGenerationMethodSelect.addEventListener('change', (event) => {
const selectedMethod = event.target.value;
if (selectedMethod === 'streaming_enabled') {
// Disable and unselect AT Narrator
atNarratorEnabledSelect.disabled = true;
atNarratorEnabledSelect.value = 'false';
textNotInsideSelect.disabled = true;
narratorVoiceSelect.disabled = true;
} else if (selectedMethod === 'standard_generation') {
// Enable AT Narrator
atNarratorEnabledSelect.disabled = false;
}
this.settings.at_generation_method = selectedMethod; // Update the setting here
this.onSettingsChange(); // Save the settings after change
});
}
// Listener for Language Dropdown
const languageSelect = document.getElementById('language_options');
if (languageSelect) {
languageSelect.addEventListener('change', (event) => {
this.settings.language = event.target.value;
this.onSettingsChange(); // Save the settings after change
});
}
// Listener for AllTalk Endpoint Input
const atServerInput = document.getElementById('at_server');
if (atServerInput) {
atServerInput.addEventListener('input', (event) => {
this.settings.provider_endpoint = event.target.value;
this.onSettingsChange(); // Save the settings after change
});
}
}
//#############################//
// Store ST interface settings //
//#############################//
onSettingsChange() {
// Update settings based on the UI elements
//this.settings.provider_endpoint = $('#at_server').val();
this.settings.language = $('#language_options').val();
//this.settings.voiceMap = $('#voicemap').val();
this.settings.at_generation_method = $('#at_generation_method').val();
this.settings.narrator_enabled = $('#at_narrator_enabled').val();
this.settings.at_narrator_text_not_inside = $('#at_narrator_text_not_inside').val();
this.settings.narrator_voice_gen = $('#narrator_voice').val();
// Save the updated settings
saveTtsProviderSettings();
}
//#########################//
// ST Handle Reload button //
//#########################//
async onRefreshClick() {
await this.checkReady(); // Check if the TTS provider is ready
await this.loadSettings(this.settings); // Reload the settings
// Additional actions as needed
}
//##################//
// Preview AT Voice //
//##################//
async previewTtsVoice(voiceName) {
try {
// Prepare data for POST request
const postData = new URLSearchParams();
postData.append("voice", `${voiceName}.wav`);
// Making the POST request
const response = await fetch(`${this.settings.provider_endpoint}/api/previewvoice/`, {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: postData,
});
if (!response.ok) {
const errorText = await response.text();
console.error(`[previewTtsVoice] Error Response Text:`, errorText);
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
// Assuming the server returns a URL to the .wav file
const data = await response.json();
if (data.output_file_url) {
// Use an audio element to play the .wav file
const audioElement = new Audio(data.output_file_url);
audioElement.play().catch(e => console.error("Error playing audio:", e));
} else {
console.warn("[previewTtsVoice] No output file URL received in the response");
throw new Error("No output file URL received in the response");
}
} catch (error) {
console.error("[previewTtsVoice] Exception caught during preview generation:", error);
throw error;
}
}
//#####################//
// Populate ST voices //
//#####################//
async getVoice(voiceName, generatePreview = false) {
// Ensure this.voices is populated
if (this.voices.length === 0) {
// Fetch voice objects logic
}
// Find the object where the name matches voiceName
const match = this.voices.find(voice => voice.name === voiceName);
if (!match) {
// Error handling
}
// Generate preview URL only if requested
if (!match.preview_url && generatePreview) {
// Generate preview logic
}
return match; // Return the found voice object
}
//##########################################//
// Generate TTS Streaming or call Standard //
//##########################################//
async generateTts(inputText, voiceId) {
try {
if (this.settings.at_generation_method === 'streaming_enabled') {
// Construct the streaming URL
const streamingUrl = `${this.settings.provider_endpoint}/api/tts-generate-streaming?text=${encodeURIComponent(inputText)}&voice=${encodeURIComponent(voiceId)}.wav&language=${encodeURIComponent(this.settings.language)}&output_file=stream_output.wav`;
console.log("Streaming URL:", streamingUrl);
// Return the streaming URL directly
return streamingUrl;
} else {
// For standard method
const outputUrl = await this.fetchTtsGeneration(inputText, voiceId);
const audioResponse = await fetch(outputUrl);
if (!audioResponse.ok) {
throw new Error(`HTTP ${audioResponse.status}: Failed to fetch audio data`);
}
return audioResponse; // Return the fetch response directly
}
} catch (error) {
console.error("Error in generateTts:", error);
throw error;
}
}
//####################//
// Generate Standard //
//####################//
async fetchTtsGeneration(inputText, voiceId) {
// Prepare the request payload
const requestBody = new URLSearchParams({
'text_input': inputText,
'text_filtering': "standard",
'character_voice_gen': voiceId + ".wav",
'narrator_enabled': this.settings.narrator_enabled,
'narrator_voice_gen': this.settings.narrator_voice_gen + ".wav",
'text_not_inside': this.settings.at_narrator_text_not_inside,
'language': this.settings.language,
'output_file_name': "st_output",
'output_file_timestamp': "true",
'autoplay': "false",
'autoplay_volume': "0.8"
}).toString();
try {
const response = await doExtrasFetch(
`${this.settings.provider_endpoint}/api/tts-generate`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-cache',
},
body: requestBody
}
);
if (!response.ok) {
const errorText = await response.text();
console.error(`[fetchTtsGeneration] Error Response Text:`, errorText);
// toastr.error(response.statusText, 'TTS Generation Failed');
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
const data = await response.json();
const outputUrl = data.output_file_url;
return outputUrl; // Return only the output_file_url
} catch (error) {
console.error("[fetchTtsGeneration] Exception caught:", error);
throw error; // Rethrow the error for further handling
}
}
}
//#########################//
// Update Status Messages //
//#########################//
function updateStatus(message) {
const statusElement = document.getElementById('status_info');
if (statusElement) {
statusElement.textContent = message;
switch (message) {
case 'Offline':
statusElement.style.color = 'red';
break;
case 'Ready':
statusElement.style.color = 'lightgreen';
break;
case 'Processing':
statusElement.style.color = 'blue';
break;
case 'Error':
statusElement.style.color = 'red';
break;
}
}
}
File diff suppressed because it is too large. Load diff
+159
View File
@@ -0,0 +1,159 @@
#tts_media_control {
/* order: 100; */
/* width: 40px;
height: 40px;
margin: 0;
padding: 1px; */
outline: none;
border: none;
cursor: pointer;
/* transition: 0.3s;
opacity: 0.7; */
display: flex;
align-items: center;
/* justify-content: center; */
}
#ttsExtensionMenuItem {
transition: 0.3s;
opacity: 0.7;
}
#ttsExtensionMenuItem:hover {
opacity: 1;
filter: brightness(1.2);
}
#tts_media_control:hover {
opacity: 1;
filter: brightness(1.2);
}
.voice_preview {
margin: 0.25rem 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
}
.voice_preview .voice_name {
text-align: left;
flex: 1;
}
.voice_preview .voice_lang {
width: 4rem;
text-align: left;
}
.voice_preview .fa-play {
cursor: pointer;
}
.tts-button {
margin: 0;
outline: none;
border: none;
cursor: pointer;
transition: 0.3s;
opacity: 0.7;
align-items: center;
justify-content: center;
}
.tts-button:hover {
opacity: 1;
}
.tts_block {
display: flex;
align-items: baseline;
column-gap: 5px;
flex-wrap: wrap;
}
.tts_custom_voices {
display: flex;
align-items: baseline;
gap: 5px;
}
.novel_tts_hints {
font-size: calc(0.9 * var(--mainFontSize));
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 5px;
}
.at-settings-row {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.at-settings-option {
flex: 1;
margin: 0 10px;
}
.at-endpoint-option {
flex: 1;
margin: 0 10px;
margin-right: 25px;
width: 38%;
}
.at-website-row {
display: flex;
justify-content: start;
align-items: center;
margin-top: 10px;
margin-bottom: 10px;
}
.at-website-option {
flex: 1;
margin-right: 10px;
margin-left: 10px;
}
.at-settings-separator {
margin-top: 10px;
margin-bottom: 10px;
padding: 18x;
font-weight: bold;
border-top: 1px solid #e1e1e1; /* Grey line */
border-bottom: 1px solid #e1e1e1; /* Grey line */
text-align: center;
}
.at-status-message {
flex: 1;
margin: 0 10px;
}
.at-model-endpoint-row {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.at-model-option, .endpoint-option {
flex: 1;
margin: 0 10px;
margin-left: 10px;
}
.at-endpoint-option {
width: 38%;
}
#at-status_info {
color: lightgreen;
}
+269
View File
@@ -0,0 +1,269 @@
import json
import argparse
from pathlib import Path
import os
import glob
import platform
import site
import subprocess
import sys
# version 0.8
def find_files_in_path_with_wildcard(pattern):
# Get the site-packages directory of the current Python environment
site_packages_path = site.getsitepackages()
found_paths = []
# Adjust the sub-directory based on the operating system
sub_directory = "nvidia/cublas"
if platform.system() == "Linux":
sub_directory = os.path.join(sub_directory, "lib")
else:
sub_directory = os.path.join(sub_directory, "bin")
# Iterate over each site-packages directory (there can be more than one)
for directory in site_packages_path:
# Construct the search directory path
search_directory = os.path.join(directory, sub_directory)
# Use glob to find all files matching the pattern in this directory
for file_path in glob.glob(os.path.join(search_directory, pattern)):
if os.path.isfile(file_path): # Ensure it's a file
found_paths.append(file_path)
return found_paths
def detect_cublas():
# Use different file patterns based on the operating system
file_name_pattern = 'cublas64_11.*' if platform.system() == "Windows" else 'libcublas.so.11*'
found_paths = find_files_in_path_with_wildcard(file_name_pattern)
if found_paths:
print("[AllTalk TTSDiff] \033[94mCublas:\033[0m \033[92mDetected\033[0m", found_paths)
else:
print("[AllTalk TTSDiff] \033[94mCublas:\033[0m \033[91mERROR Not Detected\033[0m")
print("[AllTalk TTSDiff] \033[94mPlease install Cublas from the Nvidia CUDA Toolkit \033[0mhttps://developer.nvidia.com/cuda-downloads")
exit(1)
parser = argparse.ArgumentParser(description="Compare TTS output with the original text using detailed comparison.")
parser.add_argument("--threshold", type=int, default=98, help="Similarity threshold for considering a match (default: 98)")
parser.add_argument("--ttslistpath", help="Path to the ttsList.json file")
parser.add_argument("--wavfilespath", help="Path to the wav outputs folder")
args = parser.parse_args()
if not args.ttslistpath:
parser.error("[AllTalk TTSDiff] Please specify the path to the ttslist.json file using the --ttslistpath argument.")
if not args.wavfilespath:
parser.error("[AllTalk TTSDiff] Please specify the path to the wavs output folder file using the --wavfilespath argument.")
json_file_path = Path(args.ttslistpath).resolve()
wav_file_path = Path(args.wavfilespath).resolve()
accuracy_threshold = args.threshold
def disclaimer_text():
print(f"\nDESCRIPTION: ")
print(f" This script is designed to assist in identifying bad TTS generation ID's from the TTS Generator.\n")
print(f" This will download the Whisper Large-v2 model (if not already downloaded), and use it to compare your text to")
print(f" to the generated TTS. If it finds an issue, it will flag the ID number that has the issue. This does NOT 100%")
print(f" ensure that all TTS generated is perfect, sounds good etc, but it should flag up glaring issues and help with")
print(f" the process of identifying bad TTS generations.")
print(f"\nNOTES ON USE: ")
print(f" - Ensure AllTalk is running in its own command prompt/terminal.")
print(f" - This script should be running in its own command prompt/terminal window in the same Python Environment that")
print(f" AllTalk is running in.")
print(f" - After generating your text in the TTS Generator, you need to `Export List to JSON` and save the file in the")
print(f" same folder/directory this script is running from.")
print(f" - You can use `--threshold` with a numerical value from 1 to 100 to set accuracy detection. For example it may")
print(f" detect/transcribe `their` as `there`, which of course, both words sound the same. If you want 100% accuracy")
print(f" you will set 100 as the threshold. You will more than likely want a number in the high 90's. Default is set")
print(f" at 98, which gives a little flexibility.")
print(f" - The JSON file must be named \033[93mttsList.json\033[0m")
print(f" - When you have your ID list, go back into the TTS Generator, correct any lines and regenerate them. If you")
print(f" want to re-test everthing again after re-generating, you will need to export your list again and re-run this")
print(f" script again, against your newly exported JSON list.")
print(f" - This requires access to \033[93mcublas64_11\033[0m, the same as Finetuning.")
print(f" https://github.com/erew123/alltalk_tts/tree/main?#-important-requirements-cuda-118\n")
return
try:
from faster_whisper import WhisperModel
import re
import string
import spacy
import torch
from fuzzywuzzy import fuzz
except ImportError as e:
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
print("[AllTalk TTSDiff] An error occurred importing one or more required libraries.")
print("[AllTalk TTSDiff] Please ensure you have \033[94mactivated your Python environment \033[0mand \033[94minstalled all requirements.\033[0m")
print("[AllTalk TTSDiff] \033[94mMissing library:\033[93m", str(e), "\033[0m")
exit(1)
# Attempt to load the spaCy model
try:
# Load a medium-sized spaCy model, adjust to "en_core_web_md" or "en_core_web_lg" as needed
nlp = spacy.load("en_core_web_md")
except Exception as e:
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
print("[AllTalk TTSDiff] Failed to load the spaCy language model.")
# Attempt to download the spaCy model automatically
try:
print("[AllTalk TTSDiff] Attempting to automatically download the spaCy language model...")
subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_md"], check=True)
# Try to load the model again after downloading
nlp = spacy.load("en_core_web_md")
print("[AllTalk TTSDiff] Model downloaded and loaded successfully.")
except Exception as download_exception:
print("[AllTalk TTSDiff] Automatic download failed.")
print("[AllTalk TTSDiff] Please manually install the spaCy language model by running:")
print("[AllTalk TTSDiff] \033[93mpython -m spacy download en_core_web_md\033[0m")
exit(1)
def texts_are_similar(text1, text2, threshold=0.8):
# Preliminary check for short texts
if len(text1) < 10 or len(text2) < 10:
ratio = fuzz.ratio(text1, text2) / 100.0 # Use FuzzyWuzzy for short texts
return ratio > threshold
# Process the texts through the NLP model for longer texts
doc1 = nlp(text1)
doc2 = nlp(text2)
# Compute semantic similarity
similarity = doc1.similarity(doc2)
return similarity >= threshold
def normalize_text(text):
# Normalize or remove CRLF and other non-standard whitespaces
text = text.replace("\r\n", " ").replace("\n", " ").replace("\r", " ")
# Convert to lowercase
text = text.lower()
# Standardize and then remove quotation marks
text = text.replace("“", '"').replace("”", '"').replace("‘", "'").replace("’", "'")
text = text.translate(str.maketrans('', '', '"\''))
# Remove all other punctuation except hyphens to preserve compound words
text = text.translate(str.maketrans('', '', string.punctuation.replace("-", "")))
# Collapse any sequence of whitespace (including spaces) into a single space
text = re.sub(r'\s+', ' ', text)
return text.strip()
spoken_punctuation_mapping = {
"dot": ".",
"comma": ",",
# Add more mappings as needed
}
def contains_spoken_punctuation(transcribed_text):
for spoken, punctuation in spoken_punctuation_mapping.items():
if spoken in transcribed_text:
return True
return False
def detailed_comparison(original_text, transcribed_text, threshold=98):
original_clean = normalize_text(original_text)
transcribed_clean = normalize_text(transcribed_text)
ratio = fuzz.ratio(original_clean, transcribed_clean)
return ratio > threshold
def access_local_file(url):
# Extract the file name from the URL
file_name = url.split('/')[-1]
# Construct the full path to the file on disk
file_path = wav_file_path / file_name
# Check if the file exists
if not file_path.exists():
print(f"[AllTalk TTSDiff] File does not exist: {file_path}")
return None
return file_path
def transcribe_and_compare(file_url, original_text, model, item_id, flagged_ids):
audio_file_path = access_local_file(file_url)
if audio_file_path is None:
print(f"[AllTalk TTSDiff] Could not access local file for URL: {file_url}")
return # Skip this file if it can't be accessed
try:
segments, info = model.transcribe(str(audio_file_path), beam_size=5)
transcribed_text = " ".join([segment.text for segment in segments])
except Exception as e:
print(f"[AllTalk TTSDiff] Error transcribing file {audio_file_path}: {e}")
return # Skip this file if transcription fails
segments, info = model.transcribe(str(audio_file_path), beam_size=5)
transcribed_text = " ".join([segment.text for segment in segments])
# Normalize texts for comparison
original_text_normalized = normalize_text(original_text)
transcribed_text_normalized = normalize_text(transcribed_text)
# Enhanced comparison using detailed fuzzy matching
is_detailed_match = detailed_comparison(original_text_normalized, transcribed_text_normalized, args.threshold)
has_spoken_punctuation = contains_spoken_punctuation(transcribed_text_normalized) and not contains_spoken_punctuation(original_text_normalized)
# Adjust is_match based on detailed comparison and spoken punctuation check
is_match = is_detailed_match and not has_spoken_punctuation
# Only log and flag IDs for review if there's a mismatch or detected issues
if not is_match:
#print(f"\033[93mMismatch Detected - ID:\033[0m {item_id}")
print(f"[AllTalk TTSDiff] \033[93mText:\033[0m {original_text}")
print(f"[AllTalk TTSDiff] \033[91mTTS :\033[0m{transcribed_text}")
if has_spoken_punctuation:
print(f"[AllTalk TTSDiff] Note: Potential incorrect spoken punctuation detected.")
flagged_ids.append(item_id) # Track the ID for review
def main():
print(f"[AllTalk TTSDiff]")
print(f"[AllTalk TTSDiff]")
print("[AllTalk TTSDiff] \033[92mStarting Compare of Text vs TTS:\033[0m")
print("[AllTalk TTSDiff]")
print("[AllTalk TTSDiff] \033[94mJSON file :\033[92m", json_file_path, "\033[0m")
print("[AllTalk TTSDiff] \033[94mWAV files :\033[92m", wav_file_path, "\033[0m")
print("[AllTalk TTSDiff] \033[94mAccuracy :\033[92m", accuracy_threshold, "%", "\033[0m")
detect_cublas()
model_size = "large-v2"
device = "cuda" if torch.cuda.is_available() else "cpu"
model = WhisperModel(model_size, device=device, compute_type="float32")
flagged_ids = [] # Initialize the list to track IDs needing review
try:
with open(json_file_path, "r", encoding="utf-8") as f:
tts_list = json.load(f)
except FileNotFoundError:
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
print("[AllTalk TTSDiff] Error: \033[93mttsList.json\033[0m file not found.")
print("[AllTalk TTSDiff] Please ensure you follow these steps:")
print("[AllTalk TTSDiff] After generating your text in the TTS Generator, you need to `Export List to JSON` and save the file in the")
print("[AllTalk TTSDiff] same folder/directory this script is running from.")
print("[AllTalk TTSDiff] The JSON file must be named \033[93mttsList.json\033[0m")
exit(1)
print(f"[AllTalk TTSDiff]")
for item in tts_list:
print(f"[AllTalk TTSDiff] Processing ID: {item['id']}")
transcribe_and_compare(item['fileUrl'], item['text'], model, item['id'], flagged_ids)
print(f"[AllTalk TTSDiff]")
# Print summary information at the end
if flagged_ids:
print(f"[AllTalk TTSDiff] \033[94mIDs needing review:\033[0m", ', '.join(map(str, flagged_ids)))
print(f"[AllTalk TTSDiff]")
print(f"[AllTalk TTSDiff] Review ID's and correct any lines by editing & regenerating as necessary.")
else:
print("[AllTalk TTSDiff] \033[94mIDs needing review:\033[0m No issues detected.")
summary_data = {
"flagged_ids": flagged_ids
}
with open(wav_file_path / "analysis_summary.json", "w") as summary_file:
json.dump(summary_data, summary_file)
print("[AllTalk TTSDiff]")
if __name__ == "__main__":
main()
+179
View File
@@ -0,0 +1,179 @@
export interface CrunkerConstructorOptions {
/**
* Sample rate for Crunker's internal audio context.
*
* @default 44100
*/
sampleRate: number;
}
export type CrunkerInputTypes = string | File | Blob;
/**
* An exported Crunker audio object.
*/
export interface ExportedCrunkerAudio {
blob: Blob;
url: string;
element: HTMLAudioElement;
}
/**
* Crunker is the simple way to merge, concatenate, play, export and download audio files using the Web Audio API.
*/
export default class Crunker {
private readonly _sampleRate;
private readonly _context;
/**
* Creates a new instance of Crunker with the provided options.
*
* If `sampleRate` is not defined, it will auto-select an appropriate sample rate
* for the device being used.
*/
constructor({ sampleRate }?: Partial<CrunkerConstructorOptions>);
/**
* Creates Crunker's internal AudioContext.
*
* @internal
*/
private _createContext;
/**
*
* The internal AudioContext used by Crunker.
*/
get context(): AudioContext;
/**
* Asynchronously fetches multiple audio files and returns an array of AudioBuffers.
*/
fetchAudio(...filepaths: CrunkerInputTypes[]): Promise<AudioBuffer[]>;
/**
* Merges (layers) multiple AudioBuffers into a single AudioBuffer.
*
* **Visual representation:**
*
* ![](https://user-images.githubusercontent.com/12958674/88806278-968f0680-d186-11ea-9cb5-8ef2606ffcc7.png)
*/
mergeAudio(buffers: AudioBuffer[]): AudioBuffer;
/**
* Concatenates multiple AudioBuffers into a single AudioBuffer.
*
* **Visual representation:**
*
* ![](https://user-images.githubusercontent.com/12958674/88806297-9d1d7e00-d186-11ea-8cd2-c64cb0324845.png)
*/
concatAudio(buffers: AudioBuffer[]): AudioBuffer;
/**
* Pads a specified AudioBuffer with silence from a specified start time,
* for a specified length of time.
*
* Accepts float values as well as whole integers.
*
* @param buffer AudioBuffer to pad
* @param padStart Time to start padding (in seconds)
* @param seconds Duration to pad for (in seconds)
*/
padAudio(buffer: AudioBuffer, padStart?: number, seconds?: number): AudioBuffer;
/**
* Slices an AudioBuffer from the specified start time to the end time, with optional fade in and out.
*
* @param buffer AudioBuffer to slice
* @param start Start time (in seconds)
* @param end End time (in seconds)
* @param fadeIn Fade in duration (in seconds, default is 0)
* @param fadeOut Fade out duration (in seconds, default is 0)
*/
sliceAudio(buffer: AudioBuffer, start: number, end: number, fadeIn?: number, fadeOut?: number): AudioBuffer;
/**
* Plays the provided AudioBuffer in an AudioBufferSourceNode.
*/
play(buffer: AudioBuffer): AudioBufferSourceNode;
/**
* Exports the specified AudioBuffer to a Blob, Object URI and HTMLAudioElement.
*
* Note that changing the MIME type does not change the actual file format. The
* file format will **always** be a WAVE file due to how audio is stored in the
* browser.
*
* @param buffer Buffer to export
* @param type MIME type (default: `audio/wav`)
*/
export(buffer: AudioBuffer, type?: string): ExportedCrunkerAudio;
/**
* Downloads the provided Blob.
*
* @param blob Blob to download
* @param filename An optional file name to use for the download (default: `crunker`)
*/
download(blob: Blob, filename?: string): HTMLAnchorElement;
/**
* Executes a callback if the browser does not support the Web Audio API.
*
* Returns the result of the callback, or `undefined` if the Web Audio API is supported.
*
* @param callback callback to run if the browser does not support the Web Audio API
*/
notSupported<T>(callback: () => T): T | undefined;
/**
* Closes Crunker's internal AudioContext.
*/
close(): this;
/**
* Returns the largest duration of the longest AudioBuffer.
*
* @internal
*/
private _maxDuration;
/**
* Returns the largest number of channels in an array of AudioBuffers.
*
* @internal
*/
private _maxNumberOfChannels;
/**
* Returns the sum of the lengths of an array of AudioBuffers.
*
* @internal
*/
private _totalLength;
/**
* Returns whether the browser supports the Web Audio API.
*
* @internal
*/
private _isSupported;
/**
* Writes the WAV headers for the specified Float32Array.
*
* Returns a DataView containing the WAV headers and file content.
*
* @internal
*/
private _writeHeaders;
/**
* Converts a Float32Array to 16-bit PCM.
*
* @internal
*/
private _floatTo16BitPCM;
/**
* Writes a string to a DataView at the specified offset.
*
* @internal
*/
private _writeString;
/**
* Converts an AudioBuffer to a Float32Array.
*
* @internal
*/
private _interleave;
/**
* Creates an HTMLAudioElement whose source is the specified Blob.
*
* @internal
*/
private _renderAudioElement;
/**
* Creates an Object URL for the specified Blob.
*
* @internal
*/
private _renderURL;
}
+2
View File
@@ -0,0 +1,2 @@
var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function r(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var r=0;r<t.length;r++){var a=t[r];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,(o=a.key,i=void 0,i=function(e,t){if("object"!==n(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var a=r.call(e,t||"default");if("object"!==n(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(o,"string"),"symbol"===n(i)?i:String(i)),a)}var o,i}e.d(t,{Z:()=>u});var u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.sampleRate;o(this,e),this._context=this._createContext(n),n||(n=this._context.sampleRate),this._sampleRate=n}var t,n,a;return t=e,n=[{key:"_createContext",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:44100;return window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext,new AudioContext({sampleRate:e})}},{key:"context",get:function(){return this._context}},{key:"fetchAudio",value:async function(){for(var e=this,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return await Promise.all(n.map((async function(t){var n;return n=t instanceof File||t instanceof Blob?await t.arrayBuffer():await fetch(t).then((function(e){return e.headers.has("Content-Type")&&!e.headers.get("Content-Type").includes("audio/")&&console.warn("Crunker: Attempted to fetch an audio file, but its MIME type is `".concat(e.headers.get("Content-Type").split(";")[0],"`. We'll try and continue anyway. (file: \"").concat(t,'")')),e.arrayBuffer()})),await e._context.decodeAudioData(n)})))}},{key:"mergeAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._sampleRate*this._maxDuration(e),this._sampleRate);return e.forEach((function(e){for(var n=0;n<e.numberOfChannels;n++){for(var r=t.getChannelData(n),a=e.getChannelData(n),o=e.getChannelData(n).length-1;o>=0;o--)r[o]+=a[o];t.getChannelData(n).set(r)}})),t}},{key:"concatAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._totalLength(e),this._sampleRate),n=0;return e.forEach((function(e){for(var r=0;r<e.numberOfChannels;r++)t.getChannelData(r).set(e.getChannelData(r),n);n+=e.length})),t}},{key:"padAudio",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(0===n)return e;if(t<0)throw new Error('Crunker: Parameter "padStart" in padAudio must be positive');if(n<0)throw new Error('Crunker: Parameter "seconds" in padAudio must be positive');for(var r=this._context.createBuffer(e.numberOfChannels,Math.ceil(e.length+n*e.sampleRate),e.sampleRate),a=0;a<e.numberOfChannels;a++){var o=e.getChannelData(a);r.getChannelData(a).set(o.subarray(0,Math.ceil(t*e.sampleRate)+1),0),r.getChannelData(a).set(o.subarray(Math.ceil(t*e.sampleRate)+2,r.length+1),Math.ceil((t+n)*e.sampleRate))}return r}},{key:"sliceAudio",value:function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(t>=n)throw new Error('Crunker: "start" time should be less than "end" time in sliceAudio method');for(var o=Math.round((n-t)*this._sampleRate),i=Math.round(t*this._sampleRate),u=this._context.createBuffer(e.numberOfChannels,o,this._sampleRate),l=0;l<e.numberOfChannels;l++)for(var s=e.getChannelData(l),c=u.getChannelData(l),f=0;f<o;f++)c[f]=s[i+f],f<r*this._sampleRate&&(c[f]*=f/(r*this._sampleRate)),f>o-a*this._sampleRate&&(c[f]*=(o-f)/(a*this._sampleRate));return u}},{key:"play",value:function(e){var t=this._context.createBufferSource();return t.buffer=e,t.connect(this._context.destination),t.start(),Line truncated
//# sourceMappingURL=crunker.esm.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"crunker.esm.js","mappings":"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 truncated
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+4
View File
@@ -0,0 +1,4 @@
/*! howler.js v2.2.4 | (c) 2013-2020, James Simpson of GoldFire Studios | MIT License | howlerjs.com */
!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._html5AudioPool=[],e.html5PoolSize=10,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.autoUnlock=!0,e._setup(),e},volume:function(e){var o=this||n;if(e=parseFloat(e),o.ctx||_(),void 0!==e&&e>=0&&e<=1){if(o._volume=e,o._muted)return o;o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.volume=u._volume*e)}return o}return o._volume},mute:function(e){var o=this||n;o.ctx||_(),o._muted=e,o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e?0:o._volume,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.muted=!!e||u._muted)}return o},stop:function(){for(var e=this||n,o=0;o<e._howls.length;o++)e._howls[o].stop();return e},unload:function(){for(var e=this||n,o=e._howls.length-1;o>=0;o--)e._howls[o].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"suspended":"suspended",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var o=new Audio;void 0===o.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var o=new Audio;o.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,o=null;try{o="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!o||"function"!=typeof o.canPlayType)return e;var t=o.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator?e._navigator.userAgent:"",a=r.match(/OPR\/(\d+)/g),u=a&&parseInt(a[0].split("/")[1],10)<33,d=-1!==r.indexOf("Safari")&&-1===r.indexOf("Chrome"),i=r.match(/Version\/(.*?) /),_=d&&i&&parseInt(i[1],10)<15;return e._codecs={mp3:!(u||!t&&!o.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!t,opus:!!o.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!(o.canPlayType('audio/wav; codecs="1"')||o.canPlayType("audio/wav")).replace(/^no$/,""),aac:!!o.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!o.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(o.canPlayType("audio/x-m4a;")||o.canPlayType("audio/m4a;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),m4b:!!(o.canPlayType("audio/x-m4b;")||o.canPlayType("audio/m4b;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(o.canPlayType("audio/x-mp4;")||o.canPlayType("audio/mp4;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),webm:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),dolby:!!o.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(o.canPlayType("audio/x-flac;")||o.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_unlockAudio:function(){var e=this||n;if(!e._audioUnlocked&&e.ctx){e._audioUnlocked=!1,e.autoUnlock=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var o=function(n){for(;e._html5AudioPool.length<e.html5PoolSize;)try{var t=new Audio;t._unlocked=!0,e._releaseHtml5Audio(t)}catch(n){e.noAudio=!0;break}for(var r=0;r<e._howls.length;r++)if(!e._howls[r]._webAudio)for(var a=e._howls[r]._getSoundIds(),u=0;u<a.length;u++){var d=e._howls[r]._soundById(a[u]);d&&d._node&&!d._node._unlocked&&(d._node._unlocked=!0,d._node.load())}e._autoResume();var i=e.ctx.createBufferSource();i.buffer=e._scratchBuffer,i.connect(e.ctx.destination),void 0===i.start?i.noteOn(0):i.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),i.onended=function(){i.disconnect(0),e._audioUnlocked=!0,document.removeEventListener("touchstart",o,!0),document.removeEventListener("touchend",o,!0),document.removeEventListener("click",o,!0),document.removeEventListener("keydown",o,!0);for(var n=0;n<e._howls.length;n++)e._howls[n]._emit("unlock")}};return document.addEventListener("touchstart",o,!0),document.addEventListener("touchend",o,!0),document.addEventListener("click",o,!0),document.addEventListener("keydown",o,!0),e}},_obtainHtml5Audio:function(){var e=this||n;if(e._html5AudioPool.length)return e._html5AudioPool.pop();var o=(new Audio).play();return o&&"undefined"!=typeof Promise&&(o instanceof Promise||"function"==typeof o.then)&&o.catch(function(){console.warn("HTML5 Audio pool eLine truncated
/*! Spatial Plugin */
!function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(e){var n=this;if(!n.ctx||!n.ctx.listener)return n;for(var t=n._howls.length-1;t>=0;t--)n._howls[t].stereo(e);return n},HowlerGlobal.prototype.pos=function(e,n,t){var r=this;return r.ctx&&r.ctx.listener?(n="number"!=typeof n?r._pos[1]:n,t="number"!=typeof t?r._pos[2]:t,"number"!=typeof e?r._pos:(r._pos=[e,n,t],void 0!==r.ctx.listener.positionX?(r.ctx.listener.positionX.setTargetAtTime(r._pos[0],Howler.ctx.currentTime,.1),r.ctx.listener.positionY.setTargetAtTime(r._pos[1],Howler.ctx.currentTime,.1),r.ctx.listener.positionZ.setTargetAtTime(r._pos[2],Howler.ctx.currentTime,.1)):r.ctx.listener.setPosition(r._pos[0],r._pos[1],r._pos[2]),r)):r},HowlerGlobal.prototype.orientation=function(e,n,t,r,o,i){var a=this;if(!a.ctx||!a.ctx.listener)return a;var p=a._orientation;return n="number"!=typeof n?p[1]:n,t="number"!=typeof t?p[2]:t,r="number"!=typeof r?p[3]:r,o="number"!=typeof o?p[4]:o,i="number"!=typeof i?p[5]:i,"number"!=typeof e?p:(a._orientation=[e,n,t,r,o,i],void 0!==a.ctx.listener.forwardX?(a.ctx.listener.forwardX.setTargetAtTime(e,Howler.ctx.currentTime,.1),a.ctx.listener.forwardY.setTargetAtTime(n,Howler.ctx.currentTime,.1),a.ctx.listener.forwardZ.setTargetAtTime(t,Howler.ctx.currentTime,.1),a.ctx.listener.upX.setTargetAtTime(r,Howler.ctx.currentTime,.1),a.ctx.listener.upY.setTargetAtTime(o,Howler.ctx.currentTime,.1),a.ctx.listener.upZ.setTargetAtTime(i,Howler.ctx.currentTime,.1)):a.ctx.listener.setOrientation(e,n,t,r,o,i),a)},Howl.prototype.init=function(e){return function(n){var t=this;return t._orientation=n.orientation||[1,0,0],t._stereo=n.stereo||null,t._pos=n.pos||null,t._pannerAttr={coneInnerAngle:void 0!==n.coneInnerAngle?n.coneInnerAngle:360,coneOuterAngle:void 0!==n.coneOuterAngle?n.coneOuterAngle:360,coneOuterGain:void 0!==n.coneOuterGain?n.coneOuterGain:0,distanceModel:void 0!==n.distanceModel?n.distanceModel:"inverse",maxDistance:void 0!==n.maxDistance?n.maxDistance:1e4,panningModel:void 0!==n.panningModel?n.panningModel:"HRTF",refDistance:void 0!==n.refDistance?n.refDistance:1,rolloffFactor:void 0!==n.rolloffFactor?n.rolloffFactor:1},t._onstereo=n.onstereo?[{fn:n.onstereo}]:[],t._onpos=n.onpos?[{fn:n.onpos}]:[],t._onorientation=n.onorientation?[{fn:n.onorientation}]:[],e.call(this,n)}}(Howl.prototype.init),Howl.prototype.stereo=function(n,t){var r=this;if(!r._webAudio)return r;if("loaded"!==r._state)return r._queue.push({event:"stereo",action:function(){r.stereo(n,t)}}),r;var o=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof n)return r._stereo;r._stereo=n,r._pos=[n,0,0]}for(var i=r._getSoundIds(t),a=0;a<i.length;a++){var p=r._soundById(i[a]);if(p){if("number"!=typeof n)return p._stereo;p._stereo=n,p._pos=[n,0,0],p._node&&(p._pannerAttr.panningModel="equalpower",p._panner&&p._panner.pan||e(p,o),"spatial"===o?void 0!==p._panner.positionX?(p._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),p._panner.positionY.setValueAtTime(0,Howler.ctx.currentTime),p._panner.positionZ.setValueAtTime(0,Howler.ctx.currentTime)):p._panner.setPosition(n,0,0):p._panner.pan.setValueAtTime(n,Howler.ctx.currentTime)),r._emit("stereo",p._id)}}return r},Howl.prototype.pos=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"pos",action:function(){i.pos(n,t,r,o)}}),i;if(t="number"!=typeof t?0:t,r="number"!=typeof r?-.5:r,void 0===o){if("number"!=typeof n)return i._pos;i._pos=[n,t,r]}for(var a=i._getSoundIds(o),p=0;p<a.length;p++){var s=i._soundById(a[p]);if(s){if("number"!=typeof n)return s._pos;s._pos=[n,t,r],s._node&&(s._panner&&!s._panner.pan||e(s,"spatial"),void 0!==s._panner.positionX?(s._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),s._panner.positionY.setValueAtTime(t,Howler.ctx.currentTime),s._panner.positionZ.setValueAtTime(r,Howler.ctx.currentTime)):s._panner.setPosition(n,t,r)),i._emit("pos",s._id)}}return i},Howl.prototype.orientation=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"orientation",action:function(){i.orientation(n,t,r,o)}}),i;if(t="number"!=typeof t?i._orientation[1]:t,r="number"!=typeof r?i._orientation[2]:r,void 0===o){if("number"!=typeof n)return i._orientation;i._orientation=[n,t,r]}for(var a=i._getSoundIds(o),p=0;p<a.length;p++){var s=i._soundById(a[p]);if(s){if("number"!=typeof n)return s._orientation;s._orientation=[n,t,r],s._node&&(s._panner||(s._pos||(s._pos=i._pos||[0,0,-.5]),e(s,"spatial")),void 0!==s._panner.orientationX?(s._panner.orientationX.setValueAtTime(n,Howler.ctx.currentTime),s._panner.orientationY.setValueAtTime(t,Howler.ctx.currentTime),s._panner.orientationZ.setValueAtTime(r,Howler.ctx.currentTime)):s._panner.setOrientation(n,t,r)),i._emit("orientation",s._id)}}return i},Howl.prototype.pannerAttr=function(){var n,t,r,o=this,i=arguments;if(!o._webAudioLine truncated
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
import json
import argparse
import soundfile as sf
from pathlib import Path
parser = argparse.ArgumentParser(description="Compare TTS output with the original text using detailed comparison.")
parser.add_argument("--ttslistpath", help="Path to the ttsList.json file")
parser.add_argument("--wavfilespath", help="Path to the wav outputs folder")
args = parser.parse_args()
if not args.ttslistpath:
parser.error("[AllTalk TTSSRT] Please specify the path to the ttslist.json file using the --ttslistpath argument.")
if not args.wavfilespath:
parser.error("[AllTalk TTSSRT] Please specify the path to the wavs output folder file using the --wavfilespath argument.")
json_file_path = Path(args.ttslistpath).resolve()
audio_files_base_path = Path(args.wavfilespath).resolve()
print(f"[AllTalk TTSSRT]")
print("[AllTalk TTSSRT] \033[92mStarting SRT Subtitle generation:\033[0m")
print("[AllTalk TTSSRT]")
print("[AllTalk TTSSRT] \033[94mJSON file :\033[92m", json_file_path, "\033[0m")
print("[AllTalk TTSSRT] \033[94mWAV files :\033[92m", audio_files_base_path, "\033[0m")
print("[AllTalk TTSSRT]")
# Function to convert time in seconds to SRT time format
def format_srt_time(seconds):
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
seconds = seconds % 60
milliseconds = int((seconds - int(seconds)) * 1000)
return f"{hours:02}:{minutes:02}:{int(seconds):02},{milliseconds:03}"
# Load the JSON data
with open(json_file_path, 'r') as json_file:
data = json.load(json_file)
# Initialize start time and SRT lines
start_time = 0.0
srt_lines = []
# Loop through the JSON data to build SRT entries
for entry in data:
file_name = Path(entry['fileUrl']).name # Get the file name from the URL
file_path = audio_files_base_path / file_name
print(f"[AllTalk TTSSRT] Processing file: {file_name}")
if not file_path.exists():
print(f"[AllTalk TTSSRT] Audio file does not exist: {file_path}")
continue
try:
# Use soundfile to read the duration of the WAV file
with sf.SoundFile(str(file_path), 'r') as f:
duration = len(f) / f.samplerate
end_time = start_time + duration
# Format the SRT entry
start_timestamp = format_srt_time(start_time)
end_timestamp = format_srt_time(end_time)
srt_lines.append(f"{len(srt_lines)+1}\n{start_timestamp} --> {end_timestamp}\n{entry['text']}\n")
# Update the start time for the next entry
start_time = end_time
except RuntimeError as e:
print(f"[AllTalk TTSSRT] Error reading {file_path}: {e}")
# Join all SRT lines into the final SRT content
srt_content = "\n".join(srt_lines)
# Save the SRT content to a file
srt_file_path = audio_files_base_path / "subtitles.srt"
with open(srt_file_path, "w") as srt_file:
srt_file.write(srt_content)
print("[AllTalk TTSSRT]")
print(f"[AllTalk TTSSRT] \033[94mSRT file created at \033[0m{srt_file_path}")
@@ -0,0 +1,2 @@
/*! For license information please see 1995fcd6d39cade7d871.js.LICENSE.txt */
function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}function _regeneratorRuntime(){"use strict";_regeneratorRuntime=function(){return e};var t,e={},r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(t,e,r){t[e]=r.value},i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",c=i.asyncIterator||"@@asyncIterator",u=i.toStringTag||"@@toStringTag";function l(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,r){return t[e]=r}}function f(t,e,r,n){var i=e&&e.prototype instanceof m?e:m,a=Object.create(i.prototype),c=new G(n||[]);return o(a,"_invoke",{value:S(t,r,c)}),a}function s(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=f;var h="suspendedStart",p="suspendedYield",y="executing",d="completed",v={};function m(){}function g(){}function w(){}var x={};l(x,a,(function(){return this}));var E=Object.getPrototypeOf,b=E&&E(E(B([])));b&&b!==r&&n.call(b,a)&&(x=b);var T=w.prototype=m.prototype=Object.create(x);function _(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function L(t,e){function r(o,i,a,c){var u=s(t[o],t,i);if("throw"!==u.type){var l=u.arg,f=l.value;return f&&"object"==_typeof(f)&&n.call(f,"__await")?e.resolve(f.__await).then((function(t){r("next",t,a,c)}),(function(t){r("throw",t,a,c)})):e.resolve(f).then((function(t){l.value=t,a(l)}),(function(t){return r("throw",t,a,c)}))}c(u.arg)}var i;o(this,"_invoke",{value:function(t,n){function o(){return new e((function(e,o){r(t,n,e,o)}))}return i=i?i.then(o,o):o()}})}function S(e,r,n){var o=h;return function(i,a){if(o===y)throw new Error("Generator is already running");if(o===d){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var c=n.delegate;if(c){var u=I(c,n);if(u){if(u===v)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===h)throw o=d,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=y;var l=s(e,r,n);if("normal"===l.type){if(o=n.done?d:p,l.arg===v)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o=d,n.method="throw",n.arg=l.arg)}}}function I(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,I(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),v;var i=s(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,v;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,v):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,v)}function O(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function j(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function G(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(O,this),this.reset(!0)}function B(e){if(e||""===e){var r=e[a];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,i=function r(){for(;++o<e.length;)if(n.call(e,o))return r.value=e[o],r.done=!1,r;return r.value=t,r.done=!0,r};return i.next=i}}throw new TypeError(_typeof(e)+" is not iterable")}return g.prototype=w,o(T,"constructor",{value:w,configurable:!0}),o(w,"constructor",{value:g,configurable:!0}),g.displayName=l(w,u,"GeneratorFunction"),e.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===g||"GeneratorFunction"===(e.displayName||e.name))},e.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,w):(t.__proto__=w,l(t,u,"GeneratorFunction")),t.prototype=Object.create(T),t},e.awrap=function(t){return{__await:t}},_(L.prototype),l(L.prototype,c,(function(){return this})),e.AsyncIterator=L,e.async=function(t,r,n,o,i){void 0===i&&(i=Promise);var a=new L(f(t,r,n,o),i);return e.isGeneratorFunction(r)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},_(T),l(T,u,"Generator"),l(T,a,(function(){return this})),l(T,"toString",(function(){return"[object Generator]"})),e.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},e.values=B,G.prototype={constructor:G,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(j),!e)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=t)},stop:function(){this.done=!0;var t=this.tryELine truncated
@@ -0,0 +1 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
@@ -0,0 +1,80 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
* See LICENSE in the project root for license information.
*/
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
ul {
margin: 0;
padding: 0;
}
.ms-welcome__header {
padding: 20px;
padding-bottom: 30px;
padding-top: 100px;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
align-items: center;
}
.ms-welcome__main {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-align-items: center;
align-items: center;
-webkit-flex: 1 0 0;
flex: 1 0 0;
padding: 10px 20px;
}
.ms-welcome__main > h2 {
width: 100%;
text-align: center;
}
.ms-welcome__features {
list-style-type: none;
margin-top: 20px;
}
.ms-welcome__features.ms-List .ms-ListItem {
padding-bottom: 20px;
display: -webkit-flex;
display: flex;
}
.ms-welcome__features.ms-List .ms-ListItem > .ms-Icon {
margin-right: 10px;
}
.ms-welcome__action.ms-Button--hero {
margin-top: 30px;
}
.ms-Button.ms-Button--hero .ms-Button-label {
color: #0078d7;
}
.ms-Button.ms-Button--hero:hover .ms-Button-label,
.ms-Button.ms-Button--hero:focus .ms-Button-label{
color: #005a9e;
cursor: pointer;
}
b {
font-weight: bold;
}
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

+1
View File
@@ -0,0 +1 @@
<!doctype html><html><head><meta charset="UTF-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script><script defer="defer" src="polyfill.js"></script><script defer="defer" src="commands.js"></script></head><body></body></html>
+2
View File
@@ -0,0 +1,2 @@
!function(){var e={};e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),Office.onReady((function(){})),("undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==e.g?e.g:void 0).action=function(e){var n={type:Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,message:"Performed action.",icon:"Icon.80x80",persistent:!0};Office.context.mailbox.item.notificationMessages.replaceAsync("action",n),e.completed()}}();
//# sourceMappingURL=commands.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"commands.js","mappings":"YACA,IAAIA,EAAsB,CAAC,ECD3BA,EAAoBC,EAAI,WACvB,GAA0B,iBAAfC,WAAyB,OAAOA,WAC3C,IACC,OAAOC,MAAQ,IAAIC,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAXC,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCOxBC,OAAOC,SAAQ,WACb,KAuBuB,oBAATC,KACVA,KACkB,oBAAXH,OACPA,YACkB,IAAXI,EAAAA,EACPA,EAAAA,OACAC,GAMJC,OA5BF,SAAgBC,GACd,IAAMC,EAAU,CACdC,KAAMR,OAAOS,aAAaC,4BAA4BC,qBACtDJ,QAAS,oBACTK,KAAM,aACNC,YAAY,GAIdb,OAAOc,QAAQC,QAAQC,KAAKC,qBAAqBC,aAAa,SAAUX,GAGxED,EAAMa,WACR,C","sources":["webpack://office-addin-taskpane-js/webpack/bootstrap","webpack://office-addin-taskpane-js/webpack/runtime/global","webpack://office-addin-taskpane-js/./src/commands/commands.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","/*\n * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n * See LICENSE in the project root for license information.\n */\n\n/* global global, Office, self, window */\n\nOffice.onReady(() => {\n // If needed, Office.js is ready to be called\n});\n\n/**\n * Shows a notification when the add-in command is executed.\n * @param event {Office.AddinCommands.Event}\n */\nfunction action(event) {\n const message = {\n type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,\n message: \"Performed action.\",\n icon: \"Icon.80x80\",\n persistent: true,\n };\n\n // Show a notification message\n Office.context.mailbox.item.notificationMessages.replaceAsync(\"action\", message);\n\n // Be sure to indicate when the add-in command function is complete\n event.completed();\n}\n\nfunction getGlobal() {\n return typeof self !== \"undefined\"\n ? self\n : typeof window !== \"undefined\"\n ? window\n : typeof global !== \"undefined\"\n ? global\n : undefined;\n}\n\nconst g = getGlobal();\n\n// The add-in command functions need to be available in global scope\ng.action = action;\n"],"names":["__webpack_require__","g","globalThis","this","Function","e","window","Office","onReady","self","global","undefined","action","event","message","type","MailboxEnums","ItemNotificationMessageType","InformationalMessage","icon","persistent","context","mailbox","item","notificationMessages","replaceAsync","completed"],"sourceRoot":""}
+79
View File
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<Id>68b6ad53-4f72-42a8-a971-a9643c2f409a</Id>
<Version>1.0.0.0</Version>
<ProviderName>AllTalk</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<DisplayName DefaultValue="AllTalk TTS"/>
<Description DefaultValue="Enhance your document creation with AllTalk TTS's advanced text-to-voice functionality. Requires connection to AllTalk server."/>
<IconUrl DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-32.png"/>
<HighResolutionIconUrl DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-64.png"/>
<SupportUrl DefaultValue="https://github.com/erew123/alltalk_tts/issues"/>
<AppDomains>
<AppDomain>https://www.contoso.com</AppDomain>
</AppDomains>
<Hosts>
<Host Name="Document"/>
</Hosts>
<DefaultSettings>
<SourceLocation DefaultValue="http://127.0.0.1:7851/api/word_addin/taskpane.html"/>
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
<Hosts>
<Host xsi:type="Document">
<DesktopFormFactor>
<!-- You can add GetStarted information here if needed -->
<FunctionFile resid="Commands.Url"/>
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<OfficeTab id="TabHome">
<Group id="AllTalkGroup">
<Label resid="AllTalkGroup.Label"/>
<Icon>
<bt:Image size="16" resid="Icon.16x16"/>
<bt:Image size="32" resid="Icon.32x32"/>
<bt:Image size="80" resid="Icon.80x80"/>
</Icon>
<Control xsi:type="Button" id="AllTalkTaskpaneButton">
<Label resid="AllTalkTaskpaneButton.Label"/>
<Supertip>
<Title resid="AllTalkTaskpaneButton.Label"/>
<Description resid="AllTalkTaskpaneButton.Tooltip"/>
</Supertip>
<Icon>
<bt:Image size="16" resid="Icon.16x16"/>
<bt:Image size="32" resid="Icon.32x32"/>
<bt:Image size="80" resid="Icon.80x80"/>
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>ButtonId1</TaskpaneId>
<SourceLocation resid="Taskpane.Url"/>
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
</Hosts>
<Resources>
<bt:Images>
<bt:Image id="Icon.16x16" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-16.png"/>
<bt:Image id="Icon.32x32" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-32.png"/>
<bt:Image id="Icon.80x80" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-80.png"/>
</bt:Images>
<bt:Urls>
<!-- Ensure that these URLs are pointing to valid locations -->
<bt:Url id="Commands.Url" DefaultValue="http://127.0.0.1:7851/api/word_addin/commands.html"/>
<bt:Url id="Taskpane.Url" DefaultValue="http://127.0.0.1:7851/api/word_addin/taskpane.html"/>
</bt:Urls>
<bt:ShortStrings>
<bt:String id="AllTalkGroup.Label" DefaultValue="AllTalk Controls"/>
<bt:String id="AllTalkTaskpaneButton.Label" DefaultValue="Open AllTalk"/>
</bt:ShortStrings>
<bt:LongStrings>
<bt:String id="AllTalkTaskpaneButton.Tooltip" DefaultValue="Open the AllTalk task pane to start using the add-in."/>
</bt:LongStrings>
</Resources>
</VersionOverrides>
</OfficeApp>
+2
View File
@@ -0,0 +1,2 @@
!function(){var t={35666:function(t){var r=function(t){"use strict";var r,e=Object.prototype,n=e.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value},o="function"==typeof Symbol?Symbol:{},u=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function s(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{s({},"")}catch(t){s=function(t,r,e){return t[r]=e}}function f(t,r,e,n){var o=r&&r.prototype instanceof y?r:y,u=Object.create(o.prototype),a=new j(n||[]);return i(u,"_invoke",{value:R(t,e,a)}),u}function l(t,r,e){try{return{type:"normal",arg:t.call(r,e)}}catch(t){return{type:"throw",arg:t}}}t.wrap=f;var h="suspendedStart",p="suspendedYield",v="executing",g="completed",d={};function y(){}function m(){}function b(){}var x={};s(x,u,(function(){return this}));var w=Object.getPrototypeOf,E=w&&w(w(P([])));E&&E!==e&&n.call(E,u)&&(x=E);var S=b.prototype=y.prototype=Object.create(x);function A(t){["next","throw","return"].forEach((function(r){s(t,r,(function(t){return this._invoke(r,t)}))}))}function O(t,r){function e(i,o,u,a){var c=l(t[i],t,o);if("throw"!==c.type){var s=c.arg,f=s.value;return f&&"object"==typeof f&&n.call(f,"__await")?r.resolve(f.__await).then((function(t){e("next",t,u,a)}),(function(t){e("throw",t,u,a)})):r.resolve(f).then((function(t){s.value=t,u(s)}),(function(t){return e("throw",t,u,a)}))}a(c.arg)}var o;i(this,"_invoke",{value:function(t,n){function i(){return new r((function(r,i){e(t,n,r,i)}))}return o=o?o.then(i,i):i()}})}function R(t,r,e){var n=h;return function(i,o){if(n===v)throw new Error("Generator is already running");if(n===g){if("throw"===i)throw o;return k()}for(e.method=i,e.arg=o;;){var u=e.delegate;if(u){var a=T(u,e);if(a){if(a===d)continue;return a}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if(n===h)throw n=g,e.arg;e.dispatchException(e.arg)}else"return"===e.method&&e.abrupt("return",e.arg);n=v;var c=l(t,r,e);if("normal"===c.type){if(n=e.done?g:p,c.arg===d)continue;return{value:c.arg,done:e.done}}"throw"===c.type&&(n=g,e.method="throw",e.arg=c.arg)}}}function T(t,e){var n=e.method,i=t.iterator[n];if(i===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,T(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),d;var o=l(i,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,d;var u=o.arg;return u?u.done?(e[t.resultName]=u.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,d):u:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,d)}function I(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r)}function M(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r}function j(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(I,this),this.reset(!0)}function P(t){if(t){var e=t[u];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var i=-1,o=function e(){for(;++i<t.length;)if(n.call(t,i))return e.value=t[i],e.done=!1,e;return e.value=r,e.done=!0,e};return o.next=o}}return{next:k}}function k(){return{value:r,done:!0}}return m.prototype=b,i(S,"constructor",{value:b,configurable:!0}),i(b,"constructor",{value:m,configurable:!0}),m.displayName=s(b,c,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return!!r&&(r===m||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,b):(t.__proto__=b,s(t,c,"GeneratorFunction")),t.prototype=Object.create(S),t},t.awrap=function(t){return{__await:t}},A(O.prototype),s(O.prototype,a,(function(){return this})),t.AsyncIterator=O,t.async=function(r,e,n,i,o){void 0===o&&(o=Promise);var u=new O(f(r,e,n,i),o);return t.isGeneratorFunction(e)?u:u.next().then((function(t){return t.done?t.value:u.next()}))},A(S),s(S,c,"Generator"),s(S,u,(function(){return this})),s(S,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=P,j.prototype={constructor:j,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(M),!t)for(var e in this)"t"===e.charAt(0)&&n.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=r)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function i(n,i){return a.type="throw",a.arg=t,e.next=n,i&&(e.method="next",e.arg=r),!!i}for(var o=this.tryEntries.length-1;o>=0;--o){var u=this.tryEntries[o],aLine truncated
//# sourceMappingURL=polyfill.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"polyfill.js","mappings":"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 truncated
+106
View File
@@ -0,0 +1,106 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>AllTalk TTS Add-in</title>
<script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
<link rel="stylesheet"
href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/11.0.0/css/fabric.min.css" />
<link href="1fda685b81e1123773f6.css" rel="stylesheet" />
<style>
label {
font-weight: 700;
display: block;
margin-top: 10px
}
select {
width: 100%;
padding: 5px
}
.nice-button {
background-color: #0078d4;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: background-color .3s ease
}
.nice-button:hover {
background-color: #005a9e
}
#audioSource {
width: 300px;
height: 50px
}
.input-container {
display: flex;
flex-direction: column;
margin-right: 10px
}
.input-group {
display: flex;
justify-content: start;
align-items: flex-end
}
.input-group>.input-container {
flex: 1
}
input {
width: 100%
}
</style>
<script defer="defer" src="polyfill.js"></script>
<script defer="defer" src="taskpane.js"></script>
</head>
<body class="ms-font-m ms-welcome ms-Fabric">
<header class="ms-welcome__header ms-bgColor-neutralLighter"><img width="90" height="90"
src="http://127.0.0.1:7851/api/word_addin/assets/logo-filled.png" alt="AllTalk TTS" title="AllTalk TTS" />
<h1 class="ms-font-su">AllTalk TTS</h1>
</header>
<main class="ms-welcome__main"><textarea id="text" rows="4" placeholder="Enter text here"
style="display:none"></textarea> <label for="voice">Voice:</label> <select id="voice" name="voice"
required></select> <label for="language">Language:</label> <select id="language" name="language"
value="English" required>
<option value="en" selected="selected">English</option>
<option value="ar">Arabic</option>
<option value="zh-cn">Chinese</option>
<option value="cs">Czech</option>
<option value="nl">Dutch</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="hu">Hungarian</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ru">Russian</option>
<option value="es">Spanish</option>
<option value="tr">Turkish</option>
</select><br><audio id="audioSource" controls autoplay></audio><br><button id="sendTextButton"
class="nice-button">Send Text to TTS</button><br><br><br><br>
<div class="input-group">
<div class="input-container"><label for="serverIP">Server IP:</label> <input id="serverIP" name="serverIP"
value="127.0.0.1" required></div>
<div class="input-container"><label for="portNumber">Port Number:</label> <input type="number"
id="portNumber" name="portNumber" value="7851" required></div>
</div>
</main>
<script src="1995fcd6d39cade7d871.js"></script>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
/*! For license information please see taskpane.js.LICENSE.txt */
!function(){var t={27091:function(t){"use strict";t.exports=function(t,e){return e||(e={}),t?(t=String(t.__esModule?t.default:t),e.hash&&(t+=e.hash),e.maybeNeedQuotes&&/[\t\n\f\r "'=<>`]/.test(t)?'"'.concat(t,'"'):t):t}},44944:function(t,e,r){"use strict";t.exports=r.p+"assets/logo-filled.png"},36076:function(t,e,r){"use strict";t.exports=r.p+"1995fcd6d39cade7d871.js"},60806:function(t,e,r){"use strict";t.exports=r.p+"1fda685b81e1123773f6.css"}},e={};function r(n){var o=e[n];if(void 0!==o)return o.exports;var i=e[n]={exports:{}};return t[n](i,i.exports,r),i.exports}r.m=t,r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,{a:e}),e},r.d=function(t,e){for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},function(){var t;r.g.importScripts&&(t=r.g.location+"");var e=r.g.document;if(!t&&e&&(e.currentScript&&(t=e.currentScript.src),!t)){var n=e.getElementsByTagName("script");if(n.length)for(var o=n.length-1;o>-1&&!t;)t=n[o--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r.p=t}(),r.b=document.baseURI||self.location.href,function(){function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(){"use strict";e=function(){return n};var r,n={},o=Object.prototype,i=o.hasOwnProperty,c=Object.defineProperty||function(t,e,r){t[e]=r.value},a="function"==typeof Symbol?Symbol:{},u=a.iterator||"@@iterator",f=a.asyncIterator||"@@asyncIterator",s=a.toStringTag||"@@toStringTag";function l(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(r){l=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=e&&e.prototype instanceof w?e:w,i=Object.create(o.prototype),a=new k(n||[]);return c(i,"_invoke",{value:I(t,r,a)}),i}function p(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}n.wrap=h;var y="suspendedStart",v="suspendedYield",d="executing",m="completed",g={};function w(){}function b(){}function x(){}var E={};l(E,u,(function(){return this}));var L=Object.getPrototypeOf,_=L&&L(L(T([])));_&&_!==o&&i.call(_,u)&&(E=_);var j=x.prototype=w.prototype=Object.create(E);function O(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function S(e,r){function n(o,c,a,u){var f=p(e[o],e,c);if("throw"!==f.type){var s=f.arg,l=s.value;return l&&"object"==t(l)&&i.call(l,"__await")?r.resolve(l.__await).then((function(t){n("next",t,a,u)}),(function(t){n("throw",t,a,u)})):r.resolve(l).then((function(t){s.value=t,a(s)}),(function(t){return n("throw",t,a,u)}))}u(f.arg)}var o;c(this,"_invoke",{value:function(t,e){function i(){return new r((function(r,o){n(t,e,r,o)}))}return o=o?o.then(i,i):i()}})}function I(t,e,n){var o=y;return function(i,c){if(o===d)throw new Error("Generator is already running");if(o===m){if("throw"===i)throw c;return{value:r,done:!0}}for(n.method=i,n.arg=c;;){var a=n.delegate;if(a){var u=P(a,n);if(u){if(u===g)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===y)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var f=p(t,e,n);if("normal"===f.type){if(o=n.done?m:v,f.arg===g)continue;return{value:f.arg,done:n.done}}"throw"===f.type&&(o=m,n.method="throw",n.arg=f.arg)}}}function P(t,e){var n=e.method,o=t.iterator[n];if(o===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,P(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),g;var i=p(o,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,g;var c=i.arg;return c?c.done?(e[t.resultName]=c.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,g):c:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,g)}function B(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function N(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function k(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(B,this),this.reset(!0)}function T(e){if(e||""===e){var n=e[u];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,c=function t(){for(;++o<e.length;)if(i.call(e,o))return t.value=e[o],t.done=!1,t;return t.value=r,t.done=!0,t};return c.next=c}}throw new TLine truncated
//# sourceMappingURL=taskpane.js.map
@@ -0,0 +1 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"taskpane.js","mappings":"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 truncated
+634 -727
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.
+3 -1
View File
@@ -9,4 +9,6 @@ Author BBC
This file is licensed under the Creative Commons Attribution 3.0 Unported license.
https://creativecommons.org/licenses/by/3.0/deed.en
Downsampled to 22050hz, mono and cut shorter
Downsampled to 22050hz, mono and cut shorter.
This license applies to both the original file ( «Clint_Eastwood CC3.wav» ) and it's derivative, the enhanced file ( «Clint_Eastwood (enhanced)CC3.wav» ).