jiaaom commited on
Commit
341539d
·
1 Parent(s): d042a36

fix: improve audio compatibility, add unique filenames, and add download button in web app

Browse files
Files changed (4) hide show
  1. main.py +6 -0
  2. test_debug.py +12 -0
  3. web-app/.gitignore +1 -0
  4. web-app/app.py +44 -14
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from cosyvoice3-talkingflowerzh!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
test_debug.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ os.environ["CUDA_VISIBLE_DEVICES"] = "2"
4
+ sys.path.insert(0, "/home/mason/Developer/Projects/WonderFlower/CosyVoice3-TalkingFlowerZH")
5
+ sys.path.insert(0, "/home/mason/Developer/Projects/WonderFlower/CosyVoice3-TalkingFlowerZH/third_party/Matcha-TTS")
6
+
7
+ import importlib.util
8
+ spec = importlib.util.spec_from_file_location("app", "/home/mason/Developer/Projects/WonderFlower/CosyVoice3-TalkingFlowerZH/web-app/app.py")
9
+ app = importlib.util.module_from_spec(spec)
10
+ spec.loader.exec_module(app)
11
+
12
+ print(app.generate_audio("你好呀!我是会说话的花朵,很高兴认识你!", 42, 1.0))
web-app/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ outputs/
web-app/app.py CHANGED
@@ -1,8 +1,10 @@
1
  import os
2
  import sys
3
  import time
 
4
  import random
5
  import torch
 
6
  import soundfile as sf
7
  import gradio as gr
8
 
@@ -12,6 +14,10 @@ _PARENT = os.path.dirname(_HERE)
12
  sys.path.insert(0, _PARENT)
13
  sys.path.insert(0, os.path.join(_PARENT, "third_party/Matcha-TTS"))
14
 
 
 
 
 
15
  import onnxruntime
16
  import transformers
17
 
@@ -53,6 +59,7 @@ model = None
53
  def load_model():
54
  global model
55
  if model is None:
 
56
  model = CosyVoice3(MODEL_DIR)
57
  return model
58
 
