File size: 2,421 Bytes
776566f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import gradio as gr
import subprocess
import os
import tempfile

def speak_text_via_festival(text):
    """
    Uses Festival to speak the given text and returns the path to the generated audio file.
    """
    if not text:
        return None

    # Create a temporary WAV file for Festival output
    # Using tempfile to ensure unique and safely managed temporary files
    with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_audio_file:
        audio_filepath = temp_audio_file.name

    try:
        # Command to make Festival speak and output to a WAV file
        # (audio_mode 'wav) makes it output to a file instead of direct playback
        # (utt.save.wave utt "filename.wav") saves the utterance
        festival_command = f"""
        (set! utt (SayText "{text}"))
        (utt.save.wave utt "{audio_filepath}")
        """
        
        process = subprocess.Popen(['festival', '--pipe'], 
                                   stdin=subprocess.PIPE, 
                                   stdout=subprocess.PIPE, 
                                   stderr=subprocess.PIPE,
                                   text=True)
        stdout, stderr = process.communicate(input=festival_command)
        
        if process.returncode != 0:
            print(f"Error speaking text with Festival: {stderr}")
            if os.path.exists(audio_filepath):
                os.remove(audio_filepath) # Clean up partial file
            return None
        
        # Gradio's gr.Audio component expects a path to the audio file
        return audio_filepath

    except FileNotFoundError:
        print("Error: Festival executable not found. Make sure Festival is installed and in your PATH.")
        if os.path.exists(audio_filepath):
            os.remove(audio_filepath)
        return None
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        if os.path.exists(audio_filepath):
            os.remove(audio_filepath)
        return None

# Define the Gradio Interface
iface = gr.Interface(
    fn=speak_text_via_festival,
    inputs=gr.Textbox(lines=2, label="Enter text for Festival TTS:"),
    outputs=gr.Audio(label="Generated Audio", type="filepath", autoplay=True),
    title="Festival TTS with Gradio",
    description="Enter text to synthesize speech using the local Festival system."
)

# Launch the Gradio app
if __name__ == "__main__":
    iface.launch()