RAGoLLAMA / profiler.py
K00B404's picture
Upload 9 files
0061c9d verified
raw
history blame
7.55 kB
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
import json,subprocess
import random
from TTS.api import TTS
class VoiceProfile:
def __init__(self, name, voice):
self.name = name
self.voice = voice
def to_dict(self):
return {
'name': self.name,
'voice': self.voice
}
@classmethod
def from_dict(cls, profile_dict):
return cls(
profile_dict['name'],
profile_dict['voice']
)
def configure_tts(self):
# Set Festival voice
subprocess.run(["festival", "--tts", "(voice_" + self.voice + ")"])
class VoiceProfileManager:
def __init__(self, filename="voice_profiles.json"):
self.filename = filename
self.profiles = []
self.load_profiles()
def load_profiles(self):
try:
with open(self.filename, 'r') as file:
profiles_data = json.load(file)
self.profiles = [VoiceProfile.from_dict(profile) for profile in profiles_data]
except FileNotFoundError:
print(f"File '{self.filename}' not found. Starting with an empty profile list.")
self.profiles = []
def save_profiles(self):
profiles_data = [profile.to_dict() for profile in self.profiles]
with open(self.filename, 'w') as file:
json.dump(profiles_data, file, indent=4)
print(f"Profiles saved to '{self.filename}'.")
def add_profile(self, profile):
self.profiles.append(profile)
def generate_random_profile(self):
name = f"Profile-{len(self.profiles) + 1}"
voices = ["cmu_us_slt", "cmu_us_awb", "cmu_us_rms", "cmu_us_bdl"] # Example Festival voices
voice = random.choice(voices)
new_profile = VoiceProfile(name, voice)
self.add_profile(new_profile)
return new_profile
def list_profiles(self):
if not self.profiles:
return "No profiles found."
else:
profiles_list = []
for idx, profile in enumerate(self.profiles, start=1):
profiles_list.append(f"Profile {idx}: {profile.name} - Voice: {profile.voice}")
return profiles_list
def get_profile_by_name(self, profile_name):
for profile in self.profiles:
if profile.name == profile_name:
return profile
return None
class VoiceProfileTool:
def __init__(self, root):
self.root = root
self.root.title("Voice Profile Manager")
self.profile_manager = VoiceProfileManager()
self.create_widgets()
def create_widgets(self):
# Frame for profile list and operations
profile_frame = ttk.LabelFrame(self.root, text="Voice Profiles")
profile_frame.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W+tk.E+tk.N+tk.S)
# Listbox to display profiles
self.profiles_listbox = tk.Listbox(profile_frame, width=50, height=10)
self.profiles_listbox.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W+tk.E+tk.N+tk.S)
# Scrollbar for the listbox
scrollbar = ttk.Scrollbar(profile_frame, orient=tk.VERTICAL, command=self.profiles_listbox.yview)
scrollbar.grid(row=0, column=1, pady=10, sticky=tk.N+tk.S)
self.profiles_listbox.config(yscrollcommand=scrollbar.set)
# Button to generate random profile
generate_btn = ttk.Button(profile_frame, text="Generate Random Profile", command=self.generate_random_profile)
generate_btn.grid(row=1, column=0, padx=10, pady=5, sticky=tk.W+tk.E)
# Button to refresh profile list
refresh_btn = ttk.Button(profile_frame, text="Refresh List", command=self.refresh_profiles_list)
refresh_btn.grid(row=1, column=1, padx=10, pady=5, sticky=tk.W+tk.E)
# Frame for TTS operations
tts_frame = ttk.LabelFrame(self.root, text="Text-to-Speech (TTS)")
tts_frame.grid(row=1, column=0, padx=10, pady=10, sticky=tk.W+tk.E+tk.N+tk.S)
# Text entry for TTS input
ttk.Label(tts_frame, text="Enter text to speak:").grid(row=0, column=0, padx=10, pady=5, sticky=tk.W)
self.tts_text_entry = ttk.Entry(tts_frame, width=50)
self.tts_text_entry.grid(row=0, column=1, padx=10, pady=5, sticky=tk.W+tk.E)
# Combobox to select profile for TTS
ttk.Label(tts_frame, text="Select profile:").grid(row=1, column=0, padx=10, pady=5, sticky=tk.W)
self.profile_combobox = ttk.Combobox(tts_frame, width=48, state="readonly")
self.profile_combobox.grid(row=1, column=1, padx=10, pady=5, sticky=tk.W+tk.E)
# Button to speak text
speak_btn = ttk.Button(tts_frame, text="Speak", command=self.speak_text)
speak_btn.grid(row=2, column=1, padx=10, pady=10, sticky=tk.W+tk.E)
# Populate initial profiles list
self.refresh_profiles_list()
def refresh_profiles_list(self):
# Clear current listbox and combobox
self.profiles_listbox.delete(0, tk.END)
self.profile_combobox['values'] = []
# Load profiles from manager
profiles = self.profile_manager.list_profiles()
if profiles:
for profile in profiles:
self.profiles_listbox.insert(tk.END, profile)
self.profile_combobox['values'] += (profile.split(':')[0],) # Add profile name to combobox options
def generate_random_profile(self):
new_profile = self.profile_manager.generate_random_profile()
messagebox.showinfo("Profile Generated", f"Generated new profile: {new_profile.name}")
self.refresh_profiles_list()
def speak_text(self):
text_to_speak = self.tts_text_entry.get().strip()
selected_profile_name = self.profile_combobox.get().strip()
if not text_to_speak:
messagebox.showwarning("Input Required", "Please enter text to speak.")
return
if not selected_profile_name:
messagebox.showwarning("Profile Required", "Please select a profile.")
return
profile = self.profile_manager.get_profile_by_name(selected_profile_name)
if profile:
profile.configure_tts()
subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE).communicate(bytes(text_to_speak, 'utf-8'))
messagebox.showinfo("Text-to-Speech", f"Text: {text_to_speak}\nProfile: {profile.name}\nVoice: {profile.voice}")
else:
messagebox.showerror("Profile Not Found", f"Profile '{selected_profile_name}' not found.")
# Main program
if __name__ == "__main__":
root = tk.Tk()
app = VoiceProfileTool(root)
root.mainloop()
""" Explanation:
Integration with piper_tts: This example uses the TTS class from piper_tts for text-to-speech synthesis. The configure_tts method in VoiceProfile class is used to set parameters (language, pitch, speaking_rate) on the TTS engine before synthesizing speech.
Tkinter GUI: The GUI interface (VoiceProfileTool class) is built using Tkinter widgets (Listbox, Entry, Combobox, Button, etc.) to manage voice profiles (list, generate random profile) and perform TTS (enter text, select profile, speak).
Profile Management: VoiceProfileManager handles loading/saving profiles from/to JSON file, generating random profiles, listing profiles, and retrieving profiles by name.
Handling TTS Output: After synthesizing speech with piper_tts, the example shows a message box with details about the synthesized text and the selected profile.
"""