File size: 7,407 Bytes
814308b
 
 
 
 
 
 
 
 
 
 
1519c55
 
5519ee4
 
d7c2bd8
 
 
7dd36aa
5519ee4
 
78fbd6d
 
 
ee663e7
d7c2bd8
 
 
d4ede98
d7c2bd8
e9e7200
 
d7c2bd8
 
107a3c2
0973a1e
 
 
5519ee4
78fbd6d
 
 
5519ee4
107a3c2
 
 
4ccea24
5519ee4
107a3c2
 
 
8aae1ef
 
8fad399
 
 
 
8aae1ef
 
8fad399
 
4dd712f
5519ee4
8aae1ef
5519ee4
52440b6
f3c6970
5519ee4
78fbd6d
 
 
5519ee4
0973a1e
d7c2bd8
107a3c2
4dd712f
 
d7c2bd8
 
 
0973a1e
 
 
 
 
efa217a
4ccea24
6f9caf2
7dd36aa
d7c2bd8
6f9caf2
d7c2bd8
 
6f9caf2
2c56256
 
 
6f9caf2
 
 
 
 
78fbd6d
d7c2bd8
 
1035194
 
d7c2bd8
1035194
 
d7c2bd8
 
 
 
 
 
 
 
5519ee4
78fbd6d
 
 
814308b
d7c2bd8
0973a1e
 
 
 
 
 
 
 
 
 
efa217a
0973a1e
efa217a
4ccea24
5519ee4
804ab34
d7c2bd8
5519ee4
 
 
e9e7200
7dd36aa
d7c2bd8
 
78fbd6d
5519ee4
78fbd6d
 
 
1021220
867bbac
e9e7200
d7c2bd8
 
 
e9e7200
 
d7c2bd8
e9e7200
d7c2bd8
 
 
 
e9e7200
d7c2bd8
4ccea24
 
d7c2bd8
 
7dd36aa
d7c2bd8
 
 
78fbd6d
d7c2bd8
 
5519ee4
4dd712f
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# ========================================== #
# 0. HUGGING FACE ZERO-GPU INITIALIZATION    #
# ========================================== #
try:
    import spaces
except ImportError:
    class spaces:
        @staticmethod
        def GPU(fn):
            return fn

import os
import uuid
import whisper
import gradio as gr
import soundfile as sf
import numpy as np
import scipy.io.wavfile as wav
from groq import Groq
from f5_tts.api import F5TTS

# ========================================== #
# 1. System Setup & Configuration            #
# ========================================== #
GROQ_API_KEY = os.environ.get("GROQ_API_KEY", "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")
voice_file = "my_voice_fixed.wav"

if not os.path.exists(voice_file):
    print(f"⚠️ Reference audio file '{voice_file}' not found! Creating safe baseline array profile...")
    sample_rate = 24000
    duration = 1.0
    audio_data = np.zeros(int(sample_rate * duration), dtype=np.int16)
    wav.write(voice_file, sample_rate, audio_data)

groq_client = Groq(api_key=GROQ_API_KEY) if GROQ_API_KEY else None
whisper_model = None
f5tts = None
auto_reference_text = None

# ========================================== #
# 2. Dynamic Text Response Generation        #
# ========================================== #
def get_ai_answer(question):
    global groq_client
    if not GROQ_API_KEY:
        return "Please add your active GROQ_API_KEY into Hugging Face Settings -> Secrets to chat."
    
    try:
        if groq_client is None:
            groq_client = Groq(api_key=GROQ_API_KEY)
            
        chat_completion = groq_client.chat.completions.create(
            messages=[
                {
                    "role": "system", 
                    "content": "You are an informative voice simulation assistant. Provide comprehensive, detailed, and clear explanations. Avoid single-sentence answers."
                },
                {"role": "user", "content": question}
            ],
            model="llama-3.3-70b-versatile",
            max_tokens=250, # INCREASED: Allows for longer, more detailed descriptions
            timeout=15
        )
        return chat_completion.choices[0].message.content.strip()
    except Exception as e:
        print(f"⚠️ Groq API issue detected: {e}")
        return f"The AI engine is currently offline. Details: {str(e)}"

