Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bb0d1fa58 | ||
|
|
015b9033ec | ||
|
|
7f261bb5e9 | ||
|
|
00b93cfe1b | ||
|
|
c0d01ee931 | ||
|
|
d0ceb2bb65 | ||
|
|
3231e61d56 | ||
|
|
32f3b721c2 | ||
|
|
8c588939d2 | ||
|
|
ff1077f282 | ||
|
|
36d0e92ed9 | ||
|
|
8dfb84d7e2 | ||
|
|
4caecdc5eb | ||
|
|
40f2fbf54e | ||
|
|
ab37dd8849 | ||
|
|
03b02e0e4c | ||
|
|
351f46c7b5 | ||
|
|
71ba584e7c | ||
|
|
b3f53e93cc | ||
|
|
0ed3cb75b5 | ||
|
|
c29de18ad4 | ||
|
|
ec1d0e8c5d | ||
|
|
12bf008b3f | ||
|
|
ecdc10ece5 | ||
|
|
360f70cb0a | ||
|
|
51c91c3d70 | ||
|
|
81a9f4c847 | ||
|
|
cdce7511dc | ||
|
|
6d4b6d336b | ||
|
|
6c4a9b19c7 | ||
|
|
82ecf3eecc | ||
|
|
d750959f52 | ||
|
|
bd74de53da | ||
|
|
fcec9d8f5b | ||
|
|
85e5e6ab86 | ||
|
|
d15931bdda | ||
|
|
abc9cf1fb7 | ||
|
|
2b60f5b0da | ||
|
|
e524063ec2 | ||
|
|
d93906a75f | ||
|
|
ad57deed20 | ||
|
|
d0866e3c6c | ||
|
|
af907a299d | ||
|
|
7928af1bb7 | ||
|
|
4d837a0219 | ||
|
|
e50817a234 | ||
|
|
c3bb58d2af | ||
|
|
c17959f142 | ||
|
|
def2d51c5f | ||
|
|
6166d4f751 | ||
|
|
cd164ae258 | ||
|
|
f089e3e85b | ||
|
|
d008c7ab0a | ||
|
|
a199adfbd6 | ||
|
|
61998b4d39 | ||
|
|
55799b2de8 | ||
|
|
ece55ffe06 | ||
|
|
dbc2582fa6 | ||
|
|
535c9b652a | ||
|
|
6c28d58b4a | ||
|
|
c9a222932c | ||
|
|
7010369966 | ||
|
|
525a337835 | ||
|
|
2bd1ef843e | ||
|
|
a9d95fc563 | ||
|
|
1a37ae4ba5 | ||
|
|
8c6fc4853d | ||
|
|
f34ebbd675 | ||
|
|
64cffcdf80 | ||
|
|
2731a559f4 | ||
|
|
a91a83268f | ||
|
|
5d406fbbfb | ||
|
|
cefd1e045b | ||
|
|
bec4e905d3 | ||
|
|
f5e99a5e72 | ||
|
|
631ea6dd8a | ||
|
|
08a04ba506 | ||
|
|
c78927b80a | ||
|
|
04e08c58b8 | ||
|
|
893747c9a9 | ||
|
|
d52dcf86d5 | ||
|
|
ad0eab1224 | ||
|
|
62d1cc05d3 | ||
|
|
b8292da92f | ||
|
|
180adb45dd | ||
|
|
5c0f08d49e | ||
|
|
571872dbe2 | ||
|
|
467bfbea55 | ||
|
|
5a3cbb6366 | ||
|
|
2351e418fd | ||
|
|
b987ff38a7 | ||
|
|
43899028e3 | ||
|
|
2c1ca8b2a3 | ||
|
|
139162c4e6 | ||
|
|
7da78ec045 | ||
|
|
11c70c7432 | ||
|
|
c2822edb1b | ||
|
|
cba7ed7b88 | ||
|
|
471a26f2a4 | ||
|
|
34d1b81ae4 | ||
|
|
f1b4d4b8b6 | ||
|
|
c05237143b | ||
|
|
c5846b832a | ||
|
|
7a38730c56 | ||
|
|
0b1e6f8711 | ||
|
|
8c38e925dd | ||
|
|
df70481934 | ||
|
|
e43c58a56e | ||
|
|
8dc9304a4c | ||
|
|
102424669b | ||
|
|
5210d075c1 | ||
|
|
30db974439 | ||
|
|
c2a558110b | ||
|
|
83ac18b83f | ||
|
|
6e36415746 | ||
|
|
fe7ffb535c | ||
|
|
80b7fccb50 | ||
|
|
2790ee9860 | ||
|
|
74ce2584cc | ||
|
|
8dd11541b4 | ||
|
|
d1317b49f0 | ||
|
|
a50d5a5028 | ||
|
|
33264554cd | ||
|
|
4a116e359a | ||
|
|
36bfb17eda | ||
|
|
697fb098c3 | ||
|
|
51a8e93df7 | ||
|
|
257fa59e70 | ||
|
|
7dbad85fc3 | ||
|
|
510894c793 | ||
|
|
a85058a3ac | ||
|
|
e54c7e4362 | ||
|
|
1f2ad303a0 | ||
|
|
d4a04096c8 | ||
|
|
dd45008e88 | ||
|
|
e9d9f54de6 | ||
|
|
3230397a82 | ||
|
|
840889ac9a | ||
|
|
d3e061b127 | ||
|
|
a428f67a2e | ||
|
|
b223e7b247 | ||
|
|
9296843508 | ||
|
|
f0c9e3e6bb | ||
|
|
22de1bf0c6 | ||
|
|
621f5434a7 | ||
|
|
81c8354cf8 | ||
|
|
3bc55a91e5 | ||
|
|
fc857f464c | ||
|
|
50aa6de96c | ||
|
|
10299194f8 | ||
|
|
d80d1ace3c | ||
|
|
f19f4e9a29 | ||
|
|
7e4ceef0e8 | ||
|
|
c1bc1f26cd | ||
|
|
70d385133d | ||
|
|
13b2eb5fe3 | ||
|
|
ff4b9d9e99 | ||
|
|
a22830f700 | ||
|
|
374c794fa9 | ||
|
|
d2adbd9c1e | ||
|
|
1dc4b8bf50 | ||
|
|
0eba72fc47 | ||
|
|
f2c87dcdab | ||
|
|
4a727ce14a | ||
|
|
6e15d43e63 | ||
|
|
dedc13b3b6 | ||
|
|
7cb206e531 | ||
|
|
4f80b39cd0 | ||
|
|
d5fa6bb46d | ||
|
|
332582baea | ||
|
|
2bd7ebc514 | ||
|
|
e5acc8bdbd | ||
|
|
7718bfd3ea | ||
|
|
002c5ad9db | ||
|
|
2c14847708 | ||
|
|
3647d69007 | ||
|
|
56a7ea1d8f | ||
|
|
863a7cd841 | ||
|
|
2e1709ab58 | ||
|
|
9c4efdc135 | ||
|
|
28675c976c | ||
|
|
afe3b9fe0b | ||
|
|
2e4d52170d | ||
|
|
0e2cc25571 | ||
|
|
abaa56e8f4 | ||
|
|
d0dc9f3212 | ||
|
|
67dcc411ad | ||
|
|
b11a087dc8 | ||
|
|
e068115eef | ||
|
|
0ec580539a | ||
|
|
e9feae12ad | ||
|
|
e183e3a7bb | ||
|
|
8a2b669da9 | ||
|
|
67d2b1c5ea | ||
|
|
f3b44424ef | ||
|
|
3b5c4b9b68 | ||
|
|
e452a926f2 | ||
|
|
b65291d44d | ||
|
|
b28ecaf43e | ||
|
|
ba1328311c | ||
|
|
9e6b9396bc | ||
|
|
2e40db5fe5 | ||
|
|
720bf8697f | ||
|
|
1893d1a130 | ||
|
|
8472baf031 | ||
|
|
6cab618706 | ||
|
|
ebf3b362f7 | ||
|
|
2dd303f53c | ||
|
|
df69fb0b07 | ||
|
|
a0d9771fa6 | ||
|
|
a71c46bb98 | ||
|
|
995f317b4f | ||
|
|
6ef2de2923 | ||
|
|
37c4e86566 | ||
|
|
11071b279b | ||
|
|
5ab7463f35 | ||
|
|
74c9238e3a | ||
|
|
e874e46304 | ||
|
|
b32df6ac15 | ||
|
|
b76dd3561f | ||
|
|
60bfbdcabd | ||
|
|
c128d0851b | ||
|
|
2f3b7762e4 | ||
|
|
0e594f5098 | ||
|
|
14151d4dda | ||
|
|
94ab21fb15 | ||
|
|
1acac3d6c6 | ||
|
|
95ec2dc9d2 | ||
|
|
6b93eb6c1e | ||
|
|
838578a042 | ||
|
|
2f689f0438 | ||
|
|
022025ded6 | ||
|
|
320a7a6aba | ||
|
|
fa82870883 | ||
|
|
a094d4f9da | ||
|
|
bb028af694 | ||
|
|
aeb225ec7c | ||
|
|
06a632459e | ||
|
|
221efbddb4 | ||
|
|
e81a88938a | ||
|
|
65e257077c | ||
|
|
95659d5b7a | ||
|
|
ff57270286 | ||
|
|
4fc61ba99a | ||
|
|
3cd22081f4 | ||
|
|
d20ee95e67 | ||
|
|
cd47f6b123 | ||
|
|
53a2d0a65e | ||
|
|
13318243e4 | ||
|
|
acc457436a | ||
|
|
8d80151889 | ||
|
|
8b0ade5b9f | ||
|
|
9f033e4654 | ||
|
|
1a2b8571d0 | ||
|
|
9ab20be294 | ||
|
|
a34cbfdd55 | ||
|
|
94f5b781cc | ||
|
|
f83e7c3b4e | ||
|
|
607dc89be5 | ||
|
|
47758c4aeb | ||
|
|
26414d4925 | ||
|
|
7ad92e7f5d | ||
|
|
e775cef5bd | ||
|
|
ac9ce144a0 | ||
|
|
f181c06f89 | ||
|
|
9fae4692e3 | ||
|
|
97f0d6441a | ||
|
|
2ea6cb6304 | ||
|
|
5bed68a963 | ||
|
|
be9862d0b0 | ||
|
|
f5a811f0f8 | ||
|
|
dc9d343115 | ||
|
|
c92aa435e5 | ||
|
|
1f425e6bac | ||
|
|
0854544a47 | ||
|
|
52a7922e98 | ||
|
|
558583b16f | ||
|
|
993d065368 | ||
|
|
d7376fa8ef | ||
|
|
2b175b13c4 | ||
|
|
da0445489e | ||
|
|
e4eaa760b9 | ||
|
|
de4017f385 | ||
|
|
f2119aa0f7 | ||
|
|
bb81f3f874 | ||
|
|
fae15eecb1 | ||
|
|
6edcc2125b | ||
|
|
d26909a1d6 | ||
|
|
3be6b842c4 | ||
|
|
e10dc700c3 | ||
|
|
e8e21f949c | ||
|
|
e68a7d72f2 | ||
|
|
fd26db8e8a | ||
|
|
396f1290e7 | ||
|
|
5bc7dd8692 | ||
|
|
b5b68ad51f | ||
|
|
e49ceed40c | ||
|
|
598aec7f52 | ||
|
|
f25d2627cd | ||
|
|
3e6f1bace3 | ||
|
|
fb851ff3f0 | ||
|
|
92bf8f5de8 | ||
|
|
8f318892c2 | ||
|
|
28a62ed39a | ||
|
|
4c08927ed9 | ||
|
|
a93da39711 | ||
|
|
557f4b80b6 | ||
|
|
c657a2aac6 | ||
|
|
af99748441 | ||
|
|
db87427e7c | ||
|
|
c9b82034f0 | ||
|
|
96aef2c1be | ||
|
|
a3958a6437 | ||
|
|
485aca2e6c | ||
|
|
88d588bb44 | ||
|
|
9cc98c7c31 | ||
|
|
69acc1f74a | ||
|
|
d8be718a30 | ||
|
|
efd3a0add3 | ||
|
|
55ecdfcf1f | ||
|
|
fab8d28802 | ||
|
|
72992729f9 | ||
|
|
7c5d843c61 | ||
|
|
19a66fdba4 | ||
|
|
5c88f43083 | ||
|
|
6ef01a83a8 | ||
|
|
cd2e5396a0 | ||
|
|
7e590d6e69 | ||
|
|
92e360feed | ||
|
|
5015b9e4da | ||
|
|
1131084e2f | ||
|
|
8fab3e8183 | ||
|
|
6f4df9e3b1 | ||
|
|
7223b3bc26 | ||
|
|
48a02da11d | ||
|
|
68acd49234 | ||
|
|
6728a71210 | ||
|
|
d6cfbfcedf | ||
|
|
8644a65e58 | ||
|
|
9306b31c12 | ||
|
|
ff911ee73d | ||
|
|
df89623f06 | ||
|
|
3329257c46 | ||
|
|
e853efbf94 | ||
|
|
4fae216a29 | ||
|
|
99b0a0dc17 | ||
|
|
ecc619e5fe | ||
|
|
17de71e59c | ||
|
|
34621ebabc | ||
|
|
98dae5cff8 | ||
|
|
5b174bab35 | ||
|
|
dbb51bdb41 | ||
|
|
91330111fa | ||
|
|
242ba3dc9f | ||
|
|
aae9568b72 | ||
|
|
9d002de65a | ||
|
|
48ce2421a4 | ||
|
|
2d095063a3 | ||
|
|
dbacc3d352 | ||
|
|
49489bda89 | ||
|
|
5260df4e2d | ||
|
|
a2efb1abd8 | ||
|
|
006b5a7f58 | ||
|
|
5720b56dea | ||
|
|
e0f10db484 | ||
|
|
25b14c9c21 | ||
|
|
e069c33633 | ||
|
|
7dafb0f32a |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
ko_fi: erew123
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: Bug report/Support request
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Please generate a diagnostics report and upload the "diagnostics.log".
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behaviour:
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Text/logs**
|
||||||
|
If applicable, copy/paste in your logs here from the console.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
AllTalk was updated: [approx. date]
|
||||||
|
Custom Python environment: [yes/no give details if yes]
|
||||||
|
Text-generation-webUI was updated: [approx. date]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
@@ -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,160 +1,8 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
voices/*.*
|
||||||
__pycache__/
|
models/*.*
|
||||||
*.py[cod]
|
outputs/*.*
|
||||||
*$py.class
|
finetune/*.*
|
||||||
|
config.json
|
||||||
# C extensions
|
confignew.json
|
||||||
*.so
|
models.json
|
||||||
|
diagnostics.log
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
wheels/
|
|
||||||
share/python-wheels/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.nox/
|
|
||||||
.coverage
|
|
||||||
.coverage.*
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
*.cover
|
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
|
||||||
.pytest_cache/
|
|
||||||
cover/
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
local_settings.py
|
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
|
||||||
instance/
|
|
||||||
.webassets-cache
|
|
||||||
|
|
||||||
# Scrapy stuff:
|
|
||||||
.scrapy
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
.pybuilder/
|
|
||||||
target/
|
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# pyenv
|
|
||||||
# For a library or package, you might want to ignore these files since the code is
|
|
||||||
# intended to run in multiple environments; otherwise, check them in:
|
|
||||||
# .python-version
|
|
||||||
|
|
||||||
# pipenv
|
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
||||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
||||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
||||||
# install all needed dependencies.
|
|
||||||
#Pipfile.lock
|
|
||||||
|
|
||||||
# poetry
|
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
||||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
||||||
# commonly ignored for libraries.
|
|
||||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
||||||
#poetry.lock
|
|
||||||
|
|
||||||
# pdm
|
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
||||||
#pdm.lock
|
|
||||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
||||||
# in version control.
|
|
||||||
# https://pdm.fming.dev/#use-with-ide
|
|
||||||
.pdm.toml
|
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
|
||||||
*.sage.py
|
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
|
||||||
.spyderproject
|
|
||||||
.spyproject
|
|
||||||
|
|
||||||
# Rope project settings
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# mkdocs documentation
|
|
||||||
/site
|
|
||||||
|
|
||||||
# mypy
|
|
||||||
.mypy_cache/
|
|
||||||
.dmypy.json
|
|
||||||
dmypy.json
|
|
||||||
|
|
||||||
# Pyre type checker
|
|
||||||
.pyre/
|
|
||||||
|
|
||||||
# pytype static type analyzer
|
|
||||||
.pytype/
|
|
||||||
|
|
||||||
# Cython debug symbols
|
|
||||||
cython_debug/
|
|
||||||
|
|
||||||
# PyCharm
|
|
||||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
||||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
||||||
#.idea/
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.html": "jinja-html"
|
||||||
|
},
|
||||||
|
"emmet.includeLanguages": {
|
||||||
|
"jinja-html": "html",
|
||||||
|
"jinja2": "html"
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
@@ -0,0 +1,661 @@
|
|||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the work with which it is combined will remain governed by version
|
||||||
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
@@ -0,0 +1,504 @@
|
|||||||
|
@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) Install the requirements for a %L_GREEN%Nvidia machine%RESET%.
|
||||||
|
echo 2) Install the requirements for a %L_GREEN%AMD or MAC machine%RESET%.
|
||||||
|
echo.
|
||||||
|
echo OPTIONAL
|
||||||
|
echo 3) Install the Finetuning requirements.
|
||||||
|
echo 4) Install DeepSpeed v11.2 for CUDA %L_GREEN%11.8%RESET% and Python-3.11.x.
|
||||||
|
echo 5) Install DeepSpeed v11.2 for CUDA %L_GREEN%12.1%RESET% and Python-3.11.x.
|
||||||
|
echo 6) Uninstall DeepSpeed.
|
||||||
|
echo.
|
||||||
|
echo. OTHER
|
||||||
|
echo 7) 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 InstallOtherTextGen
|
||||||
|
if "%WebUIOption%"=="3" goto InstallFinetuneTextGen
|
||||||
|
if "%WebUIOption%"=="4" goto InstallDeepSpeed118TextGen
|
||||||
|
if "%WebUIOption%"=="5" goto InstallDeepSpeed121TextGen
|
||||||
|
if "%WebUIOption%"=="6" goto UnInstallDeepSpeed
|
||||||
|
if "%WebUIOption%"=="7" 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) Delete AllTalk's custom Python environment
|
||||||
|
echo 3) Install the Finetuning requirements
|
||||||
|
echo.
|
||||||
|
echo. OTHER
|
||||||
|
echo 4) 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 DeleteCustomStandalone
|
||||||
|
if "%StandaloneOption%"=="3" goto InstallFinetuneStandalone
|
||||||
|
if "%StandaloneOption%"=="4" goto GenerateDiagsStandalone
|
||||||
|
if "%StandaloneOption%"=="9" goto End
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:InstallNvidiaTextGen
|
||||||
|
pip install -r requirements_nvidia.txt
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error installing the Nvidia requirements.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo Nvidia machine requirements installed successfully.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallOtherTextGen
|
||||||
|
pip install -r requirements_other.txt
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error installing the Other requirements.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo Other machine requirements installed successfully.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallFinetuneTextGen
|
||||||
|
pip install -r requirements_finetune.txt
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error installing the Finetune requirements.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
Echo Finetune requirements installed successfully. Please ensure you have installed CUDA 11.8.
|
||||||
|
Echo Finetune needs access to %L_GREEN%cublas64_11.dll%RESET% and will error if this is not setup correctly.
|
||||||
|
Echo Please see here for details %L_GREEN%https://github.com/erew123/alltalk_tts#-finetuning-a-model%RESET%
|
||||||
|
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
|
||||||
|
|
||||||
|
: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 )
|
||||||
|
|
||||||
|
@rem Ask user for the type of requirements to install
|
||||||
|
echo.
|
||||||
|
echo %L_BLUE%Choose the type of requirements to install%RESET%
|
||||||
|
echo.
|
||||||
|
echo 1. Nvidia graphics card machines
|
||||||
|
echo 2. Other machines (mac, amd, etc)
|
||||||
|
echo.
|
||||||
|
set /p UserChoice="Enter your choice (1 or 2): "
|
||||||
|
|
||||||
|
@rem Install requirements based on user choice
|
||||||
|
if "%UserChoice%" == "1" (
|
||||||
|
echo.
|
||||||
|
echo Installing Nvidia requirements...
|
||||||
|
echo Downloading Pytorch with CUDA..
|
||||||
|
pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --upgrade --force-reinstall --index-url https://download.pytorch.org/whl/cu121
|
||||||
|
pip install numpy==1.24.4
|
||||||
|
pip install typing-extensions>=4.8.0
|
||||||
|
pip install networkx<3.0.0,>=2.5.0
|
||||||
|
pip install fsspec>=2023.6.0
|
||||||
|
pip install soundfile==0.12.1
|
||||||
|
pip install uvicorn==0.24.0.post1
|
||||||
|
pip install transformers>=4.37.1
|
||||||
|
pip install TTS==0.21.3
|
||||||
|
pip install fastapi==0.104.1
|
||||||
|
pip install Jinja2==3.1.2
|
||||||
|
pip install requests==2.31.0
|
||||||
|
pip install tqdm==4.66.1
|
||||||
|
pip install importlib-metadata==4.8.1
|
||||||
|
pip install packaging==23.2
|
||||||
|
pip install pydantic==1.10.13
|
||||||
|
pip install sounddevice==0.4.6
|
||||||
|
pip install python-multipart==0.0.6
|
||||||
|
pip install cutlet>=0.3.0
|
||||||
|
pip install unidic-lite>=1.0.8
|
||||||
|
echo Downloading DeepSpeed...
|
||||||
|
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
|
||||||
|
) else (
|
||||||
|
echo Installing requirements for other machines...
|
||||||
|
pip install -r requirements_other.txt
|
||||||
|
)
|
||||||
|
|
||||||
|
@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
|
||||||
|
Echo.
|
||||||
|
Echo start_alltalk.bat has been created.
|
||||||
|
Echo You can now start AllTalk with %L_YELLOW%start_alltalk.bat%RESET%
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:DeleteCustomStandalone
|
||||||
|
@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
|
||||||
|
|
||||||
|
:InstallFinetuneStandalone
|
||||||
|
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 Proceed with installing requirements
|
||||||
|
pip install -r requirements_finetune.txt
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error installing the Finetune requirements.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
Echo Finetune requirements installed successfully. Please ensure you have installed CUDA 11.8.
|
||||||
|
Echo Finetune needs access to %L_GREEN%cublas64_11.dll%RESET% and will error if this is not setup correctly.
|
||||||
|
Echo Please see here for details %L_GREEN%https://github.com/erew123/alltalk_tts#-finetuning-a-model%RESET%
|
||||||
|
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
|
||||||
|
|
||||||
|
:End
|
||||||
|
echo Exiting AllTalk Setup Utility...
|
||||||
|
exit /b
|
||||||
@@ -0,0 +1,443 @@
|
|||||||
|
#!/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) Install the AllTalk requirements for an ${L_GREEN}Nvidia GPU machine.${NC}"
|
||||||
|
echo -e " 2) Install the AllTalk requirements for an ${L_GREEN}AMD or MAC machine.${NC}"
|
||||||
|
echo
|
||||||
|
echo " OPTIONAL"
|
||||||
|
echo " 3) Install the Finetuning requirements."
|
||||||
|
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) install_other_textgen ;;
|
||||||
|
3) install_finetune_textgen ;;
|
||||||
|
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="requirements_nvidia.txt"
|
||||||
|
echo " Installing Finetune requirements from $requirements_file..."
|
||||||
|
if ! pip install -r "$requirements_file"; then
|
||||||
|
echo " There was an error installing the Nvidia requirements."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo " Nvidia requirements installed successfully."
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
install_other_textgen() {
|
||||||
|
local requirements_file="requirements_other.txt"
|
||||||
|
echo " Installing Other machine requirements from $requirements_file..."
|
||||||
|
if ! pip install -r "$requirements_file"; then
|
||||||
|
echo " There was an error installing the Other requirements."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo " Other machine requirements installed successfully."
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
install_finetune_textgen() {
|
||||||
|
local requirements_file="requirements_finetune.txt"
|
||||||
|
echo " Installing Finetune requirements from $requirements_file..."
|
||||||
|
if ! pip install -r "$requirements_file"; then
|
||||||
|
echo " There was an error installing the Finetune requirements."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " Finetune base requirements installed successfully."
|
||||||
|
echo
|
||||||
|
echo -e " Finetuning requires access to ${GREEN}Cublas${NC} from the ${GREEN}Nvidia CUDA Toolkit${NC}, so will need installing."
|
||||||
|
echo
|
||||||
|
echo -e " Instructions can be found here:"
|
||||||
|
echo -e " ${GREEN}https://github.com/erew123/alltalk_tts?#-finetuning-a-model${NC}"
|
||||||
|
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 " There was an error uninstalling DeepSpeed."
|
||||||
|
echo " Press any key to return to the menu."
|
||||||
|
read -n 1
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo " DeepSpeed uninstalled successfully."
|
||||||
|
echo " Press any key to continue."
|
||||||
|
read -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_diagnostics_textgen() {
|
||||||
|
# Run diagnostics
|
||||||
|
if ! python diagnostics.py; then
|
||||||
|
echo " There was an error running diagnostics."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Diagnostics completed successfully."
|
||||||
|
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) Delete AllTalk's custom Python environment"
|
||||||
|
echo " 3) Install the Finetuning requirements"
|
||||||
|
echo " 4) Install DeepSpeed."
|
||||||
|
echo
|
||||||
|
echo " OTHER"
|
||||||
|
echo " 5) 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) delete_custom_standalone ;;
|
||||||
|
3) install_finetune_standalone ;;
|
||||||
|
4) install_deepspeed ;;
|
||||||
|
5) 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 -e " ${L_BLUE}Choose the type of requirements to install${NC}"
|
||||||
|
echo
|
||||||
|
echo " 1. Nvidia graphics card machines"
|
||||||
|
echo " 2. Other machines (mac, amd, etc)"
|
||||||
|
echo
|
||||||
|
read -p " Enter your choice (1 or 2): " user_choice
|
||||||
|
|
||||||
|
if [ "$user_choice" == "1" ]; then
|
||||||
|
pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --upgrade --force-reinstall --index-url https://download.pytorch.org/whl/cu121
|
||||||
|
pip install numpy==1.24.4
|
||||||
|
pip install typing-extensions>=4.8.0
|
||||||
|
pip install networkx<3.0.0,>=2.5.0
|
||||||
|
pip install fsspec>=2023.6.0
|
||||||
|
pip install soundfile==0.12.1
|
||||||
|
pip install uvicorn==0.24.0.post1
|
||||||
|
pip install transformers>=4.37.1
|
||||||
|
pip install TTS==0.21.3
|
||||||
|
pip install fastapi==0.104.1
|
||||||
|
pip install Jinja2==3.1.2
|
||||||
|
pip install requests==2.31.0
|
||||||
|
pip install tqdm==4.66.1
|
||||||
|
pip install importlib-metadata==4.8.1
|
||||||
|
pip install packaging==23.2
|
||||||
|
pip install pydantic==1.10.13
|
||||||
|
pip install sounddevice==0.4.6
|
||||||
|
pip install python-multipart==0.0.6
|
||||||
|
pip install cutlet>=0.3.0
|
||||||
|
pip install unidic-lite>=1.0.8
|
||||||
|
else
|
||||||
|
pip install -r requirements_other.txt
|
||||||
|
fi
|
||||||
|
# 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"
|
||||||
|
# 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
|
||||||
|
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${INSTALL_ENV_DIR}"
|
||||||
|
python script.py
|
||||||
|
EOF
|
||||||
|
chmod +x start_alltalk.sh
|
||||||
|
chmod +x start_environment.sh
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e " start_alltalk.sh has been created."
|
||||||
|
echo -e " You can now start AllTalk with ${L_YELLOW}./start_alltalk.sh${NC}"
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
install_finetune_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 " The Conda environment at '${install_env_dir}' does not exist."
|
||||||
|
echo " Please install the environment before proceeding."
|
||||||
|
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}"
|
||||||
|
local requirements_file="requirements_finetune.txt"
|
||||||
|
echo "Installing Finetune requirements from $requirements_file..."
|
||||||
|
if ! pip install -r "$requirements_file"; then
|
||||||
|
echo " There was an error installing the Finetune requirements."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " Finetune base requirements installed successfully."
|
||||||
|
echo
|
||||||
|
echo -e " Finetuning requires access to ${GREEN}Cublas${NC} from the ${GREEN}Nvidia CUDA Toolkit${NC}, so will need installing."
|
||||||
|
echo
|
||||||
|
echo -e " Instructions can be found here:"
|
||||||
|
echo -e " ${GREEN}https://github.com/erew123/alltalk_tts?#-finetuning-a-model${NC}"
|
||||||
|
echo
|
||||||
|
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 " The Conda environment at '${install_env_dir}' does not exist."
|
||||||
|
echo " Please install the environment before proceeding."
|
||||||
|
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 " There was an error running diagnostics."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo " Diagnostics completed successfully."
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Start the main menu
|
||||||
|
main_menu
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"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": "12.0", "model_loaded": true, "model_name": "tts_models/multilingual/multi-dataset/xtts_v2", "narrator_voice": "female_01.wav", "output_folder_wav": "extensions/alltalk_tts/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"}
|
|
||||||
@@ -0,0 +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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
try:
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
from importlib_metadata import distributions
|
||||||
|
import torch
|
||||||
|
import os # Import the os module
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import textwrap
|
||||||
|
import packaging.version
|
||||||
|
import packaging.specifiers
|
||||||
|
from packaging.specifiers import SpecifierSet
|
||||||
|
from packaging.specifiers import SpecifierSet
|
||||||
|
from packaging.version import parse as parse_version
|
||||||
|
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[94mfrom the text-generation-webui directory, and then try running the diagnostics again.\033[0m")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import psutil
|
||||||
|
except ImportError:
|
||||||
|
print("psutil not found. Installing...")
|
||||||
|
subprocess.run(['pip', 'install', 'psutil'])
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
def get_requirements_file():
|
||||||
|
requirements_files = glob.glob("requirements*.txt")
|
||||||
|
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 in enumerate(requirements_files, start=1):
|
||||||
|
print(f"{i}. {file}")
|
||||||
|
|
||||||
|
choice = input("\nEnter the number of your choice: ")
|
||||||
|
try:
|
||||||
|
choice = int(choice) - 1
|
||||||
|
return requirements_files[choice]
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
return "requirements.txt"
|
||||||
|
|
||||||
|
# Set up logging with filemode='w'
|
||||||
|
logging.basicConfig(filename='diagnostics.log', filemode='w', level=logging.INFO)
|
||||||
|
|
||||||
|
# Function to get GPU information using subprocess
|
||||||
|
def get_gpu_info():
|
||||||
|
try:
|
||||||
|
result = subprocess.run(['nvidia-smi'], stdout=subprocess.PIPE, text=True)
|
||||||
|
return result.stdout
|
||||||
|
except FileNotFoundError:
|
||||||
|
return "NVIDIA GPU information not available"
|
||||||
|
|
||||||
|
# Function to check if a port is in use
|
||||||
|
def is_port_in_use(port):
|
||||||
|
for conn in psutil.net_connections():
|
||||||
|
if conn.laddr.port == 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
|
||||||
|
|
||||||
|
# Function to log and print system information
|
||||||
|
def log_system_info():
|
||||||
|
# System information
|
||||||
|
os_version = platform.system() + " " + platform.version()
|
||||||
|
|
||||||
|
# Get CUDA_HOME environment variable
|
||||||
|
cuda_home = os.environ.get('CUDA_HOME', 'N/A')
|
||||||
|
|
||||||
|
gpu_info = get_gpu_info()
|
||||||
|
|
||||||
|
# Python environment information
|
||||||
|
python_version = platform.python_version()
|
||||||
|
|
||||||
|
# Torch version
|
||||||
|
torch_version = torch.__version__
|
||||||
|
|
||||||
|
# System RAM using psutil
|
||||||
|
try:
|
||||||
|
virtual_memory = psutil.virtual_memory()
|
||||||
|
total_ram = f"{virtual_memory.total / (1024 ** 3):.2f} GB"
|
||||||
|
available_ram = f"{virtual_memory.available / (1024 ** 3):.2f} GB"
|
||||||
|
system_ram = f"{available_ram} available out of {total_ram} total"
|
||||||
|
except NameError:
|
||||||
|
print("psutil is not installed. Unable to check system RAM.")
|
||||||
|
system_ram = "N/A"
|
||||||
|
|
||||||
|
# Port check (if psutil is available)
|
||||||
|
port_status = "N/A"
|
||||||
|
if 'psutil' in globals():
|
||||||
|
port_to_check = 7851
|
||||||
|
if is_port_in_use(port_to_check):
|
||||||
|
port_status = f"Port {port_to_check} is in use."
|
||||||
|
else:
|
||||||
|
port_status = f"Port {port_to_check} is available."
|
||||||
|
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
# 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 will list as build is 10.x.22xxx")
|
||||||
|
logging.info(f"Torch Version: {torch_version}")
|
||||||
|
logging.info(f"System RAM: {system_ram}")
|
||||||
|
logging.info(f"CUDA_HOME: {cuda_home}")
|
||||||
|
logging.info(f"Port Status: {port_status}")
|
||||||
|
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 PATH Environment Variable:")
|
||||||
|
for path in path_env.split(';'):
|
||||||
|
logging.info(f" {path}")
|
||||||
|
if required_packages: # Check if the dictionary is not empty
|
||||||
|
logging.info("\nPackage Versions:")
|
||||||
|
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(f"GPU Information:\n{gpu_info}")
|
||||||
|
logging.info("Package Versions:")
|
||||||
|
for package, version in package_versions.items():
|
||||||
|
logging.info(f"{package}>= {version}")
|
||||||
|
|
||||||
|
# Print to screen
|
||||||
|
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[94mCUDA_HOME:\033[0m \033[92m{cuda_home}\033[0m")
|
||||||
|
print(f"\033[94mSystem RAM:\033[0m \033[92m{system_ram}\033[0m")
|
||||||
|
print(f"\033[94mPort Status:\033[0m \033[92m{port_status}\033[0m")
|
||||||
|
print(f"\033[94mTorch 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 Version Info:\033[0m \033[92m{python_version_info}\033[0m")
|
||||||
|
print(f"\033[94mPython Executable:\033[0m \033[92m{python_executable}\033[0m")
|
||||||
|
print(f"\033[94mPython Virtual Environment:\033[0m \033[92m{python_virtual_env}\033[0m (Should be N/A when in Text-generation-webui Conda Python environment)")
|
||||||
|
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}")
|
||||||
|
print(f"\n\033[94mOS Search PATH Environment Variable:\033[0m")
|
||||||
|
for path in path_env.split(';'):
|
||||||
|
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[94mPlease upload the log file with any support ticket.\033[0m")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
log_system_info()
|
||||||
@@ -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 ]
|
||||||
@@ -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
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import torch
|
||||||
|
import os
|
||||||
|
MODEL_PATH = "best_model.pth"
|
||||||
|
# Check if best_model.pth exists
|
||||||
|
if not os.path.exists(MODEL_PATH):
|
||||||
|
print(f"\nCannot find \033[94m{MODEL_PATH}\033[0m in the current folder.")
|
||||||
|
|
||||||
|
# Check if model.pth exists as an alternative
|
||||||
|
ALTERNATIVE_PATH = "model.pth"
|
||||||
|
if os.path.exists(ALTERNATIVE_PATH):
|
||||||
|
print(f"\nIf your model is currently called \033[93m{ALTERNATIVE_PATH}\033[0m please rename it to \033[94mbest_model.pth\033[0m.")
|
||||||
|
else:
|
||||||
|
print(f"Please put \033[91mbest_model.pth\033[0m in the current folder or rename your model file to \033[94mbest_model.pth\033[0m.")
|
||||||
|
exit(1)
|
||||||
|
# Attempt to load the model
|
||||||
|
try:
|
||||||
|
checkpoint = torch.load(MODEL_PATH, map_location=torch.device("cpu"))
|
||||||
|
except Exception as e:
|
||||||
|
print("Error loading checkpoint:", e)
|
||||||
|
raise
|
||||||
|
del checkpoint["optimizer"]
|
||||||
|
for key in list(checkpoint["model"].keys()):
|
||||||
|
if "dvae" in key:
|
||||||
|
del checkpoint["model"][key]
|
||||||
|
torch.save(checkpoint, "model.pth")
|
||||||
|
print(f"\nYour compacted model is created \033[93mmodel.pth\033[0m.")
|
||||||
@@ -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
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
"README.md": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/README.md?download=true",
|
"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",
|
"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",
|
"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"
|
"vocab.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/vocab.json?download=true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,9 @@ import importlib.metadata as metadata
|
|||||||
import json
|
import json
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
##############################################################
|
#################################################################
|
||||||
#### LOAD PARAMS FROM CONFIG.JSON - REQUIRED FOR BRANDING ####
|
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
|
||||||
##############################################################
|
#################################################################
|
||||||
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
|
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
|
||||||
this_dir = Path(__file__).parent.resolve()
|
this_dir = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ def load_config(file_path):
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
config_file_path = this_dir / "config.json"
|
config_file_path = this_dir / "confignew.json"
|
||||||
params = load_config(config_file_path)
|
params = load_config(config_file_path)
|
||||||
|
|
||||||
# Define the path to the modeldownload config file file
|
# Define the path to the modeldownload config file 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"]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
gradio>=3.50.2
|
||||||
|
torch>=2.1.0+cu118
|
||||||
|
torchaudio>=2.1.0+cu118
|
||||||
|
TTS==0.21.3
|
||||||
|
faster-whisper>=0.10.0
|
||||||
|
tqdm>=4.66.0
|
||||||
|
pandas>=1.5.0
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
numpy>=1.22.0
|
numpy>=1.22.0
|
||||||
soundfile>=0.12.1
|
soundfile>=0.12.1
|
||||||
uvicorn>=0.24.0.post1
|
uvicorn>=0.24.0.post1
|
||||||
|
transformers>=4.37.1
|
||||||
TTS>=0.21.3
|
TTS>=0.21.3
|
||||||
torch>=2.1.0+cu118
|
torch>=2.1.0+cu118
|
||||||
torchaudio>=2.1.0+cu118
|
torchaudio>=2.1.0+cu118
|
||||||
@@ -10,3 +11,8 @@ requests>=2.31.0
|
|||||||
tqdm>=4.66.1
|
tqdm>=4.66.1
|
||||||
importlib-metadata>=4.8.1
|
importlib-metadata>=4.8.1
|
||||||
packaging>=23.2
|
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
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
numpy>=1.22.0
|
numpy>=1.22.0
|
||||||
soundfile>=0.12.1
|
soundfile>=0.12.1
|
||||||
uvicorn>=0.24.0.post1
|
uvicorn>=0.24.0.post1
|
||||||
|
transformers>=4.37.1
|
||||||
TTS>=0.21.3
|
TTS>=0.21.3
|
||||||
torch>=2.1.0
|
torch>=2.1.0
|
||||||
torchaudio>=2.1.0
|
torchaudio>=2.1.0
|
||||||
@@ -10,3 +11,8 @@ requests>=2.31.0
|
|||||||
tqdm>=4.66.1
|
tqdm>=4.66.1
|
||||||
importlib-metadata>=4.8.1
|
importlib-metadata>=4.8.1
|
||||||
packaging>=23.2
|
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
|
||||||
@@ -16,20 +16,30 @@ import numpy as np
|
|||||||
import soundfile as sf
|
import soundfile as sf
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
##############################################################
|
######################################
|
||||||
#### LOAD PARAMS FROM CONFIG.JSON - REQUIRED FOR BRANDING ####
|
#### 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
|
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
|
||||||
this_dir = Path(__file__).parent.resolve()
|
this_dir = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
|
|
||||||
# load config file in and get settings
|
# load config file in and get settings
|
||||||
def load_config(file_path):
|
def load_config(file_path):
|
||||||
with open(file_path, "r") as config_file:
|
with open(file_path, "r") as config_file:
|
||||||
config = json.load(config_file)
|
config = json.load(config_file)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
config_file_path = this_dir / "config.json"
|
|
||||||
# Load the params dictionary from the config.json file
|
config_file_path = this_dir / "confignew.json"
|
||||||
|
# Load the params dictionary from the confignew.json file
|
||||||
params = load_config(config_file_path)
|
params = load_config(config_file_path)
|
||||||
|
|
||||||
# Required for sentence splitting
|
# Required for sentence splitting
|
||||||
@@ -39,8 +49,8 @@ try:
|
|||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
logger.error(
|
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 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 Linux / Mac:\npip install -r /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 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."
|
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
|
raise
|
||||||
@@ -48,6 +58,7 @@ except ModuleNotFoundError:
|
|||||||
# IMPORT - Attempt Importing DeepSpeed (required for displaying Deepspeed checkbox in gradio)
|
# IMPORT - Attempt Importing DeepSpeed (required for displaying Deepspeed checkbox in gradio)
|
||||||
try:
|
try:
|
||||||
import deepspeed
|
import deepspeed
|
||||||
|
|
||||||
deepspeed_installed = True
|
deepspeed_installed = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
deepspeed_installed = False
|
deepspeed_installed = False
|
||||||
@@ -60,9 +71,12 @@ try:
|
|||||||
from modules.logging_colors import logger
|
from modules.logging_colors import logger
|
||||||
from modules.ui import create_refresh_button
|
from modules.ui import create_refresh_button
|
||||||
from modules.utils import gradio
|
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
|
# 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
|
running_in_standalone = False
|
||||||
|
output_folder_wav = params["output_folder_wav"]
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
output_folder_wav = params["output_folder_wav_standalone"]
|
||||||
print(f"[{params['branding']}Startup] Running script.py in standalone mode")
|
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
|
# 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
|
running_in_standalone = True
|
||||||
@@ -75,11 +89,15 @@ with open(this_dir / "languages.json", encoding="utf8") as f:
|
|||||||
languages = json.load(f)
|
languages = json.load(f)
|
||||||
# Create a global lock
|
# Create a global lock
|
||||||
process_lock = threading.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
|
# Gather the voice files
|
||||||
def get_available_voices():
|
def get_available_voices():
|
||||||
return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")])
|
return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")])
|
||||||
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
#### LICENSE DISPLAY ####
|
#### LICENSE DISPLAY ####
|
||||||
#########################
|
#########################
|
||||||
@@ -108,7 +126,6 @@ def delete_old_files(folder_path, days_to_keep):
|
|||||||
|
|
||||||
# Extract settings using params dictionary
|
# Extract settings using params dictionary
|
||||||
delete_output_wavs_setting = params["delete_output_wavs"]
|
delete_output_wavs_setting = params["delete_output_wavs"]
|
||||||
output_folder_wav = params["output_folder_wav"]
|
|
||||||
output_folder_wav = os.path.normpath(output_folder_wav)
|
output_folder_wav = os.path.normpath(output_folder_wav)
|
||||||
|
|
||||||
# Check and perform file deletion
|
# Check and perform file deletion
|
||||||
@@ -142,10 +159,26 @@ def check_required_files():
|
|||||||
# STARTUP Call Check routine
|
# STARTUP Call Check routine
|
||||||
check_required_files()
|
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 CONFIG.JSON ####
|
#### SET GRADIO BUTTONS BASED ON confignew.json ####
|
||||||
#################################################
|
####################################################
|
||||||
|
|
||||||
if params["tts_method_api_tts"] == True:
|
if params["tts_method_api_tts"] == True:
|
||||||
gr_modelchoice = "API TTS"
|
gr_modelchoice = "API TTS"
|
||||||
@@ -157,6 +190,7 @@ elif params["tts_method_xtts_local"] == True:
|
|||||||
# Set the default for Narrated text without asterisk or quotes to be Narrator
|
# Set the default for Narrated text without asterisk or quotes to be Narrator
|
||||||
non_quoted_text_is = True
|
non_quoted_text_is = True
|
||||||
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
#### GRADIO STUFF ####
|
#### GRADIO STUFF ####
|
||||||
######################
|
######################
|
||||||
@@ -214,17 +248,23 @@ def signal_handler(sig, frame):
|
|||||||
|
|
||||||
# Attach the signal handler to the SIGINT signal (Ctrl+C)
|
# Attach the signal handler to the SIGINT signal (Ctrl+C)
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
# Check if we're running in docker
|
||||||
|
if os.path.isfile("/.dockerenv"):
|
||||||
|
print(
|
||||||
|
f"[{params['branding']}Startup] \033[94mRunning in Docker. Please wait.\033[0m"
|
||||||
|
)
|
||||||
|
else:
|
||||||
# Start the subprocess
|
# Start the subprocess
|
||||||
process = subprocess.Popen(["python", script_path])
|
process = subprocess.Popen(["python", script_path])
|
||||||
|
|
||||||
# Check if the subprocess has started successfully
|
# Check if the subprocess has started successfully
|
||||||
if process.poll() is None:
|
if process.poll() is None:
|
||||||
print(f"[{params['branding']}Startup] TTS Subprocess starting")
|
print(f"[{params['branding']}Startup] TTS Subprocess starting")
|
||||||
|
print(f"[{params['branding']}Startup]")
|
||||||
print(
|
print(
|
||||||
f"[{params['branding']}Startup] Readme available here:",
|
f"[{params['branding']}Startup] \033[94m {params['branding']}Settings & Documentation:\033[00m",
|
||||||
f"http://{params['ip_address']}:{params['port_number']}",
|
f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m",
|
||||||
)
|
)
|
||||||
|
print(f"[{params['branding']}Startup]")
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process"
|
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process"
|
||||||
@@ -248,10 +288,10 @@ else:
|
|||||||
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
|
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
timeout = 60 # Adjust the timeout as needed
|
timeout = startup_wait_time # Gather timeout setting from startup_wait_time
|
||||||
|
|
||||||
# Introduce a delay before starting the check loop
|
# Introduce a delay before starting the check loop
|
||||||
time.sleep(25) # Wait 25 secs before checking if the tts_server.py has started up.
|
time.sleep(26) # Wait 26 secs before checking if the tts_server.py has started up.
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
while time.time() - start_time < timeout:
|
while time.time() - start_time < timeout:
|
||||||
try:
|
try:
|
||||||
@@ -261,23 +301,37 @@ while time.time() - start_time < timeout:
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
# Print the exception for debugging purposes
|
# Print the exception for debugging purposes
|
||||||
print(
|
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[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait."
|
||||||
)
|
)
|
||||||
time.sleep(1)
|
time.sleep(5)
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"[{params['branding']}Startup] Startup timed out. Check the server logs for more information."
|
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
|
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
#### MODEL LOADING AND UNLOADING ####
|
#### MODEL LOADING AND UNLOADING ####
|
||||||
#####################################
|
#####################################
|
||||||
# MODEL - Swap model based on Gradio selection API TTS, API Local, XTTSv2 Local
|
# MODEL - Swap model based on Gradio selection API TTS, API Local, XTTSv2 Local
|
||||||
def send_reload_request(tts_method):
|
def send_reload_request(tts_method):
|
||||||
|
global tts_method_xtts_ft
|
||||||
try:
|
try:
|
||||||
params["model_loaded"] = False
|
params["tts_model_loaded"] = False
|
||||||
url = f"{base_url}/api/reload"
|
url = f"{base_url}/api/reload"
|
||||||
payload = {"tts_method": tts_method}
|
payload = {"tts_method": tts_method}
|
||||||
response = requests.post(url, params=payload)
|
response = requests.post(url, params=payload)
|
||||||
@@ -285,8 +339,8 @@ def send_reload_request(tts_method):
|
|||||||
json_response = response.json()
|
json_response = response.json()
|
||||||
# Check if the reload operation was successful
|
# Check if the reload operation was successful
|
||||||
if json_response.get("status") == "model-success":
|
if json_response.get("status") == "model-success":
|
||||||
# Update model_loaded to True if the reload was successful
|
# Update tts_tts_model_loaded to True if the reload was successful
|
||||||
params["model_loaded"] = True
|
params["tts_model_loaded"] = True
|
||||||
# Update local script parameters based on the tts_method
|
# Update local script parameters based on the tts_method
|
||||||
if tts_method == "API TTS":
|
if tts_method == "API TTS":
|
||||||
params["tts_method_api_local"] = False
|
params["tts_method_api_local"] = False
|
||||||
@@ -294,17 +348,26 @@ def send_reload_request(tts_method):
|
|||||||
params["tts_method_api_tts"] = True
|
params["tts_method_api_tts"] = True
|
||||||
params["deepspeed_activate"] = False
|
params["deepspeed_activate"] = False
|
||||||
audio_path = this_dir / "templates" / "apitts.wav"
|
audio_path = this_dir / "templates" / "apitts.wav"
|
||||||
|
tts_method_xtts_ft = False
|
||||||
elif tts_method == "API Local":
|
elif tts_method == "API Local":
|
||||||
params["tts_method_api_tts"] = False
|
params["tts_method_api_tts"] = False
|
||||||
params["tts_method_xtts_local"] = False
|
params["tts_method_xtts_local"] = False
|
||||||
params["tts_method_api_local"] = True
|
params["tts_method_api_local"] = True
|
||||||
params["deepspeed_activate"] = False
|
params["deepspeed_activate"] = False
|
||||||
audio_path = this_dir / "templates" / "apilocal.wav"
|
audio_path = this_dir / "templates" / "apilocal.wav"
|
||||||
|
tts_method_xtts_ft = False
|
||||||
elif tts_method == "XTTSv2 Local":
|
elif tts_method == "XTTSv2 Local":
|
||||||
params["tts_method_api_tts"] = False
|
params["tts_method_api_tts"] = False
|
||||||
params["tts_method_api_local"] = False
|
params["tts_method_api_local"] = False
|
||||||
params["tts_method_xtts_local"] = True
|
params["tts_method_xtts_local"] = True
|
||||||
audio_path = this_dir / "templates" / "xttslocal.wav"
|
audio_path = this_dir / "templates" / "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 / "templates" / "xttsfinetuned.wav"
|
||||||
|
tts_method_xtts_ft = True
|
||||||
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# Handle the HTTP request error
|
# Handle the HTTP request error
|
||||||
@@ -313,13 +376,14 @@ def send_reload_request(tts_method):
|
|||||||
)
|
)
|
||||||
return {"status": "error", "message": str(e)}
|
return {"status": "error", "message": str(e)}
|
||||||
|
|
||||||
|
|
||||||
##################
|
##################
|
||||||
#### LOW VRAM ####
|
#### LOW VRAM ####
|
||||||
##################
|
##################
|
||||||
# LOW VRAM - Gradio Checkbox handling
|
# LOW VRAM - Gradio Checkbox handling
|
||||||
def send_lowvram_request(low_vram):
|
def send_lowvram_request(low_vram):
|
||||||
try:
|
try:
|
||||||
params["model_loaded"] = False
|
params["tts_model_loaded"] = False
|
||||||
if low_vram:
|
if low_vram:
|
||||||
audio_path = this_dir / "templates" / "lowvramenabled.wav"
|
audio_path = this_dir / "templates" / "lowvramenabled.wav"
|
||||||
else:
|
else:
|
||||||
@@ -332,7 +396,7 @@ def send_lowvram_request(low_vram):
|
|||||||
# Check if the low VRAM request was successful
|
# Check if the low VRAM request was successful
|
||||||
if json_response.get("status") == "lowvram-success":
|
if json_response.get("status") == "lowvram-success":
|
||||||
# Update any relevant variables or perform other actions on success
|
# Update any relevant variables or perform other actions on success
|
||||||
params["model_loaded"] = True
|
params["tts_model_loaded"] = True
|
||||||
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# Handle the HTTP request error
|
# Handle the HTTP request error
|
||||||
@@ -348,7 +412,7 @@ def send_lowvram_request(low_vram):
|
|||||||
# DEEPSPEED - Reload the model when DeepSpeed checkbox is enabled/disabled
|
# DEEPSPEED - Reload the model when DeepSpeed checkbox is enabled/disabled
|
||||||
def send_deepspeed_request(deepspeed_param):
|
def send_deepspeed_request(deepspeed_param):
|
||||||
try:
|
try:
|
||||||
params["model_loaded"] = False
|
params["tts_model_loaded"] = False
|
||||||
if deepspeed_param:
|
if deepspeed_param:
|
||||||
audio_path = this_dir / "templates" / "deepspeedenabled.wav"
|
audio_path = this_dir / "templates" / "deepspeedenabled.wav"
|
||||||
else:
|
else:
|
||||||
@@ -362,7 +426,7 @@ def send_deepspeed_request(deepspeed_param):
|
|||||||
# Check if the deepspeed request was successful
|
# Check if the deepspeed request was successful
|
||||||
if json_response.get("status") == "deepspeed-success":
|
if json_response.get("status") == "deepspeed-success":
|
||||||
# Update any relevant variables or perform other actions on success
|
# Update any relevant variables or perform other actions on success
|
||||||
params["model_loaded"] = True
|
params["tts_model_loaded"] = True
|
||||||
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
return f'<audio src="file/{audio_path}" controls autoplay></audio>'
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# Handle the HTTP request error
|
# Handle the HTTP request error
|
||||||
@@ -400,7 +464,7 @@ Synthesizer.split_into_sentences = new_split_into_sentences
|
|||||||
# Check model is loaded and string isnt empty, before sending a TTS request.
|
# Check model is loaded and string isnt empty, before sending a TTS request.
|
||||||
def before_audio_generation(string, params):
|
def before_audio_generation(string, params):
|
||||||
# Check Model is loaded into cuda or cpu and error if not
|
# Check Model is loaded into cuda or cpu and error if not
|
||||||
if not params["model_loaded"]:
|
if not params["tts_model_loaded"]:
|
||||||
print(
|
print(
|
||||||
f"[{params['branding']}Model] \033[91mWarning\033[0m Model is still loading, please wait before trying to generate TTS"
|
f"[{params['branding']}Model] \033[91mWarning\033[0m Model is still loading, please wait before trying to generate TTS"
|
||||||
)
|
)
|
||||||
@@ -427,9 +491,13 @@ def combine(audio_files, output_folder, state):
|
|||||||
|
|
||||||
# Save the combined audio to a file with a specified sample rate
|
# Save the combined audio to a file with a specified sample rate
|
||||||
if "character_menu" in state:
|
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:
|
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)
|
sf.write(output_file_path, audio, samplerate=sample_rate)
|
||||||
# Clean up unnecessary files
|
# Clean up unnecessary files
|
||||||
for audio_file in audio_files:
|
for audio_file in audio_files:
|
||||||
@@ -460,12 +528,19 @@ def voice_preview(string):
|
|||||||
output_file = Path(params["output_folder_wav"]) / "voice_preview.wav"
|
output_file = Path(params["output_folder_wav"]) / "voice_preview.wav"
|
||||||
# Generate the audio
|
# Generate the audio
|
||||||
language_code = languages.get(params["language"])
|
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
|
# Convert the WindowsPath object to a string before using it in JSON payload
|
||||||
output_file_str = output_file.as_posix()
|
output_file_str = output_file.as_posix()
|
||||||
# Lock before making the generate request
|
# Lock before making the generate request
|
||||||
with process_lock:
|
with process_lock:
|
||||||
generate_response = send_generate_request(
|
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
|
# Check if lock is already acquired
|
||||||
if process_lock.locked():
|
if process_lock.locked():
|
||||||
@@ -482,6 +557,55 @@ def voice_preview(string):
|
|||||||
return f"[{params['branding']}Server] Audio generation failed. Status: {generate_response.get('status')}"
|
return f"[{params['branding']}Server] Audio generation failed. Status: {generate_response.get('status')}"
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
#### TTS STANDARD GENERATION ####
|
#### TTS STANDARD GENERATION ####
|
||||||
#################################
|
#################################
|
||||||
@@ -490,104 +614,103 @@ def output_modifier(string, state):
|
|||||||
if not params["activate"]:
|
if not params["activate"]:
|
||||||
return string
|
return string
|
||||||
original_string = string
|
original_string = string
|
||||||
|
# print("ORIGINAL STRING IS:", original_string)
|
||||||
cleaned_string = before_audio_generation(string, params)
|
cleaned_string = before_audio_generation(string, params)
|
||||||
if cleaned_string is None:
|
if cleaned_string is None:
|
||||||
return
|
return
|
||||||
string = cleaned_string
|
string = cleaned_string
|
||||||
language_code = languages.get(params["language"])
|
language_code = languages.get(params["language"])
|
||||||
|
temperature = params["local_temperature"]
|
||||||
|
repetition_penalty = params["local_repetition_penalty"]
|
||||||
# Create a list to store generated audio paths
|
# Create a list to store generated audio paths
|
||||||
audio_files = []
|
audio_files = []
|
||||||
if process_lock.acquire(blocking=False):
|
if process_lock.acquire(blocking=False):
|
||||||
try:
|
try:
|
||||||
if params["narrator_enabled"]:
|
if params["narrator_enabled"]:
|
||||||
# print(original_string)
|
processed_parts = process_text(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("'", "'")
|
|
||||||
.replace("\n", " ")
|
|
||||||
# Add special characters to the quote so that we can use it to identify things later after its been split
|
|
||||||
.replace('"', '"<')
|
|
||||||
# Capture new conversations which wont have things like "e in them
|
|
||||||
.replace('"', '"<')
|
|
||||||
)
|
|
||||||
#capturing another outlier in inital character paragraph
|
|
||||||
# print("processed string 1 is:", processed_string)
|
|
||||||
processed_string = processed_string.replace('"<. *', '"< *"')
|
|
||||||
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.
|
|
||||||
audio_files_all_paragraphs = []
|
audio_files_all_paragraphs = []
|
||||||
# Split the line using " 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 *
|
for part_type, part in processed_parts:
|
||||||
parts = re.split(r'"|\.\*', processed_string)
|
|
||||||
audio_files_paragraph = []
|
|
||||||
for i, part in enumerate(parts):
|
|
||||||
# Skip parts that are too short
|
# Skip parts that are too short
|
||||||
if len(part.strip()) <= 1:
|
if len(part.strip()) <= 3:
|
||||||
continue
|
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
|
# Determine the voice to use based on the part type
|
||||||
if '<' in part and '< *' not in part and '<*' not in part and '< *' not in part and '< ' not in part and '< ' not in part:
|
if part_type == "narrator":
|
||||||
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('*', ''))
|
|
||||||
voice_to_use = params["narrator_voice"]
|
voice_to_use = params["narrator_voice"]
|
||||||
#If the other two dont capture it, aka, the AI gave no * or " on the line, use non_quoted_text_is aka user interface, user can choose Char or Narrator
|
print(
|
||||||
elif non_quoted_text_is:
|
f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m"
|
||||||
cleaned_part = html.unescape(part.replace('< ', '').replace('< ', '').replace('< ', ''))
|
) # Green
|
||||||
|
elif part_type == "character":
|
||||||
voice_to_use = params["voice"]
|
voice_to_use = params["voice"]
|
||||||
|
print(
|
||||||
|
f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m"
|
||||||
|
) # Yellow
|
||||||
else:
|
else:
|
||||||
cleaned_part = html.unescape(part.replace('< ', '').replace('< ', '').replace('< ', ''))
|
# Handle ambiguous parts based on user preference
|
||||||
voice_to_use = params["narrator_voice"]
|
voice_to_use = (
|
||||||
# Check if character name exists and if not, just call it TTSOUT_
|
params["voice"]
|
||||||
if "character_menu" in state:
|
if non_quoted_text_is
|
||||||
output_file = Path(f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}_{i}.wav')
|
else params["narrator_voice"]
|
||||||
else:
|
)
|
||||||
output_file = Path(f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}_{i}.wav')
|
voice_description = (
|
||||||
# Generate that TTS and output to a file
|
"\033[36mCharacter (Text-not-inside)\033[0m"
|
||||||
output_file_str = output_file.as_posix()
|
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(
|
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_path = generate_response.get("data", {}).get("audio_path")
|
||||||
audio_files_paragraph.append(audio_path)
|
audio_files_all_paragraphs.append(audio_path)
|
||||||
# Accumulate audio files within the paragraph
|
|
||||||
audio_files_all_paragraphs.extend(audio_files_paragraph)
|
|
||||||
# Combine audio files across paragraphs
|
# Combine audio files across paragraphs
|
||||||
final_output_file = combine(
|
final_output_file = combine(
|
||||||
audio_files_all_paragraphs, params["output_folder_wav"], state
|
audio_files_all_paragraphs, params["output_folder_wav"], state
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
processed_string = (
|
# Decode HTML entities first
|
||||||
original_string
|
cleaned_part = html.unescape(original_string)
|
||||||
.replace("***", "")
|
# Replace multiple instances of certain punctuation marks with a single instance
|
||||||
.replace("**", "")
|
cleaned_part = re.sub(r"([!?.])\1+", r"\1", cleaned_part)
|
||||||
.replace("*", "")
|
# Further clean to remove any other unwanted characters
|
||||||
.replace("\n\n", "\n")
|
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)
|
||||||
.replace("'", "'")
|
# Remove all newline characters (single or multiple)
|
||||||
)
|
cleaned_part = re.sub(r"\n+", " ", cleaned_part)
|
||||||
cleaned_part = html.unescape(processed_string)
|
|
||||||
# Process the part and give it a non-character name if being used vai API or standalone.
|
# Process the part and give it a non-character name if being used vai API or standalone.
|
||||||
if "character_menu" in state:
|
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:
|
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_str = output_file.as_posix()
|
||||||
output_file = get_output_filename(state)
|
output_file = get_output_filename(state)
|
||||||
generate_response = send_generate_request(
|
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")
|
audio_path = generate_response.get("data", {}).get("audio_path")
|
||||||
final_output_file = audio_path
|
final_output_file = audio_path
|
||||||
@@ -627,20 +750,29 @@ def output_modifier(string, state):
|
|||||||
|
|
||||||
|
|
||||||
def get_output_filename(state):
|
def get_output_filename(state):
|
||||||
|
if "character_menu" in state:
|
||||||
return Path(
|
return Path(
|
||||||
f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav'
|
f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav'
|
||||||
).as_posix()
|
).as_posix()
|
||||||
|
else:
|
||||||
|
return Path(
|
||||||
|
f'{params["output_folder_wav"]}/TTSOUT_{str(uuid.uuid4())[:8]}.wav'
|
||||||
|
).as_posix()
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
#### SEND GENERATION REQUEST TO TTS ENGINE ####
|
#### 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"
|
url = f"{base_url}/api/generate"
|
||||||
payload = {
|
payload = {
|
||||||
"text": text,
|
"text": text,
|
||||||
"voice": voice,
|
"voice": voice,
|
||||||
"language": language,
|
"language": language,
|
||||||
|
"temperature": temperature,
|
||||||
|
"repetition_penalty": repetition_penalty,
|
||||||
"output_file": output_file,
|
"output_file": output_file,
|
||||||
}
|
}
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
@@ -665,12 +797,14 @@ def state_modifier(state):
|
|||||||
state["stream"] = False
|
state["stream"] = False
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
def update_narrator_enabled(value):
|
def update_narrator_enabled(value):
|
||||||
if value == "Enabled":
|
if value == "Enabled":
|
||||||
params["narrator_enabled"] = True
|
params["narrator_enabled"] = True
|
||||||
elif value == "Disabled":
|
elif value == "Disabled":
|
||||||
params["narrator_enabled"] = False
|
params["narrator_enabled"] = False
|
||||||
|
|
||||||
|
|
||||||
def update_non_quoted_text_is(value):
|
def update_non_quoted_text_is(value):
|
||||||
global non_quoted_text_is
|
global non_quoted_text_is
|
||||||
if value == "Narrator":
|
if value == "Narrator":
|
||||||
@@ -678,6 +812,7 @@ def update_non_quoted_text_is(value):
|
|||||||
elif value == "Char":
|
elif value == "Char":
|
||||||
non_quoted_text_is = True
|
non_quoted_text_is = True
|
||||||
|
|
||||||
|
|
||||||
def input_modifier(string, state):
|
def input_modifier(string, state):
|
||||||
if not params["activate"]:
|
if not params["activate"]:
|
||||||
return string
|
return string
|
||||||
@@ -685,42 +820,56 @@ def input_modifier(string, state):
|
|||||||
shared.processing_message = "*Is recording a voice message...*"
|
shared.processing_message = "*Is recording a voice message...*"
|
||||||
return string
|
return string
|
||||||
|
|
||||||
def custom_css():
|
|
||||||
path_to_css = Path(f"{this_dir}/style.css")
|
|
||||||
return open(path_to_css, "r").read()
|
|
||||||
|
|
||||||
|
|
||||||
def ui():
|
def ui():
|
||||||
with gr.Accordion(params["branding"] + " TTS (XTTSv2)"):
|
with gr.Accordion(params["branding"] + " TTS (XTTSv2)"):
|
||||||
|
# Activate alltalk_tts, Enable autoplay, Show text
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
activate = gr.Checkbox(value=params["activate"], label="Activate TTS")
|
activate = gr.Checkbox(value=params["activate"], label="Enable TTS")
|
||||||
autoplay = gr.Checkbox(
|
autoplay = gr.Checkbox(value=params["autoplay"], label="Autoplay TTS")
|
||||||
value=params["autoplay"], label="Play TTS automatically"
|
show_text = gr.Checkbox(value=params["show_text"], label="Show Text")
|
||||||
)
|
|
||||||
|
|
||||||
|
# Low vram enable, Deepspeed enable, Remove trailing dots
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
show_text = gr.Checkbox(
|
low_vram = gr.Checkbox(
|
||||||
value=params["show_text"], label="Show message text under audio player"
|
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(
|
remove_trailing_dots = gr.Checkbox(
|
||||||
value=params["remove_trailing_dots"],
|
value=params["remove_trailing_dots"], label='Remove trailing "."'
|
||||||
label='Remove trailing "." from text segments before generation',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TTS method, Character voice selection
|
||||||
with gr.Row():
|
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():
|
with gr.Row():
|
||||||
available_voices = get_available_voices()
|
available_voices = get_available_voices()
|
||||||
default_voice = params["voice"]
|
default_voice = params[
|
||||||
# Check if the default voice is in the list of available voices
|
"voice"
|
||||||
|
] # Check if the default voice is in the list of available voices
|
||||||
|
|
||||||
if default_voice not in 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[
|
default_voice = available_voices[
|
||||||
0
|
0
|
||||||
] # Choose the first available voice as the default
|
] # Choose the first available voice as the default
|
||||||
# Add allow_custom_value=True to the Dropdown
|
# Add allow_custom_value=True to the Dropdown
|
||||||
voice = gr.Dropdown(
|
voice = gr.Dropdown(
|
||||||
available_voices,
|
available_voices,
|
||||||
label="Default Voice",
|
label="Character Voice",
|
||||||
value=default_voice,
|
value=default_voice,
|
||||||
allow_custom_value=True,
|
allow_custom_value=True,
|
||||||
)
|
)
|
||||||
@@ -734,14 +883,11 @@ def ui():
|
|||||||
"refresh-button",
|
"refresh-button",
|
||||||
)
|
)
|
||||||
|
|
||||||
language = gr.Dropdown(
|
# Language, Narrator voice
|
||||||
languages.keys(),
|
|
||||||
label="Language",
|
|
||||||
allow_custom_value=True,
|
|
||||||
value=params["language"],
|
|
||||||
)
|
|
||||||
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
|
language = gr.Dropdown(
|
||||||
|
languages.keys(), label="Language", value=params["language"]
|
||||||
|
)
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
narrator_voice_gr = gr.Dropdown(
|
narrator_voice_gr = gr.Dropdown(
|
||||||
get_available_voices(),
|
get_available_voices(),
|
||||||
@@ -758,40 +904,42 @@ def ui():
|
|||||||
},
|
},
|
||||||
"refresh-button",
|
"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(
|
narrator_enabled_gr = gr.Radio(
|
||||||
choices={"Enabled": "true", "Disabled": "false"},
|
choices={"Enabled": "true", "Disabled": "false"},
|
||||||
label="Narrator Activation",
|
label="Narrator",
|
||||||
value="Enabled" if params.get("narrator_enabled") else "Disabled",
|
value="Enabled" if params.get("narrator_enabled") else "Disabled",
|
||||||
)
|
)
|
||||||
non_quoted_text_is_gr = gr.Radio(
|
non_quoted_text_is_gr = gr.Radio(
|
||||||
choices={"Char": "true", "Narrator": "false"},
|
choices={"Character": "true", "Narrator": "false"},
|
||||||
label='Text NOT inside of * or " is',
|
label='Unmarked text NOT inside of * or " is',
|
||||||
value="Char" if non_quoted_text_is else "Narrator",
|
value="Character" if non_quoted_text_is else "Narrator",
|
||||||
)
|
)
|
||||||
|
|
||||||
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(
|
explanation_text = gr.HTML(
|
||||||
f"<p>NOTE: Switching Model Type, Low VRAM & DeepSpeed 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>"
|
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>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Preview speech
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
preview_text = gr.Text(
|
preview_text = gr.Text(
|
||||||
show_label=False,
|
show_label=False,
|
||||||
@@ -861,18 +1009,34 @@ def ui():
|
|||||||
autoplay.change(lambda x: params.update({"autoplay": x}), autoplay, None)
|
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: params.update({"low_vram": x}), low_vram, None)
|
||||||
low_vram.change(lambda x: send_lowvram_request(x), low_vram, low_vram_play, 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)
|
tts_radio_buttons.change(
|
||||||
deepspeed_checkbox.change(send_deepspeed_request, deepspeed_checkbox, deepspeed_checkbox_play, None)
|
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(
|
remove_trailing_dots.change(
|
||||||
lambda x: params.update({"remove_trailing_dots": x}), remove_trailing_dots, None
|
lambda x: params.update({"remove_trailing_dots": x}), remove_trailing_dots, None
|
||||||
)
|
)
|
||||||
voice.change(lambda x: params.update({"voice": x}), voice, None)
|
voice.change(lambda x: params.update({"voice": x}), voice, None)
|
||||||
language.change(lambda x: params.update({"language": x}), language, 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 selection actions
|
||||||
narrator_enabled_gr.change(update_narrator_enabled, narrator_enabled_gr, None)
|
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)
|
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
|
# Play preview
|
||||||
preview_text.submit(voice_preview, preview_text, preview_audio)
|
preview_text.submit(voice_preview, preview_text, preview_audio)
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
.SDAP .hires_opts input[type="number"] {
|
|
||||||
width: 6em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* silero_tts preview */
|
|
||||||
.form:has(> #silero_preview_text) {
|
|
||||||
min-width: 75%
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -201,12 +201,12 @@
|
|||||||
value="{{ data.output_folder_wav }}" />
|
value="{{ data.output_folder_wav }}" />
|
||||||
|
|
||||||
|
|
||||||
<input type="hidden" id="model_loaded" name="model_loaded" value="{{ data.model_loaded }}" />
|
<input type="hidden" id="tts_model_loaded" name="tts_model_loaded" value="{{ data.tts_model_loaded }}" />
|
||||||
|
|
||||||
<!-- Continue updating other dropdowns and inputs in a similar manner -->
|
<!-- Continue updating other dropdowns and inputs in a similar manner -->
|
||||||
|
|
||||||
<label for="model_name" style="color: red;"> API TTS Model Name:</label>
|
<label for="tts_model_name" style="color: red;"> API TTS Model Name:</label>
|
||||||
<input id="model_name" name="model_name" required="" type="text" value="{{ data.model_name }}" />
|
<input id="tts_model_name" name="tts_model_name" required="" type="text" value="{{ data.tts_model_name }}" />
|
||||||
|
|
||||||
<label for="model_version"
|
<label for="model_version"
|
||||||
style="color: red; font-size: 16px; line-height: 1; vertical-align: bottom; margin-bottom: 0;">
|
style="color: red; font-size: 16px; line-height: 1; vertical-align: bottom; margin-bottom: 0;">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 547 KiB After Width: | Height: | Size: 547 KiB |
@@ -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:**
|
||||||
|
*
|
||||||
|
* 
|
||||||
|
*/
|
||||||
|
mergeAudio(buffers: AudioBuffer[]): AudioBuffer;
|
||||||
|
/**
|
||||||
|
* Concatenates multiple AudioBuffers into a single AudioBuffer.
|
||||||
|
*
|
||||||
|
* **Visual representation:**
|
||||||
|
*
|
||||||
|
* 
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"crunker.esm.js","mappings":"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 truncated
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 839 B |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 99 KiB |
@@ -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>
|
||||||
@@ -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
|
||||||
@@ -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":""}
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"polyfill.js","mappings":"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 truncated
|
||||||
@@ -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>
|
||||||
@@ -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 */
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"taskpane.js","mappings":"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 truncated
|
||||||