docs/deps: point upstream to github.com/maxmelichov/BlueTTS
Browse files- README.md +3 -3
- app.py +127 -33
- pyproject.toml +1 -1
- requirements.txt +1 -1
- uv.lock +2 -2
README.md
CHANGED
|
@@ -12,7 +12,7 @@ python_version: "3.12"
|
|
| 12 |
|
| 13 |
# BlueTTS โ Multilingual text-to-speech
|
| 14 |
|
| 15 |
-
Interactive demo for **BlueTTS
|
| 16 |
|
| 17 |
## Languages
|
| 18 |
|
|
@@ -39,7 +39,7 @@ If you fork this Space and point downloads at a **private** repo, set a Hugging
|
|
| 39 |
## Links
|
| 40 |
|
| 41 |
- **ONNX weights:** [notmax123/blue-onnx](https://huggingface.co/notmax123/blue-onnx)
|
| 42 |
-
- **
|
| 43 |
- **Hebrew G2P:** [thewh1teagle/renikud](https://huggingface.co/thewh1teagle/renikud)
|
| 44 |
|
| 45 |
## Local development
|
|
@@ -60,4 +60,4 @@ uv export --no-hashes --no-emit-project > requirements.txt
|
|
| 60 |
|
| 61 |
## License
|
| 62 |
|
| 63 |
-
See the
|
|
|
|
| 12 |
|
| 13 |
# BlueTTS โ Multilingual text-to-speech
|
| 14 |
|
| 15 |
+
Interactive demo for **[BlueTTS](https://github.com/maxmelichov/BlueTTS)**: fast on-device synthesis with **ONNX Runtime**. Type text, pick a language and voice, and generate audio in the browser. Project site: [lightbluetts.com](https://lightbluetts.com/).
|
| 16 |
|
| 17 |
## Languages
|
| 18 |
|
|
|
|
| 39 |
## Links
|
| 40 |
|
| 41 |
- **ONNX weights:** [notmax123/blue-onnx](https://huggingface.co/notmax123/blue-onnx)
|
| 42 |
+
- **Source code:** [maxmelichov/BlueTTS on GitHub](https://github.com/maxmelichov/BlueTTS)
|
| 43 |
- **Hebrew G2P:** [thewh1teagle/renikud](https://huggingface.co/thewh1teagle/renikud)
|
| 44 |
|
| 45 |
## Local development
|
|
|
|
| 60 |
|
| 61 |
## License
|
| 62 |
|
| 63 |
+
See the [BlueTTS](https://github.com/maxmelichov/BlueTTS) repository and the [blue-onnx](https://huggingface.co/notmax123/blue-onnx) model card for licensing of code and weights.
|
app.py
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
import re
|
| 3 |
import sys
|
|
@@ -862,38 +866,130 @@ body, .gradio-container {
|
|
| 862 |
.gradio-textbox label span, .gradio-dropdown label span,
|
| 863 |
.gradio-radio label span, .gradio-slider label span { color: #9ca3af !important; font-size: 0.8rem !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: 0.05em !important; }
|
| 864 |
|
| 865 |
-
/* Controls
|
| 866 |
-
.controls-row {
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 872 |
.controls-row .gradio-dropdown > label > div {
|
| 873 |
background: #0d0d14 !important;
|
| 874 |
border: 1px solid #2a2a3e !important;
|
| 875 |
border-radius: 8px !important;
|
| 876 |
color: #e8e8f0 !important;
|
| 877 |
min-height: 42px !important;
|
|
|
|
| 878 |
}
|
| 879 |
-
.controls-row .gradio-
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 883 |
border: 1px solid #2a2a3e !important;
|
| 884 |
-
border-radius: 8px;
|
| 885 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 886 |
}
|
| 887 |
-
|
| 888 |
-
|
|
|
|
| 889 |
.controls-row .gradio-slider > label > div {
|
| 890 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 891 |
}
|
| 892 |
-
|
| 893 |
-
|
| 894 |
-
|
| 895 |
-
|
| 896 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 897 |
}
|
| 898 |
|
| 899 |
/* Generate button */
|
|
@@ -973,18 +1069,16 @@ with gr.Blocks(title="BlueTTS โ Multilingual TTS") as demo:
|
|
| 973 |
value="ืืืื ืืฉื ืืช ืืชืืื ืืจืืข ืฉืื ืืชื ืืืืื ืฉืื ืืคืฉืจื!",
|
| 974 |
)
|
| 975 |
|
| 976 |
-
with gr.Row(
|
| 977 |
-
|
| 978 |
-
|
| 979 |
-
|
| 980 |
-
|
| 981 |
-
|
| 982 |
-
|
| 983 |
-
|
| 984 |
-
|
| 985 |
-
|
| 986 |
-
with gr.Column(scale=2, min_width=150):
|
| 987 |
-
speed_input = gr.Slider(0.5, 2.0, 1.0, step=0.05, label="Speed")
|
| 988 |
|
| 989 |
btn = gr.Button("โก Generate Speech", elem_classes="gen-btn")
|
| 990 |
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Gradio Space for BlueTTS โ multilingual ONNX TTS.
|
| 3 |
+
Upstream: https://github.com/maxmelichov/BlueTTS
|
| 4 |
+
"""
|
| 5 |
import os
|
| 6 |
import re
|
| 7 |
import sys
|
|
|
|
| 866 |
.gradio-textbox label span, .gradio-dropdown label span,
|
| 867 |
.gradio-radio label span, .gradio-slider label span { color: #9ca3af !important; font-size: 0.8rem !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: 0.05em !important; }
|
| 868 |
|
| 869 |
+
/* Controls grid โ 4 equal cells, all top-aligned */
|
| 870 |
+
.controls-row {
|
| 871 |
+
margin-top: 1.25rem;
|
| 872 |
+
display: grid !important;
|
| 873 |
+
grid-template-columns: repeat(4, 1fr) !important;
|
| 874 |
+
gap: 0.75rem !important;
|
| 875 |
+
align-items: start !important;
|
| 876 |
+
}
|
| 877 |
+
/* Remove any Gradio flex overrides inside the row */
|
| 878 |
+
.controls-row > div,
|
| 879 |
+
.controls-row > div > div { all: unset; display: contents; }
|
| 880 |
+
|
| 881 |
+
/* Shared label style for all four controls */
|
| 882 |
+
.controls-row .gradio-dropdown > label > span,
|
| 883 |
+
.controls-row .gradio-radio > fieldset > legend > span,
|
| 884 |
+
.controls-row .gradio-slider > label > span {
|
| 885 |
+
display: block !important;
|
| 886 |
+
color: #9ca3af !important;
|
| 887 |
+
font-size: 0.75rem !important;
|
| 888 |
+
font-weight: 600 !important;
|
| 889 |
+
text-transform: uppercase !important;
|
| 890 |
+
letter-spacing: 0.06em !important;
|
| 891 |
+
margin-bottom: 0.4rem !important;
|
| 892 |
+
line-height: 1 !important;
|
| 893 |
+
}
|
| 894 |
+
|
| 895 |
+
/* Shared control surface height */
|
| 896 |
+
.ctrl-surface {
|
| 897 |
+
background: #0d0d14;
|
| 898 |
+
border: 1px solid #2a2a3e;
|
| 899 |
+
border-radius: 8px;
|
| 900 |
+
height: 42px;
|
| 901 |
+
display: flex;
|
| 902 |
+
align-items: center;
|
| 903 |
+
padding: 0 0.75rem;
|
| 904 |
+
transition: border-color 0.2s;
|
| 905 |
+
}
|
| 906 |
+
.ctrl-surface:focus-within { border-color: #60a5fa; }
|
| 907 |
+
|
| 908 |
+
/* Dropdown */
|
| 909 |
+
.controls-row .gradio-dropdown { display: block !important; }
|
| 910 |
.controls-row .gradio-dropdown > label > div {
|
| 911 |
background: #0d0d14 !important;
|
| 912 |
border: 1px solid #2a2a3e !important;
|
| 913 |
border-radius: 8px !important;
|
| 914 |
color: #e8e8f0 !important;
|
| 915 |
min-height: 42px !important;
|
| 916 |
+
padding: 0 0.75rem !important;
|
| 917 |
}
|
| 918 |
+
.controls-row .gradio-dropdown > label > div:focus-within {
|
| 919 |
+
border-color: #60a5fa !important;
|
| 920 |
+
}
|
| 921 |
+
|
| 922 |
+
/* Radio โ horizontal pills */
|
| 923 |
+
.controls-row .gradio-radio { display: block !important; }
|
| 924 |
+
.controls-row .gradio-radio > fieldset {
|
| 925 |
+
border: none !important;
|
| 926 |
+
padding: 0 !important;
|
| 927 |
+
margin: 0 !important;
|
| 928 |
+
background: transparent !important;
|
| 929 |
+
}
|
| 930 |
+
.controls-row .gradio-radio > fieldset > div {
|
| 931 |
+
display: flex !important;
|
| 932 |
+
flex-direction: row !important;
|
| 933 |
+
gap: 0.4rem !important;
|
| 934 |
+
flex-wrap: wrap !important;
|
| 935 |
+
}
|
| 936 |
+
.controls-row .gradio-radio > fieldset > div > label {
|
| 937 |
+
flex: 1 !important;
|
| 938 |
+
display: flex !important;
|
| 939 |
+
align-items: center !important;
|
| 940 |
+
justify-content: center !important;
|
| 941 |
+
height: 42px !important;
|
| 942 |
+
background: #0d0d14 !important;
|
| 943 |
border: 1px solid #2a2a3e !important;
|
| 944 |
+
border-radius: 8px !important;
|
| 945 |
+
cursor: pointer !important;
|
| 946 |
+
transition: border-color 0.2s, background 0.2s !important;
|
| 947 |
+
padding: 0 0.5rem !important;
|
| 948 |
+
white-space: nowrap !important;
|
| 949 |
+
}
|
| 950 |
+
.controls-row .gradio-radio > fieldset > div > label:has(input:checked) {
|
| 951 |
+
background: #1a2744 !important;
|
| 952 |
+
border-color: #60a5fa !important;
|
| 953 |
+
}
|
| 954 |
+
.controls-row .gradio-radio > fieldset > div > label > input[type=radio] {
|
| 955 |
+
display: none !important;
|
| 956 |
+
}
|
| 957 |
+
.controls-row .gradio-radio > fieldset > div > label > span {
|
| 958 |
+
color: #c4c4d4 !important;
|
| 959 |
+
font-size: 0.85rem !important;
|
| 960 |
+
font-weight: 500 !important;
|
| 961 |
+
text-transform: none !important;
|
| 962 |
+
letter-spacing: normal !important;
|
| 963 |
+
}
|
| 964 |
+
.controls-row .gradio-radio > fieldset > div > label:has(input:checked) > span {
|
| 965 |
+
color: #60a5fa !important;
|
| 966 |
}
|
| 967 |
+
|
| 968 |
+
/* Sliders */
|
| 969 |
+
.controls-row .gradio-slider { display: block !important; }
|
| 970 |
.controls-row .gradio-slider > label > div {
|
| 971 |
+
background: #0d0d14 !important;
|
| 972 |
+
border: 1px solid #2a2a3e !important;
|
| 973 |
+
border-radius: 8px !important;
|
| 974 |
+
height: 42px !important;
|
| 975 |
+
display: flex !important;
|
| 976 |
+
align-items: center !important;
|
| 977 |
+
padding: 0 0.75rem !important;
|
| 978 |
+
gap: 0.6rem !important;
|
| 979 |
}
|
| 980 |
+
.controls-row .gradio-slider > label > div > input[type=range] {
|
| 981 |
+
flex: 1 !important;
|
| 982 |
+
accent-color: #60a5fa !important;
|
| 983 |
+
margin: 0 !important;
|
| 984 |
+
}
|
| 985 |
+
.controls-row .gradio-slider > label > div > input[type=number] {
|
| 986 |
+
background: transparent !important;
|
| 987 |
+
border: none !important;
|
| 988 |
+
color: #9ca3af !important;
|
| 989 |
+
font-size: 0.8rem !important;
|
| 990 |
+
width: 3rem !important;
|
| 991 |
+
text-align: right !important;
|
| 992 |
+
padding: 0 !important;
|
| 993 |
}
|
| 994 |
|
| 995 |
/* Generate button */
|
|
|
|
| 1069 |
value="ืืืื ืืฉื ืืช ืืชืืื ืืจืืข ืฉืื ืืชื ืืืืื ืฉืื ืืคืฉืจื!",
|
| 1070 |
)
|
| 1071 |
|
| 1072 |
+
with gr.Row(elem_classes="controls-row"):
|
| 1073 |
+
lang_input = gr.Dropdown(
|
| 1074 |
+
choices=[("Hebrew ๐ฎ๐ฑ", "he"), ("English ๐บ๐ธ", "en"), ("Spanish ๐ช๐ธ", "es"), ("German ๐ฉ๐ช", "de"), ("Italian ๐ฎ๐น", "it")],
|
| 1075 |
+
value="he", label="Language", elem_id="ctrl-lang",
|
| 1076 |
+
)
|
| 1077 |
+
voice_input = gr.Radio(
|
| 1078 |
+
choices=list(VOICES.keys()), value="Female 1", label="Voice", elem_id="ctrl-voice",
|
| 1079 |
+
)
|
| 1080 |
+
steps_input = gr.Slider(2, 16, 8, step=1, label="Quality (steps)", elem_id="ctrl-steps")
|
| 1081 |
+
speed_input = gr.Slider(0.5, 2.0, 1.0, step=0.05, label="Speed", elem_id="ctrl-speed")
|
|
|
|
|
|
|
| 1082 |
|
| 1083 |
btn = gr.Button("โก Generate Speech", elem_classes="gen-btn")
|
| 1084 |
|
pyproject.toml
CHANGED
|
@@ -16,4 +16,4 @@ dependencies = [
|
|
| 16 |
|
| 17 |
[tool.uv.sources]
|
| 18 |
renikud-onnx = { git = "https://github.com/thewh1teagle/renikud-v5.git", subdirectory = "renikud-onnx" }
|
| 19 |
-
lightblue-onnx = { git = "https://github.com/maxmelichov/
|
|
|
|
| 16 |
|
| 17 |
[tool.uv.sources]
|
| 18 |
renikud-onnx = { git = "https://github.com/thewh1teagle/renikud-v5.git", subdirectory = "renikud-onnx" }
|
| 19 |
+
lightblue-onnx = { git = "https://github.com/maxmelichov/BlueTTS" }
|
requirements.txt
CHANGED
|
@@ -103,7 +103,7 @@ jsonschema-specifications==2025.9.1
|
|
| 103 |
# via jsonschema
|
| 104 |
language-tags==1.2.0
|
| 105 |
# via csvw
|
| 106 |
-
lightblue-onnx @ git+https://github.com/maxmelichov/
|
| 107 |
# via styletts2-hebrew
|
| 108 |
markdown-it-py==4.0.0
|
| 109 |
# via rich
|
|
|
|
| 103 |
# via jsonschema
|
| 104 |
language-tags==1.2.0
|
| 105 |
# via csvw
|
| 106 |
+
lightblue-onnx @ git+https://github.com/maxmelichov/BlueTTS
|
| 107 |
# via styletts2-hebrew
|
| 108 |
markdown-it-py==4.0.0
|
| 109 |
# via rich
|
uv.lock
CHANGED
|
@@ -658,7 +658,7 @@ wheels = [
|
|
| 658 |
[[package]]
|
| 659 |
name = "lightblue-onnx"
|
| 660 |
version = "0.1.0"
|
| 661 |
-
source = { git = "https://github.com/maxmelichov/
|
| 662 |
dependencies = [
|
| 663 |
{ name = "numpy" },
|
| 664 |
{ name = "onnxruntime" },
|
|
@@ -1618,7 +1618,7 @@ dependencies = [
|
|
| 1618 |
requires-dist = [
|
| 1619 |
{ name = "espeakng-loader", specifier = ">=0.1.9" },
|
| 1620 |
{ name = "gradio", specifier = ">=6.9.0" },
|
| 1621 |
-
{ name = "lightblue-onnx", git = "https://github.com/maxmelichov/
|
| 1622 |
{ name = "num2words", specifier = ">=0.5.14" },
|
| 1623 |
{ name = "phonemizer-fork", specifier = ">=3.3.2" },
|
| 1624 |
{ name = "renikud-onnx", git = "https://github.com/thewh1teagle/renikud-v5.git?subdirectory=renikud-onnx" },
|
|
|
|
| 658 |
[[package]]
|
| 659 |
name = "lightblue-onnx"
|
| 660 |
version = "0.1.0"
|
| 661 |
+
source = { git = "https://github.com/maxmelichov/BlueTTS" }
|
| 662 |
dependencies = [
|
| 663 |
{ name = "numpy" },
|
| 664 |
{ name = "onnxruntime" },
|
|
|
|
| 1618 |
requires-dist = [
|
| 1619 |
{ name = "espeakng-loader", specifier = ">=0.1.9" },
|
| 1620 |
{ name = "gradio", specifier = ">=6.9.0" },
|
| 1621 |
+
{ name = "lightblue-onnx", git = "https://github.com/maxmelichov/BlueTTS" },
|
| 1622 |
{ name = "num2words", specifier = ">=0.5.14" },
|
| 1623 |
{ name = "phonemizer-fork", specifier = ">=3.3.2" },
|
| 1624 |
{ name = "renikud-onnx", git = "https://github.com/thewh1teagle/renikud-v5.git?subdirectory=renikud-onnx" },
|