simple mixer dialog, showing a couple of voices and the slider for each

This commit is contained in:
Juraj Borza
2025-04-28 10:11:35 +02:00
parent 44e555c83e
commit 8583f229f1
2 changed files with 194 additions and 1 deletions
+12
View File
@@ -70,6 +70,7 @@ from constants import (
SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION,
)
from threading import Thread
from voice_formula_gui import VoiceFormulaDialog
# Import ctypes for Windows-specific taskbar icon
if platform.system() == "Windows":
@@ -575,6 +576,14 @@ class abogen(QWidget):
self.voice_formula.setText('0.242 * am_michael + 0.758 * bf_isabella')
voice_row.addWidget(self.voice_formula)
self.btn_voice_formula_mixer = QPushButton(self)
self.btn_voice_formula_mixer.setText("") # TODO add voice formula icon
self.btn_voice_formula_mixer.setToolTip("Mix and match voices")
self.btn_voice_formula_mixer.setFixedSize(40, 36)
self.btn_voice_formula_mixer.setStyleSheet("QPushButton { padding: 6px 12px; }")
self.btn_voice_formula_mixer.clicked.connect(self.show_voice_formula_dialog)
voice_row.addWidget(self.btn_voice_formula_mixer)
# Play/Stop icons
def make_icon(color, shape):
pix = QPixmap(20, 20)
@@ -1652,6 +1661,9 @@ class abogen(QWidget):
self.config["check_updates"] = checked
save_config(self.config)
def show_voice_formula_dialog(self):
VoiceFormulaDialog(self).exec_()
def show_about_dialog(self):
"""Show an About dialog with program information including GitHub link."""
# Get application icon for dialog
+181
View File
@@ -0,0 +1,181 @@
from PyQt5.QtWidgets import (
QDialog,
QVBoxLayout,
QCheckBox,
QLabel,
QHBoxLayout,
QDoubleSpinBox,
QSlider,
QScrollArea,
QWidget,
QPushButton
)
from PyQt5.QtCore import Qt
class VoiceMixer(QWidget):
def __init__(self, voice_name, language_icon, update_formula_callback):
super().__init__()
self.voice_name = voice_name
self.update_formula_callback = update_formula_callback
# Main Layout
layout = QVBoxLayout()
# Checkbox and Voice Name
self.checkbox = QCheckBox()
self.checkbox.setChecked(True)
self.checkbox.stateChanged.connect(self.update_formula_callback)
name_label = QLabel(f"{voice_name} {language_icon}")
name_label.setStyleSheet("font-size: 16px;")
name_layout = QHBoxLayout()
name_layout.addWidget(self.checkbox)
name_layout.addWidget(name_label)
name_layout.addStretch()
layout.addLayout(name_layout)
# Input and Slider
self.spin_box = QDoubleSpinBox()
self.spin_box.setRange(0, 1)
self.spin_box.setSingleStep(0.01)
self.spin_box.setDecimals(2)
self.spin_box.valueChanged.connect(self.update_formula_callback)
self.slider = QSlider(Qt.Horizontal)
self.slider.setRange(0, 100)
self.slider.setValue(50) # Default to 0.5
self.slider.valueChanged.connect(
lambda val: self.spin_box.setValue(val / 100)
)
self.spin_box.valueChanged.connect(
lambda val: self.slider.setValue(int(val * 100))
)
slider_layout = QHBoxLayout()
slider_layout.addWidget(QLabel("0"))
slider_layout.addWidget(self.slider)
slider_layout.addWidget(QLabel("1"))
input_layout = QVBoxLayout()
input_layout.addWidget(self.spin_box)
input_layout.addLayout(slider_layout)
layout.addLayout(input_layout)
self.setLayout(layout)
def get_formula_component(self):
if self.checkbox.isChecked():
weight = self.spin_box.value()
return f"{weight:.3f} * {self.voice_name.lower().replace(' ', '_')}"
return ""
class VoiceFormulaDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Voice Mixer")
self.voice_mixers = []
# Main Layout
main_layout = QVBoxLayout()
# Scroll Area for Voice Panels
self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.voice_list_widget = QWidget()
self.voice_list_layout = QVBoxLayout()
self.voice_list_widget.setLayout(self.voice_list_layout)
self.scroll_area.setWidget(self.voice_list_widget)
main_layout.addWidget(self.scroll_area)
# Formula Label
self.formula_label = QLabel("Voice Formula: ")
self.formula_label.setStyleSheet("font-size: 14px; font-weight: bold;")
main_layout.addWidget(self.formula_label)
# Add buttons
button_layout = QHBoxLayout()
ok_button = QPushButton("OK")
cancel_button = QPushButton("Cancel")
# Connect buttons to appropriate slots
ok_button.clicked.connect(self.accept) # Close dialog and return QDialog.Accepted
cancel_button.clicked.connect(self.reject) # Close dialog and return QDialog.Rejected
button_layout.addStretch() # Push buttons to the right
button_layout.addWidget(ok_button)
button_layout.addWidget(cancel_button)
main_layout.addLayout(button_layout)
self.setLayout(main_layout)
# Initialize with fixed voices
self.add_fixed_voices()
def add_fixed_voices(self):
voices = ['af_bella', 'af_sarah', 'am_eric']
language_icon = '🇺🇸'
for voice in voices:
self.add_voice(voice, language_icon)
def add_voice(self, voice_name, language_icon):
voice_mixer = VoiceMixer(voice_name, language_icon, self.update_formula)
self.voice_mixers.append(voice_mixer)
self.voice_list_layout.addWidget(voice_mixer)
self.update_formula()
def update_formula(self):
formula_components = [
mixer.get_formula_component() for mixer in self.voice_mixers
]
formula = " + ".join(filter(None, formula_components))
self.formula_label.setText(f"Voice Formula: {formula}")
# """ Show a dialog to mix the voice formula """
# ### todo
# # Get application icon for dialog
# icon = self.windowIcon()
# # Create custom dialog
# dialog = QDialog(self)
# dialog.setWindowTitle(f"Voice Formula Mixer")
# dialog.setWindowFlags(dialog.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# dialog.setFixedSize(1200, 400) # Increased height for new button
# layout = QVBoxLayout(dialog)
# layout.setSpacing(10)
# # add a picker for each voice
# # TODO add all voices
# voices = ['af_bella','af_sarah','am_eric']
# language_icon = '🇺🇸'
# for voice in voices:
# self.add_voice(voice, language_icon)
# # Scroll Area for Voice Panels
# self.scroll_area = QScrollArea()
# self.scroll_area.setWidgetResizable(True)
# self.voice_list_widget = QWidget()
# self.voice_list_layout = QVBoxLayout()
# self.voice_list_widget.setLayout(self.voice_list_layout)
# self.scroll_area.setWidget(self.voice_list_widget)
# layout.addWidget(self.scroll_area)
# # TODO add all voices
# self.add_fixed_voices()
# # Close button
# close_btn = QPushButton("Close")
# close_btn.clicked.connect(dialog.accept)
# close_btn.setFixedHeight(32)
# layout.addWidget(close_btn)
# dialog.exec_()