@@ -81,28 +88,50 @@ def remove_tail_click(audio, sr, search_s=0.20, burst_thresh=0.05,
81
 
82
  def generate_audio(text, seed, speed):
83
  if not text:
84
- return None, "Please enter some text."
85
 
86
  set_all_random_seed(seed)
87
 
88
  try:
89
- model = load_model()
 
 
 
 
90
 
91
- for output in model.inference_sft(
92
- INSTRUCT + text,
 
 
93
  spk_id=SPK_ID,
94
  stream=False,
95
  speed=speed,
96
- text_frontend=False,
97
  ):
98
- audio = remove_tail_click(output["tts_speech"], model.sample_rate)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- output_path = os.path.join(_HERE, "output.wav")
101
- sf.write(output_path, audio.squeeze(0).cpu().numpy(), model.sample_rate)
102
- return output_path, f"Success! (Seed: {seed})"
103
 
104
  except Exception as e:
105
- return None, f"Error: {str(e)}"
 
 
106
 
107
  # Gradio UI Theme & Setup (inspired by Talking-Flower)
108
  custom_css = """
@@ -144,14 +173,15 @@ with gr.Blocks(title="Talking Flower TTS", css=custom_css) as demo:
144
  audio_output = gr.Audio(
145
  label="输出音频 (Generated Audio)",
146
  type="filepath",
147
- interactive=False, # Enables native download button
148
  elem_classes="wonder-card"
149
  )
 
150
  status_output = gr.Textbox(label="Status", interactive=False, elem_classes="wonder-card")
151
 
152
  gr.Markdown("---")
153
  gr.Markdown("### 🧠 Model Architecture (CosyVoice 3 Sub-Models)")
154
- gr.HTML("""
155
  <div class="model-arch">
156
  <p>This repository uses a three-stage cascade architecture for zero-shot and supervised text-to-speech:</p>
157
  <ol>
@@ -160,12 +190,12 @@ with gr.Blocks(title="Talking Flower TTS", css=custom_css) as demo:
160
  <li><strong>HIFT (HiFi-GAN Vocoder) <code>hift.pt</code></strong>: A high-fidelity generative adversarial network that converts the Mel-spectrograms into the final raw audio waveform.</li>
161
  </ol>
162
  </div>
163
- """)
164
 
165
  generate_btn.click(
166
  fn=generate_audio,
167
  inputs=[text_input, seed_input, speed_input],
168
- outputs=[audio_output, status_output]
169
  )
170
 
171
  if __name__ == "__main__":
 
1
  import os
2
  import sys
3
  import time
4
+ import uuid
5
  import random
6
  import torch
7
+ import numpy as np
8
  import soundfile as sf
9
  import gradio as gr
10
 
 
14
  sys.path.insert(0, _PARENT)
15
  sys.path.insert(0, os.path.join(_PARENT, "third_party/Matcha-TTS"))
16
 
17
+ # Create an output directory for generated audio
18
+ OUTPUT_DIR = os.path.join(_HERE, "outputs")
19
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
20
+
21
  import onnxruntime
22
  import transformers
23
 
 
59
  def load_model():
60
  global model
61
  if model is None:
62
+ print(f"Loading model from {MODEL_DIR}...")
63
  model = CosyVoice3(MODEL_DIR)
64
  return model
65
 
 
88
 
89
  def generate_audio(text, seed, speed):
90
  if not text:
91
+ return None, None, "Please enter some text."
92
 
93
  set_all_random_seed(seed)
94
 
95
  try:
96
+ model_instance = load_model()
97
+
98
+ # Determine if we should use frontend based on the presence of special tokens
99
+ # Note: cosyvoice internal logic also handles this, but we mirror it here for clarity
100
+ use_frontend = not ('<|' in text and '|>' in text)
101
 
102
+ full_text = INSTRUCT + text
103
+
104
+ for output in model_instance.inference_sft(
105
+ full_text,
106
  spk_id=SPK_ID,
107
  stream=False,
108
  speed=speed,
109
+ text_frontend=False, # We pass False here because we already prepended INSTRUCT
110
  ):
111
+ audio = remove_tail_click(output["tts_speech"], model_instance.sample_rate)
112
+
113
+ # Convert to numpy and normalize
114
+ audio_np = audio.squeeze(0).cpu().numpy()
115
+
116
+ # Simple normalization to avoid clipping and improve compatibility
117
+ max_val = np.abs(audio_np).max()
118
+ if max_val > 1.0:
119
+ audio_np = audio_np / max_val
120
+
121
+ # Convert to 16-bit PCM for widest compatibility
122
+ audio_int16 = (audio_np * 32767).astype(np.int16)
123
+
124
+ # Unique filename for each request
125
+ request_id = str(uuid.uuid4())[:8]
126
+ output_path = os.path.join(OUTPUT_DIR, f"output_{request_id}.wav")
127
 
128
+ sf.write(output_path, audio_int16, model_instance.sample_rate)
129
+ return output_path, output_path, f"Success! (Seed: {seed})"
 
130
 
131
  except Exception as e:
132
+ import traceback
133
+ traceback.print_exc()
134
+ return None, None, f"Error: {str(e)}"
135
 
136
  # Gradio UI Theme & Setup (inspired by Talking-Flower)
137
  custom_css = """
 
173
  audio_output = gr.Audio(
174
  label="输出音频 (Generated Audio)",
175
  type="filepath",
176
+ interactive=False,
177
  elem_classes="wonder-card"
178
  )
179
+ download_output = gr.File(label="下载文件 (Download Wav)", elem_classes="wonder-card")
180
  status_output = gr.Textbox(label="Status", interactive=False, elem_classes="wonder-card")
181
 
182
  gr.Markdown("---")
183
  gr.Markdown("### 🧠 Model Architecture (CosyVoice 3 Sub-Models)")
184
+ gr.HTML(\"\"\"
185
  <div class="model-arch">
186
  <p>This repository uses a three-stage cascade architecture for zero-shot and supervised text-to-speech:</p>
187
  <ol>
 
190
  <li><strong>HIFT (HiFi-GAN Vocoder) <code>hift.pt</code></strong>: A high-fidelity generative adversarial network that converts the Mel-spectrograms into the final raw audio waveform.</li>
191
  </ol>
192
  </div>
193
+ \"\"\")
194
 
195
  generate_btn.click(
196
  fn=generate_audio,
197
  inputs=[text_input, seed_input, speed_input],
198
+ outputs=[audio_output, download_output, status_output]
199
  )
200
 
201
  if __name__ == "__main__":