Updates to Piper
This commit is contained in:
1 parent
1a5c10710d
commit
85f204c3f1
2 files changed
+798
-320
No files matched your search
@@ -0,0 +1,360 @@
|
|||||||
|
# help_content.py
|
||||||
|
# pylint: disable=no-member
|
||||||
|
|
||||||
|
class AllTalkHelpContent:
|
||||||
|
"""CSS and help content for help_content.py"""
|
||||||
|
custom_css = """
|
||||||
|
/* Add this to your existing CSS */
|
||||||
|
.gradio-container .prose {
|
||||||
|
max-width: none !important;
|
||||||
|
padding: 0.5rem !important; /* Reduced padding */
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-markdown div {
|
||||||
|
border: none !important; /* Remove the inner border */
|
||||||
|
margin-top: 0 !important; /* Remove top margin */
|
||||||
|
margin-bottom: 0 !important; /* Remove bottom margin */
|
||||||
|
padding-top: 0 !important; /* Remove top padding */
|
||||||
|
padding-bottom: 0 !important; /* Remove bottom padding */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the existing custom-markdown class */
|
||||||
|
.custom-markdown {
|
||||||
|
font-size: 15px !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
background-color: var(--background-fill-primary) !important;
|
||||||
|
border: 1px solid var(--border-color-primary) !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 0.5rem !important;
|
||||||
|
margin: 0 !important; /* Changed from 1rem 0 to 0 */
|
||||||
|
max-width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
/* Default text color for all content (grey) */
|
||||||
|
color: rgba(156, 163, 175, 1) !important; /* Adjust this grey value to match your interface */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make headings white */
|
||||||
|
.custom-markdown h1,
|
||||||
|
.custom-markdown h2,
|
||||||
|
.custom-markdown h3,
|
||||||
|
.custom-markdown h4,
|
||||||
|
.custom-markdown h5,
|
||||||
|
.custom-markdown h6 {
|
||||||
|
color: var(--heading-text-color, var(--body-text-color)) !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep all other elements in the grey color */
|
||||||
|
.custom-markdown p,
|
||||||
|
.custom-markdown li,
|
||||||
|
.custom-markdown ul,
|
||||||
|
.custom-markdown ol {
|
||||||
|
color: rgba(156, 163, 175, 1) !important; /* Same grey as the base text */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Additional targeting for any wrapping elements */
|
||||||
|
.gradio-container .prose > * {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the list item spacing in your existing CSS */
|
||||||
|
.custom-markdown li {
|
||||||
|
font-size: 0.95rem !important;
|
||||||
|
margin-bottom: 0.2rem !important; /* Reduced from 0.5rem to 0.3rem */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add specific styling for definition-style lists (like your Default, Recommendation, Tip items) */
|
||||||
|
.custom-markdown li p {
|
||||||
|
margin: 0 !important; /* Remove paragraph margins within list items */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If you need even tighter spacing for specific types of lists */
|
||||||
|
.custom-markdown li + li {
|
||||||
|
margin-top: 0.2rem !important; /* Space between consecutive list items */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure nested lists maintain proper spacing */
|
||||||
|
.custom-markdown li > ul,
|
||||||
|
.custom-markdown li > ol {
|
||||||
|
margin: 0.2rem 0 0.2rem 1rem !important; /* Reduced from 0.5rem */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consistent heading styles */
|
||||||
|
.custom-markdown h2 {
|
||||||
|
font-size: 1.2rem !important; /* Fixed size relative to root */
|
||||||
|
font-weight: 600 !important;
|
||||||
|
margin: 1.5rem 0 1rem !important;
|
||||||
|
color: var(--heading-text-color, var(--body-text-color)) !important;
|
||||||
|
border-bottom: 1px solid var(--border-color-primary) !important;
|
||||||
|
padding-bottom: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First paragraph styling */
|
||||||
|
.custom-markdown p:first-of-type {
|
||||||
|
font-size: 0.95rem !important; /* Match base size */
|
||||||
|
font-weight: 400 !important;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Regular paragraphs */
|
||||||
|
.custom-markdown p {
|
||||||
|
font-size: 0.95rem !important;
|
||||||
|
margin: 0.8rem 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List styling */
|
||||||
|
.custom-markdown ul,
|
||||||
|
.custom-markdown ol {
|
||||||
|
margin: 0.8rem 0 !important;
|
||||||
|
padding-left: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code styling */
|
||||||
|
.custom-markdown code {
|
||||||
|
font-family: ui-monospace, monospace !important;
|
||||||
|
background-color: var(--background-fill-secondary) !important;
|
||||||
|
padding: 0.2rem 0.4rem !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
font-size: 0.8rem !important; /* Slightly smaller than regular text */
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add styles for bold and emphasis */
|
||||||
|
.custom-markdown strong {
|
||||||
|
font-weight: 600 !important;
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-markdown em {
|
||||||
|
font-style: italic !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure both columns take equal width */
|
||||||
|
.gradio-row > div {
|
||||||
|
flex: 1 1 50% !important;
|
||||||
|
min-width: 0 !important; /* Prevents flex items from overflowing */
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION = """
|
||||||
|
## 🔊 TTS Engine Capabilities Help
|
||||||
|
|
||||||
|
This guide explains the various capabilities that **may** be available in different TTS engines and models. Each capability affects how the TTS engine processes and generates speech output.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION1 = """
|
||||||
|
## 🚀 Performance Features
|
||||||
|
|
||||||
|
- **DeepSpeed Capable**: Enables GPU acceleration using the DeepSpeed optimization library.
|
||||||
|
- **Requires**: NVIDIA GPU with CUDA support
|
||||||
|
- **Benefit**: Significantly faster text-to-speech generation
|
||||||
|
- **Note**: Model must specifically support DeepSpeed inference
|
||||||
|
|
||||||
|
- **Low VRAM Capable**: Optimized for systems with limited GPU memory.
|
||||||
|
- **Benefit**: Efficient memory management between CPU and GPU
|
||||||
|
- **Use Case**: Ideal when running alongside other GPU-intensive applications like LLMs
|
||||||
|
- **Note**: May trade speed for memory efficiency
|
||||||
|
|
||||||
|
- **Streaming Capable**: Enables real-time speech generation.
|
||||||
|
- **Benefit**: Immediate playback without generating entire audio first
|
||||||
|
- **Use Case**: Interactive applications and real-time responses
|
||||||
|
- **Note**: Not all output formats support streaming
|
||||||
|
|
||||||
|
## 🎵 Voice Control Features
|
||||||
|
|
||||||
|
- **Pitch Capable**: Allows adjustment of voice pitch.
|
||||||
|
- **Benefit**: Creates more expressive and varied speech output
|
||||||
|
- **Use Case**: Customizing voice characteristics
|
||||||
|
- **Note**: Adjustment range varies by model
|
||||||
|
|
||||||
|
- **Generation Speed Capable**: Controls speech rate.
|
||||||
|
- **Benefit**: Adjustable playback speed during generation
|
||||||
|
- **Use Case**: Creating faster or slower speech output
|
||||||
|
- **Note**: May affect audio quality at extreme settings
|
||||||
|
|
||||||
|
- **Temperature Capable**: Controls output randomness.
|
||||||
|
- **Benefit**: Adjustable speech variation and creativity
|
||||||
|
- **Use Case**: Balancing consistency vs. naturality
|
||||||
|
- **Note**: Higher values increase variation but may reduce quality
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION2 = """
|
||||||
|
## 🎯 Quality Enhancement Features
|
||||||
|
|
||||||
|
- **Repetition Penalty Capable**: Prevents unnatural speech patterns.
|
||||||
|
- **Benefit**: Reduces repeated sounds and phrases
|
||||||
|
- **Use Case**: Improving natural flow of longer texts
|
||||||
|
- **Note**: Strength of penalty may be adjustable
|
||||||
|
|
||||||
|
## 🌐 Multi-Feature Support
|
||||||
|
|
||||||
|
- **Multi-Languages Capable Models**: Each model Supports multiple languages.
|
||||||
|
- **Benefit**: Generate speech in different languages
|
||||||
|
- **Note**: Quality may vary between languages
|
||||||
|
- **Tip**: Check model-specific language support
|
||||||
|
|
||||||
|
- **Multi-Voice Capable**: Supports multiple speaking voices.
|
||||||
|
- **Benefit**: Different voices or speaking styles
|
||||||
|
- **Types**: Pre-trained voices or voice cloning
|
||||||
|
- **Note**: Voice quality may vary by model
|
||||||
|
|
||||||
|
- **Multi-Model Capable Engine**: Supports multiple TTS models.
|
||||||
|
- **Benefit**: Flexibility in model selection
|
||||||
|
- **Use Case**: Switching between models for different needs
|
||||||
|
- **Note**: Each model may have different capabilities
|
||||||
|
|
||||||
|
## 📁 Technical Features
|
||||||
|
|
||||||
|
- **Default Audio Output Format**: Specifies output file format.
|
||||||
|
- **Common Formats**: WAV, MP3, FLAC, Opus, AAC, PCM
|
||||||
|
- **Note**: Transcoding to different formats adds processing time
|
||||||
|
- **Warning**: Not all formats support streaming
|
||||||
|
|
||||||
|
- **Platform Support**: Operating system compatibility.
|
||||||
|
- **Platforms**: Windows, Linux, macOS
|
||||||
|
- **Note**: Additional setup may be required
|
||||||
|
- **Warning**: Support level may vary by platform
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS = """
|
||||||
|
## 🎯 TTS Engine Settings Help
|
||||||
|
|
||||||
|
This guide explains the settings and configuration options available for individual Text-to-Speech engines within AllTalk.
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS1 = """
|
||||||
|
## 🎚️ Engine Capabilities & Controls
|
||||||
|
|
||||||
|
- **Low VRAM Mode**
|
||||||
|
- Optimizes memory usage for systems with limited GPU memory
|
||||||
|
- Efficiently manages resources by moving data between CPU and GPU
|
||||||
|
- Recommended for systems with less than 4GB VRAM or when running alongside other GPU-intensive applications
|
||||||
|
|
||||||
|
- **DeepSpeed Capability**
|
||||||
|
- Accelerates TTS generation using optimized inference
|
||||||
|
- Only available for engines and models that support DeepSpeed
|
||||||
|
- Requires NVIDIA GPU with CUDA support
|
||||||
|
|
||||||
|
- **Temperature Control**
|
||||||
|
- Adjusts the variability in speech generation
|
||||||
|
- **Range**: 0.0 to 1.0
|
||||||
|
- **Lower values** (0.1-0.5): More consistent, stable output
|
||||||
|
- **Higher values** (0.6-1.0): More variable, potentially more natural-sounding output
|
||||||
|
|
||||||
|
- **Repetition Penalty**
|
||||||
|
- Helps prevent repetitive speech patterns
|
||||||
|
- **Range**: 1.0 to 15.0
|
||||||
|
- Higher values more strongly discourage repetition
|
||||||
|
- Typically most effective between 1.0-3.0
|
||||||
|
|
||||||
|
- **Pitch Adjustment**
|
||||||
|
- Modifies the voice pitch when supported
|
||||||
|
- **Range**: -20 to +20
|
||||||
|
- Use subtle adjustments for most natural results
|
||||||
|
|
||||||
|
- **Generation Speed**
|
||||||
|
- Controls the pace of generated speech
|
||||||
|
- **Range**: 0.5 to 2.0
|
||||||
|
- 1.0 represents normal speed
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS2 = """
|
||||||
|
|
||||||
|
## 🗣️ Voice Configuration
|
||||||
|
|
||||||
|
### OpenAI Voice Mappings
|
||||||
|
- Only relevant when using the OpenAI-compatible API endpoint
|
||||||
|
- Maps OpenAI's six standard voices to equivalent voices in the current engine:
|
||||||
|
- `alloy`
|
||||||
|
- `echo`
|
||||||
|
- `fable`
|
||||||
|
- `nova`
|
||||||
|
- `onyx`
|
||||||
|
- `shimmer`
|
||||||
|
- Essential for maintaining compatibility with OpenAI API calls
|
||||||
|
- Each mapping can be customized to any available voice in the current engine
|
||||||
|
|
||||||
|
Information on the OpenAI Endpoint is available in the [Github Wiki](https://github.com/erew123/alltalk_tts/wiki)
|
||||||
|
|
||||||
|
### Default Voices
|
||||||
|
- **Default/Character Voice**: Used when no specific voice is specified in API calls
|
||||||
|
- **Narrator Voice**: Separate default for narrator-specific text
|
||||||
|
- These defaults are engine-specific and won't affect other TTS engines
|
||||||
|
- Can be overridden by explicitly specifying voices in API calls
|
||||||
|
|
||||||
|
## ⚙️ Important Notes
|
||||||
|
|
||||||
|
- Settings availability is determined by engine capabilities
|
||||||
|
- Grayed-out options indicate features not supported by the current engine
|
||||||
|
- Changes only affect the currently selected TTS engine
|
||||||
|
- Settings here act as defaults but can be overridden via API parameters
|
||||||
|
- All changes require clicking "Update Settings" to take effect
|
||||||
|
- Some settings require an engine reload to take effect
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE = """
|
||||||
|
## 🎯 Piper TTS Engine Help
|
||||||
|
|
||||||
|
Piper is a fast, local neural Text-to-Speech system designed for efficient performance with high-quality output.
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE1 = """
|
||||||
|
## 📁 File Locations & Management
|
||||||
|
|
||||||
|
- **Model Storage**
|
||||||
|
- Models are stored in `/alltalk_tts/models/piper/`
|
||||||
|
- Each model consists of two required files:
|
||||||
|
- `.onnx` file (the voice model)
|
||||||
|
- `.onnx.json` file (model configuration)
|
||||||
|
|
||||||
|
- **Output Files**
|
||||||
|
- Generated audio is saved to `/alltalk_tts/outputs/`
|
||||||
|
- Automatic cleanup available via `Del WAV's older than` setting
|
||||||
|
- When enabled, old files are removed on startup
|
||||||
|
- Set to `Disabled` to preserve all output files
|
||||||
|
|
||||||
|
## 🗣️ Voice System
|
||||||
|
|
||||||
|
- **Built-in Voices**
|
||||||
|
- Voices are integrated into the models themselves
|
||||||
|
- No separate voice files needed
|
||||||
|
- Each model represents a complete voice with its own characteristics
|
||||||
|
- Models are organized by language and quality levels (x_low, low, medium, high)
|
||||||
|
|
||||||
|
- **Language Support**
|
||||||
|
- Wide range of languages available
|
||||||
|
- Models named using language codes (e.g., en_US, de_DE)
|
||||||
|
- Multiple voice options per language
|
||||||
|
- Different quality levels for varying needs
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE2 = """
|
||||||
|
## ⚡ Performance Features
|
||||||
|
|
||||||
|
- **Quality Levels**
|
||||||
|
- `x_low`: Fastest, lowest resource usage
|
||||||
|
- `low`: Good balance of speed and quality
|
||||||
|
- `medium`: Higher quality, moderate resources
|
||||||
|
- `high`: Best quality, higher resource usage
|
||||||
|
|
||||||
|
## 📝 Important Notes
|
||||||
|
|
||||||
|
- **Model Names**
|
||||||
|
- Format: `[language_code]-[voice_name]-[quality]`
|
||||||
|
- Example: `en_US-lessac-medium`
|
||||||
|
- Indicates language, speaker, and quality level
|
||||||
|
|
||||||
|
- **Best Practices**
|
||||||
|
- Choose quality level based on your system capabilities
|
||||||
|
- Use appropriate language model for your text
|
||||||
|
|
||||||
|
## 🔄 Model Downloads
|
||||||
|
|
||||||
|
- Models can be downloaded individually or as language packs
|
||||||
|
- All models are sourced from the official Piper repository
|
||||||
|
- Downloads include both required files automatically
|
||||||
|
- Models can be managed through the Models/Voices Download tab
|
||||||
|
"""
|
||||||
@@ -1,320 +1,438 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
import gradio as gr
|
import gradio as gr
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
this_dir = Path(__file__).parent.resolve() # Sets up self.this_dir as a variable for the folder THIS script is running in.
|
from .help_content import AllTalkHelpContent
|
||||||
main_dir = Path(__file__).parent.parent.parent.parent.resolve() # Sets up self.main_dir as a variable for the folder AllTalk is running in
|
this_dir = Path(__file__).parent.resolve() # Sets up self.this_dir as a variable for the folder THIS script is running in.
|
||||||
|
main_dir = Path(__file__).parent.parent.parent.parent.resolve() # Sets up self.main_dir as a variable for the folder AllTalk is running in
|
||||||
##########################################################################
|
|
||||||
# REQUIRED CHANGE #
|
##########################################################################
|
||||||
# Populate the voices list, using the method specific to your TTS engine #
|
# REQUIRED CHANGE #
|
||||||
##########################################################################
|
# Populate the voices list, using the method specific to your TTS engine #
|
||||||
# This function is responsible for populating the list of available voices for your TTS engine.
|
##########################################################################
|
||||||
# You need to modify this function to use the appropriate method for your engine to retrieve the voice list.
|
# This function is responsible for populating the list of available voices for your TTS engine.
|
||||||
#
|
# You need to modify this function to use the appropriate method for your engine to retrieve the voice list.
|
||||||
# The current implementation lists all the WAV files in a "voices" directory, which may not be suitable for your engine.
|
#
|
||||||
# You should replace the `xxxx_voices_file_list` function name to match your engine name. For example, if your engine
|
# The current implementation lists all the WAV files in a "voices" directory, which may not be suitable for your engine.
|
||||||
# is named "mytts", the function should be named `mytts_voices_file_list`.
|
# You should replace the `xxxx_voices_file_list` function name to match your engine name. For example, if your engine
|
||||||
#
|
# is named "mytts", the function should be named `mytts_voices_file_list`.
|
||||||
# You will also neef to update the code with your own implementation that retrieves the voice list according to your
|
#
|
||||||
# engine's specific requirements. Typically this is the same code as will be in your model_engine.py file.
|
# You will also neef to update the code with your own implementation that retrieves the voice list according to your
|
||||||
#
|
# engine's specific requirements. Typically this is the same code as will be in your model_engine.py file.
|
||||||
# For example, if your engine has a dedicated API or configuration file for managing voices, you should modify this
|
#
|
||||||
# function to interact with that API or read from that configuration file.
|
# For example, if your engine has a dedicated API or configuration file for managing voices, you should modify this
|
||||||
#
|
# function to interact with that API or read from that configuration file.
|
||||||
# After making the necessary changes, this function should return a list of available voices that can be used
|
#
|
||||||
# in your TTS engine's settings page.
|
# After making the necessary changes, this function should return a list of available voices that can be used
|
||||||
def piper_voices_file_list():
|
# in your TTS engine's settings page.
|
||||||
voices = []
|
def piper_voices_file_list():
|
||||||
models_dir = main_dir / "models" / "piper"
|
voices = []
|
||||||
|
models_dir = main_dir / "models" / "piper"
|
||||||
for root, dirs, files in os.walk(models_dir):
|
|
||||||
onnx_files = [file for file in files if file.endswith(".onnx")]
|
for root, dirs, files in os.walk(models_dir):
|
||||||
for onnx_file in onnx_files:
|
onnx_files = [file for file in files if file.endswith(".onnx")]
|
||||||
json_file = onnx_file + ".json"
|
for onnx_file in onnx_files:
|
||||||
if json_file in files:
|
json_file = onnx_file + ".json"
|
||||||
relative_path = os.path.relpath(os.path.join(root, onnx_file), models_dir)
|
if json_file in files:
|
||||||
voices.append(relative_path)
|
relative_path = os.path.relpath(os.path.join(root, onnx_file), models_dir)
|
||||||
|
voices.append(relative_path)
|
||||||
return voices
|
|
||||||
|
return voices
|
||||||
######################################################
|
|
||||||
# REQUIRED CHANGE #
|
# Load the available models from the JSON file
|
||||||
# Imports and saves the TTS engine-specific settings #
|
with open(os.path.join(this_dir, "available_models.json"), "r") as f:
|
||||||
######################################################
|
available_models = json.load(f)
|
||||||
# This function is responsible for importing and saving the settings specific to your TTS engine.
|
# Extract the model names for the dropdown
|
||||||
# You need to make the following change:
|
model_names = [model["model_name"] for model in available_models["models"]]
|
||||||
#
|
|
||||||
# 1. Change the name of the function `xxxx_model_update_settings` to match your engine's name.
|
#####################################################################
|
||||||
# For example, if your engine is named "mytts", the function should be named `mytts_model_update_settings`.
|
# Piper Specific section for grouping/downloading the models/voices #
|
||||||
#
|
#####################################################################
|
||||||
# After making this change, the function will load the model settings from a JSON file, update the settings and voice
|
|
||||||
# dictionaries with the values provided as arguments, and save the updated settings back to the JSON file.
|
def group_models_by_language():
|
||||||
#
|
"""Group available models by language code (first 2 letters)"""
|
||||||
# You do not need to modify the function's logic or any other part of the code.
|
language_groups = {}
|
||||||
def piper_model_update_settings(def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr):
|
|
||||||
# Load the model_config_data from the JSON file
|
for model in available_models["models"]:
|
||||||
with open(os.path.join(this_dir, "model_settings.json"), "r") as f:
|
model_name = model["model_name"]
|
||||||
model_config_data = json.load(f)
|
lang_code = model_name[:2] # Get first two letters (language code)
|
||||||
# Update the settings and openai_voices dictionaries with the new values
|
|
||||||
model_config_data["settings"]["def_character_voice"] = def_character_voice_gr
|
if lang_code not in language_groups:
|
||||||
model_config_data["settings"]["def_narrator_voice"] = def_narrator_voice_gr
|
language_groups[lang_code] = {
|
||||||
model_config_data["openai_voices"]["alloy"] = alloy_gr
|
"name": get_language_name(lang_code),
|
||||||
model_config_data["openai_voices"]["echo"] = echo_gr
|
"models": []
|
||||||
model_config_data["openai_voices"]["fable"] = fable_gr
|
}
|
||||||
model_config_data["openai_voices"]["nova"] = nova_gr
|
|
||||||
model_config_data["openai_voices"]["onyx"] = onyx_gr
|
language_groups[lang_code]["models"].append(model)
|
||||||
model_config_data["openai_voices"]["shimmer"] = shimmer_gr
|
|
||||||
model_config_data["settings"]["lowvram_enabled"] = lowvram_enabled_gr == "Enabled"
|
return language_groups
|
||||||
model_config_data["settings"]["deepspeed_enabled"] = deepspeed_enabled_gr == "Enabled"
|
|
||||||
model_config_data["settings"]["temperature_set"] = temperature_set_gr
|
def get_language_name(lang_code):
|
||||||
model_config_data["settings"]["repetitionpenalty_set"] = repetitionpenalty_set_gr
|
"""Convert language code to full name"""
|
||||||
model_config_data["settings"]["pitch_set"] = pitch_set_gr
|
language_names = {
|
||||||
model_config_data["settings"]["generationspeed_set"] = generationspeed_set_gr
|
"ar": "Arabic",
|
||||||
# Save the updated model_config_data to the JSON file
|
"ca": "Catalan",
|
||||||
with open(os.path.join(this_dir, "model_settings.json"), "w") as f:
|
"cs": "Czech",
|
||||||
json.dump(model_config_data, f, indent=4)
|
"da": "Danish",
|
||||||
return "Settings updated successfully!"
|
"de": "German",
|
||||||
|
"el": "Greek",
|
||||||
#######################################################
|
"en": "English",
|
||||||
# REQUIRED CHANGE #
|
"es": "Spanish",
|
||||||
# Sets up the engine-specific settings page in Gradio #
|
"fa": "Persian",
|
||||||
#######################################################
|
"fi": "Finnish",
|
||||||
# This function sets up the Gradio interface for the settings page specific to your TTS engine.
|
"fr": "French",
|
||||||
# You need to make the following changes:
|
"hu": "Hungarian",
|
||||||
#
|
"is": "Icelandic",
|
||||||
# 1. Change the name of the function `xxxx_model_alltalk_settings` to match your engine's name.
|
"it": "Italian",
|
||||||
# For example, if your engine is named "mytts", the function should be named `mytts_model_alltalk_settings`.
|
"ka": "Georgian",
|
||||||
#
|
"kk": "Kazakh",
|
||||||
# 2. Change the name of the `submit_button.click` function call to match the name you gave to the function
|
"lb": "Luxembourgish",
|
||||||
# that imports and saves your engine's settings (the function you modified above).
|
"ne": "Nepali",
|
||||||
#
|
"nl": "Dutch",
|
||||||
# 3. Change the name of the `voice_list` function call to match the name of the function that lists
|
"no": "Norwegian",
|
||||||
# the available voices for your TTS engine.
|
"pl": "Polish",
|
||||||
#
|
"pt": "Portuguese",
|
||||||
# 4. Change the 'title' of the `gr.Blocks` to match your engine's name e.g. title="mytts TTS"
|
"ro": "Romanian",
|
||||||
#
|
"ru": "Russian",
|
||||||
# After making these changes, this function will create and return the Gradio interface for your TTS engine's
|
"sk": "Slovak",
|
||||||
# settings page, allowing users to configure various options and voice selections.
|
"sl": "Slovenian",
|
||||||
def piper_model_alltalk_settings(model_config_data):
|
"sr": "Serbian",
|
||||||
features_list = model_config_data['model_capabilties']
|
"sv": "Swedish",
|
||||||
voice_list = piper_voices_file_list()
|
"sw": "Swahili",
|
||||||
with gr.Blocks(title="piper TTS", analytics_enabled=False) as app:
|
"tr": "Turkish",
|
||||||
with gr.Tab("Default Settings"):
|
"uk": "Ukrainian",
|
||||||
with gr.Row():
|
"vi": "Vietnamese",
|
||||||
lowvram_enabled_gr = gr.Radio(choices={"Enabled": "true", "Disabled": "false"}, label="Low VRAM" if model_config_data["model_capabilties"]["lowvram_capable"] else "Low VRAM N/A", value="Enabled" if model_config_data["settings"]["lowvram_enabled"] else "Disabled", interactive=model_config_data["model_capabilties"]["lowvram_capable"])
|
"zh": "Chinese"
|
||||||
deepspeed_enabled_gr = gr.Radio(choices={"Enabled": "true", "Disabled": "false"}, label="DeepSpeed Activate" if model_config_data["model_capabilties"]["deepspeed_capable"] else "DeepSpeed N/A", value="Enabled" if model_config_data["settings"]["deepspeed_enabled"] else "Disabled", interactive=model_config_data["model_capabilties"]["deepspeed_capable"])
|
}
|
||||||
temperature_set_gr = gr.Slider(value=float(model_config_data["settings"]["temperature_set"]), minimum=0, maximum=1, step=0.05, label="Temperature" if model_config_data["model_capabilties"]["temperature_capable"] else "Temperature N/A", interactive=model_config_data["model_capabilties"]["temperature_capable"])
|
return language_names.get(lang_code, f"Unknown ({lang_code})")
|
||||||
repetitionpenalty_set_gr = gr.Slider(value=float(model_config_data["settings"]["repetitionpenalty_set"]), minimum=1, maximum=20, step=1, label="Repetition Penalty" if model_config_data["model_capabilties"]["repetitionpenalty_capable"] else "Repetition N/A", interactive=model_config_data["model_capabilties"]["repetitionpenalty_capable"])
|
|
||||||
pitch_set_gr = gr.Slider(value=float(model_config_data["settings"]["pitch_set"]), minimum=-10, maximum=10, step=1, label="Pitch" if model_config_data["model_capabilties"]["pitch_capable"] else "Pitch N/A", interactive=model_config_data["model_capabilties"]["pitch_capable"])
|
def download_model(model_name, force_download=False):
|
||||||
generationspeed_set_gr = gr.Slider(value=float(model_config_data["settings"]["generationspeed_set"]), minimum=0.25, maximum=2.00, step=0.25, label="Speed" if model_config_data["model_capabilties"]["generationspeed_capable"] else "Speed N/A", interactive=model_config_data["model_capabilties"]["generationspeed_capable"])
|
# Find the selected model in the available models
|
||||||
with gr.Row():
|
selected_model = next(model for model in available_models["models"] if model["model_name"] == model_name)
|
||||||
with gr.Column():
|
# Get the folder path and files to download
|
||||||
gr.Markdown("### OpenAI Voice Mappings")
|
folder_path = os.path.join(main_dir, "models", "piper")
|
||||||
with gr.Group():
|
files_to_download = selected_model["files_to_download"]
|
||||||
with gr.Row():
|
# Check if all files are already downloaded
|
||||||
alloy_gr = gr.Dropdown(value=model_config_data["openai_voices"]["alloy"], label="Alloy", choices=voice_list, allow_custom_value=True)
|
all_files_exists = all(os.path.exists(os.path.join(folder_path, os.path.basename(url.split('?')[0]))) for url in files_to_download)
|
||||||
echo_gr = gr.Dropdown(value=model_config_data["openai_voices"]["echo"], label="Echo", choices=voice_list, allow_custom_value=True)
|
if all_files_exists and not force_download:
|
||||||
with gr.Row():
|
return "All files are already downloaded. No need to download again."
|
||||||
fable_gr = gr.Dropdown(value=model_config_data["openai_voices"]["fable"], label="Fable", choices=voice_list, allow_custom_value=True)
|
else:
|
||||||
nova_gr = gr.Dropdown(value=model_config_data["openai_voices"]["nova"], label="Nova", choices=voice_list, allow_custom_value=True)
|
# Create the folder if it doesn't exist
|
||||||
with gr.Row():
|
os.makedirs(folder_path, exist_ok=True)
|
||||||
onyx_gr = gr.Dropdown(value=model_config_data["openai_voices"]["onyx"], label="Onyx", choices=voice_list, allow_custom_value=True)
|
# Download the missing files
|
||||||
shimmer_gr = gr.Dropdown(value=model_config_data["openai_voices"]["shimmer"], label="Shimmer", choices=voice_list, allow_custom_value=True)
|
for url in files_to_download:
|
||||||
with gr.Column():
|
file_name = os.path.basename(url.split('?')[0])
|
||||||
gr.Markdown("### Default Voices")
|
file_path = os.path.join(folder_path, file_name)
|
||||||
with gr.Row():
|
if not os.path.exists(file_path) or force_download:
|
||||||
def_character_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_character_voice"], label="Default/Character Voice", choices=voice_list, allow_custom_value=True)
|
print(f"Downloading {file_name}...")
|
||||||
def_narrator_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_narrator_voice"], label="Narrator Voice", choices=voice_list, allow_custom_value=True)
|
response = requests.get(url, stream=True)
|
||||||
with gr.Group():
|
total_size_in_bytes = int(response.headers.get("content-length", 0))
|
||||||
with gr.Row():
|
block_size = 1024 # 1 Kibibyte
|
||||||
details_text = gr.Textbox(label="Details", show_label=False, lines=5, interactive=False, value="In this section, you can set the default settings for this TTS engine. Settings that are not supported by the current engine will be greyed out and cannot be selected. Default voices specified here will be used when no specific voice is provided in the TTS generation request. If a voice is specified in the request, it will override these default settings. When using the OpenAI API compatable API with this TTS engine, the voice mappings will be applied. As the OpenAI API has a limited set of 6 voices, these mappings ensure compatibility by mapping the OpenAI voices to the available voices in this TTS engine.")
|
progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True)
|
||||||
with gr.Row():
|
with open(file_path, "wb") as file:
|
||||||
submit_button = gr.Button("Update Settings")
|
for data in response.iter_content(block_size):
|
||||||
output_message = gr.Textbox(label="Output Message", interactive=False, show_label=False)
|
progress_bar.update(len(data))
|
||||||
submit_button.click(piper_model_update_settings, inputs=[def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr], outputs=output_message)
|
file.write(data)
|
||||||
|
progress_bar.close()
|
||||||
###########################################################################################
|
return "Model downloaded successfully!"
|
||||||
# Do not change this section apart from "TTS Engine Name" value to match your engine name #
|
|
||||||
###########################################################################################
|
def download_language_pack(lang_code, progress=gr.Progress()):
|
||||||
with gr.Tab("Engine Information"):
|
"""Download all models for a specific language"""
|
||||||
with gr.Row():
|
language_groups = group_models_by_language()
|
||||||
with gr.Group():
|
if lang_code not in language_groups:
|
||||||
gr.Textbox(label="Manufacturer Name", value=model_config_data['model_details']['manufacturer_name'], interactive=False)
|
return f"Error: Language pack {lang_code} not found"
|
||||||
gr.Textbox(label="Manufacturer Website/TTS Engine Support", value=model_config_data['model_details']['manufacturer_website'], interactive=False)
|
|
||||||
gr.Textbox(label="Engine/Model Description", value=model_config_data['model_details']['model_description'], interactive=False, lines=13)
|
models = language_groups[lang_code]["models"]
|
||||||
with gr.Column():
|
total_models = len(models)
|
||||||
with gr.Row():
|
|
||||||
gr.Textbox(label="DeepSpeed Capable", value='Yes' if features_list['deepspeed_capable'] else 'No', interactive=False)
|
progress(0, desc=f"Downloading {get_language_name(lang_code)} voice pack")
|
||||||
gr.Textbox(label="Pitch Capable", value='Yes' if features_list['pitch_capable'] else 'No', interactive=False)
|
|
||||||
gr.Textbox(label="Generation Speed Capable", value='Yes' if features_list['generationspeed_capable'] else 'No', interactive=False)
|
folder_path = os.path.join(main_dir, "models", "piper")
|
||||||
with gr.Row():
|
os.makedirs(folder_path, exist_ok=True)
|
||||||
gr.Textbox(label="Repetition Penalty Capable", value='Yes' if features_list['repetitionpenalty_capable'] else 'No', interactive=False)
|
|
||||||
gr.Textbox(label="Multi Languages Capable", value='Yes' if features_list['languages_capable'] else 'No', interactive=False)
|
downloaded_files = []
|
||||||
gr.Textbox(label="Streaming Capable", value='Yes' if features_list['streaming_capable'] else 'No', interactive=False)
|
errors = []
|
||||||
with gr.Row():
|
|
||||||
gr.Textbox(label="Low VRAM Capable", value='Yes' if features_list['lowvram_capable'] else 'No', interactive=False)
|
for idx, model in enumerate(models, 1):
|
||||||
gr.Textbox(label="Temperature Capable", value='Yes' if features_list['temperature_capable'] else 'No', interactive=False)
|
progress(idx/total_models, desc=f"Downloading model {idx}/{total_models}")
|
||||||
gr.Textbox(label="Multi Model Capable Engine", value='Yes' if features_list['multimodel_capable'] else 'No', interactive=False)
|
|
||||||
with gr.Row():
|
for url in model["files_to_download"]:
|
||||||
gr.Textbox(label="Multi Voice Capable Models", value='Yes' if features_list['multivoice_capable'] else 'No', interactive=False)
|
try:
|
||||||
gr.Textbox(label="Default Audio output format", value=model_config_data['model_capabilties']['audio_format'], interactive=False)
|
file_name = os.path.basename(url.split('?')[0])
|
||||||
gr.Textbox(label="TTS Engine Name", value="piper", interactive=False)
|
file_path = os.path.join(folder_path, file_name)
|
||||||
with gr.Row():
|
|
||||||
gr.Textbox(label="Windows Support", value='Yes' if features_list['windows_capable'] else 'No', interactive=False)
|
if not os.path.exists(file_path):
|
||||||
gr.Textbox(label="Linux Support", value='Yes' if features_list['linux_capable'] else 'No', interactive=False)
|
response = requests.get(url, stream=True)
|
||||||
gr.Textbox(label="Mac Support", value='Yes' if features_list['mac_capable'] else 'No', interactive=False)
|
total_size = int(response.headers.get("content-length", 0))
|
||||||
with gr.Row():
|
|
||||||
gr.Markdown("""
|
with open(file_path, "wb") as file:
|
||||||
#### 🟧 DeepSpeed Capable
|
for chunk in response.iter_content(chunk_size=1024):
|
||||||
DeepSpeed is a deep learning optimization library that can significantly speed up model training and inference. If a model is DeepSpeed capable, it means it can utilize DeepSpeed to accelerate the generation of text-to-speech output. This requires the model to be loaded into CUDA/VRAM on an Nvidia GPU and the model's inference method to support DeepSpeed.
|
if chunk:
|
||||||
#### 🟧 Pitch Capable
|
file.write(chunk)
|
||||||
Pitch refers to the highness or lowness of a sound. If a model is pitch capable, it can adjust the pitch of the generated speech, allowing for more expressive and varied output.
|
|
||||||
#### 🟧 Generation Speed Capable
|
downloaded_files.append(file_name)
|
||||||
Generation speed refers to the rate at which the model can generate text-to-speech output. If a model is generation speed capable, it means the speed of the generated speech can be adjusted, making it faster or slower depending on the desired output.
|
|
||||||
#### 🟧 Repetition Penalty Capable
|
except Exception as e:
|
||||||
Repetition penalty is a technique used to discourage the model from repeating the same words or phrases multiple times in the same sounding way. If a model is repetition penalty capable, it can apply this penalty during generation to improve the diversity and naturalness of the output.
|
errors.append(f"Error downloading {file_name}: {str(e)}")
|
||||||
#### 🟧 Multi-Languages Capable
|
|
||||||
Multi-language capable models can generate speech in multiple languages. This means that the model has been trained on data from different languages and can switch between them during generation. Some models are language-specific.
|
if errors:
|
||||||
#### 🟧 Multi-Voice Capable
|
return f"Downloaded {len(downloaded_files)} files with {len(errors)} errors:\n" + "\n".join(errors)
|
||||||
Multi-voice capable models generate speech in multiple voices or speaking styles. This means that the model has been trained on data from different speakers and can mimic their voices during generation, or is a voice cloning model that can generate speech based on the input sample.
|
else:
|
||||||
""")
|
return f"Successfully downloaded {len(downloaded_files)} files for {get_language_name(lang_code)}"
|
||||||
gr.Markdown("""
|
|
||||||
#### 🟧 Streaming Capable
|
|
||||||
Streaming refers to the ability to generate speech output in real-time, without the need to generate the entire output before playback. If a model is streaming capable, it can generate speech on-the-fly, allowing for faster response times and more interactive applications.
|
######################################################
|
||||||
#### 🟧 Low VRAM Capable
|
# REQUIRED CHANGE #
|
||||||
VRAM (Video Random Access Memory) is a type of memory used by GPUs to store and process data. If a model is low VRAM capable, it can efficiently utilize the available VRAM by moving data between CPU and GPU memory as needed, allowing for generation even on systems with limited VRAM where it may be competing with an LLM model for VRAM.
|
# Imports and saves the TTS engine-specific settings #
|
||||||
#### 🟧 Temperature Capable
|
######################################################
|
||||||
Temperature is a hyperparameter that controls the randomness of the generated output. If a model is temperature capable, the temperature can be adjusted to make the output more or less random, affecting the creativity and variability of the generated speech.
|
# This function is responsible for importing and saving the settings specific to your TTS engine.
|
||||||
#### 🟧 Multi-Model Capable Engine
|
# You need to make the following change:
|
||||||
If an engine is multi-model capable, it means that it can support and utilize multiple models for text-to-speech generation. This allows for greater flexibility and the ability to switch between different models depending on the desired output. Different models may be capable of different languages, specific languages, voices, etc.
|
#
|
||||||
#### 🟧 Default Audio Output Format
|
# 1. Change the name of the function `xxxx_model_update_settings` to match your engine's name.
|
||||||
Specifies the file format in which the generated speech will be saved. Common audio formats include WAV, MP3, FLAC, Opus, AAC, and PCM. If you want different outputs, you can set the transcode function to change the output audio, though transcoding will add a little time to the generation and is not available for streaming generation.
|
# For example, if your engine is named "mytts", the function should be named `mytts_model_update_settings`.
|
||||||
#### 🟧 Windows/Linux/Mac Support
|
#
|
||||||
These indicators show whether the model and engine are compatible with Windows, Linux, or macOS. However, additional setup or requirements may be necessary to ensure full functionality on your operating system. Please note that full platform support has not been extensively tested.
|
# After making this change, the function will load the model settings from a JSON file, update the settings and voice
|
||||||
""")
|
# dictionaries with the values provided as arguments, and save the updated settings back to the JSON file.
|
||||||
|
#
|
||||||
#######################################################################################################################################################################################################
|
# You do not need to modify the function's logic or any other part of the code.
|
||||||
# REQUIRED CHANGE #
|
def piper_model_update_settings(def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr):
|
||||||
# You will need to build a custom method to identify if your models are installed and download them. Store your models list in the available_models.json file, alongside your model_settings.json etc #
|
# Load the model_config_data from the JSON file
|
||||||
#######################################################################################################################################################################################################
|
with open(os.path.join(this_dir, "model_settings.json"), "r") as f:
|
||||||
with gr.Tab("Models/Voices Download"):
|
model_config_data = json.load(f)
|
||||||
with gr.Row():
|
# Update the settings and openai_voices dictionaries with the new values
|
||||||
# Load the available models from the JSON file
|
model_config_data["settings"]["def_character_voice"] = def_character_voice_gr
|
||||||
with open(os.path.join(this_dir, "available_models.json"), "r") as f:
|
model_config_data["settings"]["def_narrator_voice"] = def_narrator_voice_gr
|
||||||
available_models = json.load(f)
|
model_config_data["openai_voices"]["alloy"] = alloy_gr
|
||||||
# Extract the model names for the dropdown
|
model_config_data["openai_voices"]["echo"] = echo_gr
|
||||||
model_names = [model["model_name"] for model in available_models["models"]]
|
model_config_data["openai_voices"]["fable"] = fable_gr
|
||||||
# Create the dropdown
|
model_config_data["openai_voices"]["nova"] = nova_gr
|
||||||
model_dropdown = gr.Dropdown(choices=sorted(model_names), label="Select Model", value=model_names[0])
|
model_config_data["openai_voices"]["onyx"] = onyx_gr
|
||||||
download_button = gr.Button("Download Model/Missing Files")
|
model_config_data["openai_voices"]["shimmer"] = shimmer_gr
|
||||||
|
model_config_data["settings"]["lowvram_enabled"] = lowvram_enabled_gr == "Enabled"
|
||||||
def download_model(model_name, force_download=False):
|
model_config_data["settings"]["deepspeed_enabled"] = deepspeed_enabled_gr == "Enabled"
|
||||||
# Find the selected model in the available models
|
model_config_data["settings"]["temperature_set"] = temperature_set_gr
|
||||||
selected_model = next(model for model in available_models["models"] if model["model_name"] == model_name)
|
model_config_data["settings"]["repetitionpenalty_set"] = repetitionpenalty_set_gr
|
||||||
# Get the folder path and files to download
|
model_config_data["settings"]["pitch_set"] = pitch_set_gr
|
||||||
folder_path = os.path.join(main_dir, "models", "piper")
|
model_config_data["settings"]["generationspeed_set"] = generationspeed_set_gr
|
||||||
files_to_download = selected_model["files_to_download"]
|
# Save the updated model_config_data to the JSON file
|
||||||
# Check if all files are already downloaded
|
with open(os.path.join(this_dir, "model_settings.json"), "w") as f:
|
||||||
all_files_exists = all(os.path.exists(os.path.join(folder_path, os.path.basename(url.split('?')[0]))) for url in files_to_download)
|
json.dump(model_config_data, f, indent=4)
|
||||||
if all_files_exists and not force_download:
|
return "Settings updated successfully!"
|
||||||
return "All files are already downloaded. No need to download again."
|
|
||||||
else:
|
#######################################################
|
||||||
# Create the folder if it doesn't exist
|
# REQUIRED CHANGE #
|
||||||
os.makedirs(folder_path, exist_ok=True)
|
# Sets up the engine-specific settings page in Gradio #
|
||||||
# Download the missing files
|
#######################################################
|
||||||
for url in files_to_download:
|
# This function sets up the Gradio interface for the settings page specific to your TTS engine.
|
||||||
file_name = os.path.basename(url.split('?')[0])
|
# You need to make the following changes:
|
||||||
file_path = os.path.join(folder_path, file_name)
|
#
|
||||||
if not os.path.exists(file_path) or force_download:
|
# 1. Change the name of the function `xxxx_model_alltalk_settings` to match your engine's name.
|
||||||
print(f"Downloading {file_name}...")
|
# For example, if your engine is named "mytts", the function should be named `mytts_model_alltalk_settings`.
|
||||||
response = requests.get(url, stream=True)
|
#
|
||||||
total_size_in_bytes = int(response.headers.get("content-length", 0))
|
# 2. Change the name of the `submit_button.click` function call to match the name you gave to the function
|
||||||
block_size = 1024 # 1 Kibibyte
|
# that imports and saves your engine's settings (the function you modified above).
|
||||||
progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True)
|
#
|
||||||
with open(file_path, "wb") as file:
|
# 3. Change the name of the `voice_list` function call to match the name of the function that lists
|
||||||
for data in response.iter_content(block_size):
|
# the available voices for your TTS engine.
|
||||||
progress_bar.update(len(data))
|
#
|
||||||
file.write(data)
|
# 4. Change the 'title' of the `gr.Blocks` to match your engine's name e.g. title="mytts TTS"
|
||||||
progress_bar.close()
|
#
|
||||||
return "Model downloaded successfully!"
|
# After making these changes, this function will create and return the Gradio interface for your TTS engine's
|
||||||
|
# settings page, allowing users to configure various options and voice selections.
|
||||||
with gr.Row():
|
def piper_model_alltalk_settings(model_config_data):
|
||||||
download_status = gr.Textbox(label="Download Status")
|
features_list = model_config_data['model_capabilties']
|
||||||
|
voice_list = piper_voices_file_list()
|
||||||
download_button.click(download_model, inputs=model_dropdown, outputs=download_status)
|
with gr.Blocks(title="piper TTS", analytics_enabled=False) as app:
|
||||||
|
with gr.Tab("Default Settings"):
|
||||||
def show_confirm_cancel(model_name):
|
with gr.Row():
|
||||||
all_files_exists = all(os.path.exists(os.path.join(main_dir, "models", "piper", os.path.basename(file.split('?')[0]))) for model in available_models["models"] if model["model_name"] == model_name for file in model["files_to_download"])
|
lowvram_enabled_gr = gr.Radio(choices={"Enabled": "true", "Disabled": "false"}, label="Low VRAM" if model_config_data["model_capabilties"]["lowvram_capable"] else "Low VRAM N/A", value="Enabled" if model_config_data["settings"]["lowvram_enabled"] else "Disabled", interactive=model_config_data["model_capabilties"]["lowvram_capable"])
|
||||||
if all_files_exists:
|
deepspeed_enabled_gr = gr.Radio(choices={"Enabled": "true", "Disabled": "false"}, label="DeepSpeed Activate" if model_config_data["model_capabilties"]["deepspeed_capable"] else "DeepSpeed N/A", value="Enabled" if model_config_data["settings"]["deepspeed_enabled"] else "Disabled", interactive=model_config_data["model_capabilties"]["deepspeed_capable"])
|
||||||
return [gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)]
|
temperature_set_gr = gr.Slider(value=float(model_config_data["settings"]["temperature_set"]), minimum=0, maximum=1, step=0.05, label="Temperature" if model_config_data["model_capabilties"]["temperature_capable"] else "Temperature N/A", interactive=model_config_data["model_capabilties"]["temperature_capable"])
|
||||||
else:
|
repetitionpenalty_set_gr = gr.Slider(value=float(model_config_data["settings"]["repetitionpenalty_set"]), minimum=1, maximum=20, step=1, label="Repetition Penalty" if model_config_data["model_capabilties"]["repetitionpenalty_capable"] else "Repetition N/A", interactive=model_config_data["model_capabilties"]["repetitionpenalty_capable"])
|
||||||
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)]
|
pitch_set_gr = gr.Slider(value=float(model_config_data["settings"]["pitch_set"]), minimum=-10, maximum=10, step=1, label="Pitch" if model_config_data["model_capabilties"]["pitch_capable"] else "Pitch N/A", interactive=model_config_data["model_capabilties"]["pitch_capable"])
|
||||||
|
generationspeed_set_gr = gr.Slider(value=float(model_config_data["settings"]["generationspeed_set"]), minimum=0.25, maximum=2.00, step=0.25, label="Speed" if model_config_data["model_capabilties"]["generationspeed_capable"] else "Speed N/A", interactive=model_config_data["model_capabilties"]["generationspeed_capable"])
|
||||||
def confirm_download(model_name):
|
with gr.Row():
|
||||||
download_status_text = download_model(model_name, force_download=True)
|
with gr.Column():
|
||||||
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), download_status_text]
|
gr.Markdown("### OpenAI Voice Mappings")
|
||||||
|
with gr.Group():
|
||||||
def cancel_download():
|
with gr.Row():
|
||||||
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), ""]
|
alloy_gr = gr.Dropdown(value=model_config_data["openai_voices"]["alloy"], label="Alloy", choices=voice_list, allow_custom_value=True)
|
||||||
|
echo_gr = gr.Dropdown(value=model_config_data["openai_voices"]["echo"], label="Echo", choices=voice_list, allow_custom_value=True)
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
confirm_button = gr.Button("Download Anyway", visible=False)
|
fable_gr = gr.Dropdown(value=model_config_data["openai_voices"]["fable"], label="Fable", choices=voice_list, allow_custom_value=True)
|
||||||
cancel_button = gr.Button("Cancel", visible=False)
|
nova_gr = gr.Dropdown(value=model_config_data["openai_voices"]["nova"], label="Nova", choices=voice_list, allow_custom_value=True)
|
||||||
|
with gr.Row():
|
||||||
download_button.click(show_confirm_cancel, inputs=model_dropdown, outputs=[confirm_button, download_button, cancel_button])
|
onyx_gr = gr.Dropdown(value=model_config_data["openai_voices"]["onyx"], label="Onyx", choices=voice_list, allow_custom_value=True)
|
||||||
confirm_button.click(confirm_download, inputs=model_dropdown, outputs=[confirm_button, download_button, cancel_button, download_status])
|
shimmer_gr = gr.Dropdown(value=model_config_data["openai_voices"]["shimmer"], label="Shimmer", choices=voice_list, allow_custom_value=True)
|
||||||
cancel_button.click(cancel_download, inputs=None, outputs=[confirm_button, download_button, cancel_button, download_status])
|
with gr.Column():
|
||||||
|
gr.Markdown("### Default Voices")
|
||||||
###################################################################################################
|
with gr.Row():
|
||||||
# REQUIRED CHANGE #
|
def_character_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_character_voice"], label="Default/Character Voice", choices=voice_list, allow_custom_value=True)
|
||||||
# Add any engine specific help, bugs, issues, operating system specifc requirements/setup in here #
|
def_narrator_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_narrator_voice"], label="Narrator Voice", choices=voice_list, allow_custom_value=True)
|
||||||
# Please use Markdown format, so gr.Markdown() with your markdown inside it. #
|
with gr.Group():
|
||||||
###################################################################################################
|
with gr.Row():
|
||||||
with gr.Tab("Engine Help"):
|
details_text = gr.Textbox(label="Details", show_label=False, lines=5, interactive=False, value="Configure default settings and voice mappings for the selected TTS engine. Unavailable options are grayed out based on engine capabilities. See the Help section below for detailed information about each setting.")
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
gr.Markdown("""
|
submit_button = gr.Button("Update Settings")
|
||||||
### 🟧 Where are the Piper models stored?
|
output_message = gr.Textbox(label="Output Message", interactive=False, show_label=False)
|
||||||
This extension will download the models to `/alltalk_tts/models/piper/` folder.<br>
|
with gr.Accordion("HELP - 🔊 Understanding TTS Engine Default Settings Page", open=False):
|
||||||
|
with gr.Row():
|
||||||
### 🟧 Where are the voices stored for piper models?
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS, elem_classes="custom-markdown")
|
||||||
Piper models themselves are the voices/have the voices built into them. The models are made up of 2x files, an `onnx` file and a `onnx.json` file.<br>
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS1, elem_classes="custom-markdown")
|
||||||
### 🟧 Where are the outputs stored & Automatic output wav file deletion
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS2, elem_classes="custom-markdown")
|
||||||
Voice outputs are stored in `/alltalk_tts/outputs/`. You can configure automatic maintenance deletion of old wav files by setting `Del WAV's older than` in the global settings.<br>
|
submit_button.click(piper_model_update_settings, inputs=[def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr], outputs=output_message)
|
||||||
|
|
||||||
> When `Disabled`, your output wav files will be left untouched.<br>
|
###########################################################################################
|
||||||
> When set to a setting `1 Day` or greater, your output wav files older than that time period will be automatically deleted on start-up of AllTalk.<br>
|
# Do not change this section apart from "TTS Engine Name" value to match your engine name #
|
||||||
""")
|
###########################################################################################
|
||||||
gr.Markdown("""
|
with gr.Tab("Engine Information"):
|
||||||
""")
|
with gr.Row():
|
||||||
|
with gr.Group():
|
||||||
|
gr.Textbox(label="Manufacturer Name", value=model_config_data['model_details']['manufacturer_name'], interactive=False)
|
||||||
return app
|
gr.Textbox(label="Manufacturer Website/TTS Engine Support", value=model_config_data['model_details']['manufacturer_website'], interactive=False)
|
||||||
|
gr.Textbox(label="Engine/Model Description", value=model_config_data['model_details']['model_description'], interactive=False, lines=13)
|
||||||
################################
|
with gr.Column():
|
||||||
# REQUIRED CHANGE #
|
with gr.Row():
|
||||||
# Sets up the Gradio interface #
|
gr.Textbox(label="DeepSpeed Capable", value='Yes' if features_list['deepspeed_capable'] else 'No', interactive=False)
|
||||||
################################
|
gr.Textbox(label="Pitch Capable", value='Yes' if features_list['pitch_capable'] else 'No', interactive=False)
|
||||||
# This function sets up the Gradio interface for your TTS engine's settings page.
|
gr.Textbox(label="Generation Speed Capable", value='Yes' if features_list['generationspeed_capable'] else 'No', interactive=False)
|
||||||
# You need to change the name of the function calls to match the names you set in the functions above.
|
with gr.Row():
|
||||||
#
|
gr.Textbox(label="Repetition Penalty Capable", value='Yes' if features_list['repetitionpenalty_capable'] else 'No', interactive=False)
|
||||||
# Specifically, you need to update the following:
|
gr.Textbox(label="Multi Languages Capable", value='Yes' if features_list['languages_capable'] else 'No', interactive=False)
|
||||||
#
|
gr.Textbox(label="Streaming Capable", value='Yes' if features_list['streaming_capable'] else 'No', interactive=False)
|
||||||
# 1. The name of the function `xxxx_at_gradio_settings_page` to match your engine's name.
|
with gr.Row():
|
||||||
# For example, if your engine is named "mytts", the function should be named `mytts_at_gradio_settings_page`.
|
gr.Textbox(label="Low VRAM Capable", value='Yes' if features_list['lowvram_capable'] else 'No', interactive=False)
|
||||||
#
|
gr.Textbox(label="Temperature Capable", value='Yes' if features_list['temperature_capable'] else 'No', interactive=False)
|
||||||
# 2. The name of the function call `xxxx_model_alltalk_settings(model_config_data)`.
|
gr.Textbox(label="Multi Model Capable Engine", value='Yes' if features_list['multimodel_capable'] else 'No', interactive=False)
|
||||||
# This should match the name you gave to the function that sets up the engine-specific settings page in Gradio.
|
with gr.Row():
|
||||||
# If you named that function `mytts_model_alltalk_settings`, then the call should be:
|
gr.Textbox(label="Multi Voice Capable Models", value='Yes' if features_list['multivoice_capable'] else 'No', interactive=False)
|
||||||
# `mytts_model_alltalk_settings(model_config_data)`
|
gr.Textbox(label="Default Audio output format", value=model_config_data['model_capabilties']['audio_format'], interactive=False)
|
||||||
#
|
gr.Textbox(label="TTS Engine Name", value="piper", interactive=False)
|
||||||
# After making these changes, this function will create and return the Gradio app for your TTS engine's settings page.
|
with gr.Row():
|
||||||
def piper_at_gradio_settings_page(model_config_data):
|
gr.Textbox(label="Windows Support", value='Yes' if features_list['windows_capable'] else 'No', interactive=False)
|
||||||
app = piper_model_alltalk_settings(model_config_data)
|
gr.Textbox(label="Linux Support", value='Yes' if features_list['linux_capable'] else 'No', interactive=False)
|
||||||
return app
|
gr.Textbox(label="Mac Support", value='Yes' if features_list['mac_capable'] else 'No', interactive=False)
|
||||||
def piper_at_gradio_settings_page(model_config_data):
|
with gr.Row():
|
||||||
app = piper_model_alltalk_settings(model_config_data)
|
with gr.Accordion("HELP - 🔊 Understanding TTS Engine Capabilities", open=False):
|
||||||
return app
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION, elem_classes="custom-markdown")
|
||||||
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION1, elem_classes="custom-markdown")
|
||||||
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION2, elem_classes="custom-markdown")
|
||||||
|
|
||||||
|
#######################################################################################################################################################################################################
|
||||||
|
# REQUIRED CHANGE #
|
||||||
|
# You will need to build a custom method to identify if your models are installed and download them. Store your models list in the available_models.json file, alongside your model_settings.json etc #
|
||||||
|
#######################################################################################################################################################################################################
|
||||||
|
with gr.Tab("Models/Voices Download"):
|
||||||
|
|
||||||
|
with gr.Tab("Language Pack Download"):
|
||||||
|
with gr.Row():
|
||||||
|
language_groups = group_models_by_language()
|
||||||
|
language_choices = [
|
||||||
|
f"{code} - {info['name']} ({len(info['models'])} voices)"
|
||||||
|
for code, info in sorted(language_groups.items())
|
||||||
|
]
|
||||||
|
|
||||||
|
lang_pack_dropdown = gr.Dropdown(
|
||||||
|
choices=language_choices,
|
||||||
|
label="Select Language Pack",
|
||||||
|
value=language_choices[0]
|
||||||
|
)
|
||||||
|
lang_pack_download_button = gr.Button("Download Language Pack")
|
||||||
|
|
||||||
|
with gr.Row():
|
||||||
|
lang_pack_status = gr.Textbox(label="Language Pack Download Status")
|
||||||
|
|
||||||
|
def download_selected_language_pack(selected_pack):
|
||||||
|
lang_code = selected_pack.split(" - ")[0]
|
||||||
|
return download_language_pack(lang_code)
|
||||||
|
|
||||||
|
lang_pack_download_button.click(
|
||||||
|
download_selected_language_pack,
|
||||||
|
inputs=lang_pack_dropdown,
|
||||||
|
outputs=lang_pack_status
|
||||||
|
)
|
||||||
|
|
||||||
|
with gr.Tab("Individual Voice Download"):
|
||||||
|
with gr.Row():
|
||||||
|
model_dropdown = gr.Dropdown(
|
||||||
|
choices=sorted(model_names),
|
||||||
|
label="Select Individual Voice",
|
||||||
|
value=model_names[0]
|
||||||
|
)
|
||||||
|
download_button = gr.Button("Download Selected Voice")
|
||||||
|
|
||||||
|
with gr.Row():
|
||||||
|
download_status = gr.Textbox(label=" Individual Voice Download Status")
|
||||||
|
|
||||||
|
download_button.click(
|
||||||
|
download_model,
|
||||||
|
inputs=model_dropdown,
|
||||||
|
outputs=download_status
|
||||||
|
)
|
||||||
|
|
||||||
|
def show_confirm_cancel(model_name):
|
||||||
|
all_files_exists = all(os.path.exists(os.path.join(main_dir, "models", "piper", os.path.basename(file.split('?')[0]))) for model in available_models["models"] if model["model_name"] == model_name for file in model["files_to_download"])
|
||||||
|
if all_files_exists:
|
||||||
|
return [gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)]
|
||||||
|
else:
|
||||||
|
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)]
|
||||||
|
|
||||||
|
def confirm_download(model_name):
|
||||||
|
download_status_text = download_model(model_name, force_download=True)
|
||||||
|
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), download_status_text]
|
||||||
|
|
||||||
|
def cancel_download():
|
||||||
|
return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), ""]
|
||||||
|
|
||||||
|
with gr.Row():
|
||||||
|
confirm_button = gr.Button("Download Anyway", visible=False)
|
||||||
|
cancel_button = gr.Button("Cancel", visible=False)
|
||||||
|
|
||||||
|
download_button.click(show_confirm_cancel, inputs=model_dropdown, outputs=[confirm_button, download_button, cancel_button])
|
||||||
|
confirm_button.click(confirm_download, inputs=model_dropdown, outputs=[confirm_button, download_button, cancel_button, download_status])
|
||||||
|
cancel_button.click(cancel_download, inputs=None, outputs=[confirm_button, download_button, cancel_button, download_status])
|
||||||
|
|
||||||
|
###################################################################################################
|
||||||
|
# REQUIRED CHANGE #
|
||||||
|
# Add any engine specific help, bugs, issues, operating system specifc requirements/setup in here #
|
||||||
|
# Please use Markdown format, so gr.Markdown() with your markdown inside it. #
|
||||||
|
###################################################################################################
|
||||||
|
with gr.Tab("Engine Help"):
|
||||||
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE, elem_classes="custom-markdown")
|
||||||
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE1, elem_classes="custom-markdown")
|
||||||
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE2, elem_classes="custom-markdown")
|
||||||
|
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
################################
|
||||||
|
# REQUIRED CHANGE #
|
||||||
|
# Sets up the Gradio interface #
|
||||||
|
################################
|
||||||
|
# This function sets up the Gradio interface for your TTS engine's settings page.
|
||||||
|
# You need to change the name of the function calls to match the names you set in the functions above.
|
||||||
|
#
|
||||||
|
# Specifically, you need to update the following:
|
||||||
|
#
|
||||||
|
# 1. The name of the function `xxxx_at_gradio_settings_page` to match your engine's name.
|
||||||
|
# For example, if your engine is named "mytts", the function should be named `mytts_at_gradio_settings_page`.
|
||||||
|
#
|
||||||
|
# 2. The name of the function call `xxxx_model_alltalk_settings(model_config_data)`.
|
||||||
|
# This should match the name you gave to the function that sets up the engine-specific settings page in Gradio.
|
||||||
|
# If you named that function `mytts_model_alltalk_settings`, then the call should be:
|
||||||
|
# `mytts_model_alltalk_settings(model_config_data)`
|
||||||
|
#
|
||||||
|
# After making these changes, this function will create and return the Gradio app for your TTS engine's settings page.
|
||||||
|
def piper_at_gradio_settings_page(model_config_data):
|
||||||
|
app = piper_model_alltalk_settings(model_config_data)
|
||||||
|
return app
|
||||||
|
def piper_at_gradio_settings_page(model_config_data):
|
||||||
|
app = piper_model_alltalk_settings(model_config_data)
|
||||||
|
return app
|
||||||
Reference in new issue
Block a user