# ========================================== #
# 3. Native Voice Synthesis Processing       #
# ========================================== #
def clone_and_speak(text):
    global f5tts, auto_reference_text
    try:
        if "offline" in text.lower() or "secrets" in text.lower():
            return None
            
        unique_filename = f"voice_output_{uuid.uuid4().hex[:8]}.wav"
        print(f"πŸ”Š Rendering voice cloning track for text: '{text}'")
        
        if f5tts is None:
            print("Loading F5-TTS Core Neural Simulator...")
            f5tts = F5TTS()
            
        if auto_reference_text is None:
            auto_reference_text = "Hi, my name is Rabbani. I am software engineering in the Gamana solution."
            
        result = f5tts.infer(
            ref_file=voice_file,
            ref_text=auto_reference_text,
            gen_text=text
        )
        
        if isinstance(result, tuple):
            if len(result) == 2:
                audio_data, sample_rate = result[0], result[1]
            elif len(result) >= 3:
                audio_data, sample_rate = result[0], result[1]
            else:
                audio_data, sample_rate = result[0], 24000
        else:
            audio_data, sample_rate = result, 24000
            
        if hasattr(audio_data, "cpu"):
            audio_data = audio_data.cpu().numpy()
        elif hasattr(audio_data, "numpy"):
            audio_data = audio_data.numpy()
            
        audio_data = np.squeeze(audio_data)
        sf.write(unique_filename, audio_data, sample_rate, format='WAV')
        
        if os.path.exists(unique_filename) and os.path.getsize(unique_filename) > 0:
            print(f"πŸŽ‰ Generated track successfully saved to: {unique_filename}")
            return unique_filename
        return None
    except Exception as e:
        print(f"❌ Core TTS System Exception triggered: {e}")
        return None

# ========================================== #
# 4. Request Router Pipeline                 #
# ========================================== #
@spaces.GPU
def chatbot_engine(text_input, audio_input):
    global whisper_model, auto_reference_text
    if whisper_model is None:
        print("Loading Lightweight Whisper Engine...")
        whisper_model = whisper.load_model("tiny")
        
    if auto_reference_text is None:
        try:
            ref_result = whisper_model.transcribe(voice_file, fp16=False)
            auto_reference_text = ref_result["text"].strip()
            if not auto_reference_text:
                auto_reference_text = "Hi, my name is Rabbani. I am software engineering in the Gamana solution."
        except Exception:
            auto_reference_text = "Hi, my name is Rabbani. I am software engineering in the Gamana solution."
            
    if audio_input is not None:
        user_transcription = whisper_model.transcribe(audio_input, fp16=False)
        question = user_transcription["text"]
    elif text_input and text_input.strip() != "":
        question = text_input
    else:
        return "System Notification: Please enter a text question or record your microphone.", None
        
    ai_text_response = get_ai_answer(question)
    generated_audio_track = clone_and_speak(ai_text_response)
    return ai_text_response, generated_audio_track, gr.update(value=""), gr.update(value=None)

# ========================================== #
# 5. Full-Output Single-Page UI Canvas       #
# ========================================== #
with gr.Blocks(title="Rabbani A I voice clone") as interface:
    gr.Markdown("# πŸŽ™οΈ Rabbani A I voice clone")
    gr.Markdown("Type or speak your question below. The system processes the response dynamically and outputs both text and voice simulation results simultaneously.")
    
    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### πŸ’¬ Input Interaction Canvas")
            text_prompt_box = gr.Textbox(placeholder="Type your custom question query here...", label="Your Written Question")
            audio_prompt_box = gr.Audio(label="Or Record/Speak Your Question Directly", type="filepath")
            submit_btn = gr.Button("Send Question to AI Engine", variant="primary")
            clear_btn = gr.ClearButton(value="Clear Inputs")
            
        with gr.Column(scale=1):
            gr.Markdown("### πŸ“Š Cloned Output Responses")
            text_output_box = gr.Textbox(label="AI Answer Text Output", interactive=False)
            audio_output_player = gr.Audio(
                label="Rendered Cloned Response Audio Player",
                type="filepath",
                interactive=False
            )
            
    submit_btn.click(
        fn=chatbot_engine,
        inputs=[text_prompt_box, audio_prompt_box],
        outputs=[text_output_box, audio_output_player, text_prompt_box, audio_prompt_box]
    )
    clear_btn.add([text_prompt_box, audio_prompt_box, text_output_box, audio_output_player])

interface.queue().launch()