File size: 5,203 Bytes
e228198
89668f6
 
e228198
 
 
 
 
 
 
 
 
89668f6
e228198
89668f6
 
 
 
 
 
 
 
 
 
e228198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89668f6
e228198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89668f6
e228198
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Required Libraries
import os
import tempfile
import whisper
from groq import Groq
from gtts import gTTS
import gradio as gr
from pydub import AudioSegment

# ---------------------------
# πŸ”‘ API Key Configuration
# ---------------------------
os.environ['GROQ_API_KEY'] = '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'

# ---------------------------
# πŸ“₯ Load Whisper Model
# ---------------------------
try:
    whisper_model = whisper.load_model("base")
    print("[INFO] Whisper model loaded successfully.")
except AttributeError:
    from whisper import Whisper
    whisper_model = Whisper.load_model("base")
    print("[INFO] Whisper model loaded using alternative syntax.")

# ---------------------------
# πŸŽ™οΈ Audio Processing
# ---------------------------

def validate_audio_file(audio_file):
    """Validate if the audio file exists and is not empty."""
    if not audio_file or not os.path.exists(audio_file) or os.path.getsize(audio_file) == 0:
        print(f"[ERROR] Invalid or empty audio file: {audio_file}")
        return False
    return True


def convert_to_wav(audio_file):
    """Convert audio file to WAV format if needed."""
    try:
        audio = AudioSegment.from_file(audio_file)
        wav_path = tempfile.NamedTemporaryFile(suffix=".wav", delete=False).name
        audio.export(wav_path, format="wav")
        print(f"[INFO] Audio converted to WAV: {wav_path}")
        return wav_path
    except Exception as e:
        print(f"[ERROR] Audio Conversion Error: {e}")
        return None


def transcribe_audio(audio_file):
    """Transcribe audio using Whisper."""
    try:
        print(f"[INFO] Transcribing audio file: {audio_file}")
        if not validate_audio_file(audio_file):
            raise FileNotFoundError("Audio file not found or invalid path.")
        
        audio_file = convert_to_wav(audio_file)
        if not audio_file:
            raise Exception("Failed to convert audio to WAV format.")
        
        result = whisper_model.transcribe(audio_file)
        print(f"[INFO] Transcription result: {result['text']}")
        return result['text']
    except Exception as e:
        print(f"[ERROR] Transcription Error: {e}")
        return f"Transcription Error: {e}"


# ---------------------------
# πŸ€– LLM Interaction
# ---------------------------

def get_groq_response(user_input):
    """Get chatbot response from Groq's API."""
    try:
        print(f"[INFO] Sending input to Groq: {user_input}")
        client = Groq(api_key=os.environ['GROQ_API_KEY'])
        chat_completion = client.chat.completions.create(
            messages=[
                {"role": "user", "content": user_input}
            ],
            model="llama-3.3-70b-versatile",
            stream=False,
        )
        response = chat_completion.choices[0].message.content
        print(f"[INFO] Groq response: {response}")
        return response
    except Exception as e:
        print(f"[ERROR] Groq API Error: {e}")
        return f"Groq API Error: {e}"


# ---------------------------
# πŸ—£οΈ Text-to-Speech
# ---------------------------

def text_to_speech(text):
    """Convert text to speech using gTTS."""
    try:
        print(f"[INFO] Converting text to speech: {text}")
        tts = gTTS(text)
        audio_path = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False).name
        tts.save(audio_path)
        print(f"[INFO] Audio file saved: {audio_path}")
        return audio_path
    except Exception as e:
        print(f"[ERROR] TTS Error: {e}")
        return f"TTS Error: {e}"


# ---------------------------
# πŸ› οΈ Main Interaction Logic
# ---------------------------

def chatbot(audio_input):
    """Handle full chatbot interaction."""
    try:
        print(f"[INFO] Audio Input Path: {audio_input}")
        
        # Validate Audio File
        if not validate_audio_file(audio_input):
            return "Error: Audio file not found or invalid path", None

        # Step 1: Transcribe Audio
        text_input = transcribe_audio(audio_input)
        if "Error" in text_input:
            return text_input, None

        # Step 2: Get Response from Groq
        llm_response = get_groq_response(text_input)
        if "Error" in llm_response:
            return llm_response, None

        # Step 3: Convert Response to Audio
        audio_output = text_to_speech(llm_response)
        if "Error" in audio_output:
            return audio_output, None

        return llm_response, audio_output
    except Exception as e:
        print(f"[ERROR] General Error: {e}")
        return f"General Error: {e}", None


# ---------------------------
# 🌐 Gradio Interface
# ---------------------------

interface = gr.Interface(
    fn=chatbot,
    inputs=gr.Audio(type="filepath"),
    outputs=[
        gr.Textbox(label="LLM Response"),
        gr.Audio(label="Audio Response")
    ],
    title="Real-Time Voice-to-Voice Chatbot",
    description="Speak into the microphone, and the chatbot will respond with audio.",
    live=True  # Ensures real-time interaction
)

# Launch Gradio App
if __name__ == "__main__":
    print("[INFO] Starting Gradio Interface...")
    interface.launch(share=True)