mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
simple mixer dialog, showing a couple of voices and the slider for each
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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_()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user