Opera8 commited on
Commit
a6cd2a1
·
verified ·
1 Parent(s): f2ebb51

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -40
app.py CHANGED
@@ -174,7 +174,24 @@ def vevo_timbre(content_wav, reference_wav):
174
  raise ValueError("Please upload audio files")
175
 
176
  try:
177
- # --- آماده سازی Reference (اول رفرنس را پردازش می‌کنیم تا سطح صدا را بگیریم) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  if isinstance(reference_wav, tuple):
179
  ref_sr, ref_data = reference_wav if isinstance(reference_wav[0], int) else (reference_wav[1], reference_wav[0])
180
  else:
@@ -188,43 +205,27 @@ def vevo_timbre(content_wav, reference_wav):
188
  ref_tensor = torchaudio.functional.resample(ref_tensor, ref_sr, 24000)
189
  ref_sr = 24000
190
 
191
- # محاسبه انرژی رفرنس
192
- ref_max_vol = torch.max(torch.abs(ref_tensor)) + 1e-6
193
- ref_tensor = ref_tensor / ref_max_vol * 0.95 # نرمال سازی رفرنس
194
 
195
- # برش رفرنس به 20 ثانیه
196
  if ref_tensor.shape[1] > 24000 * 20:
197
  ref_tensor = ref_tensor[:, :24000 * 20]
198
 
199
  save_audio_pcm16(ref_tensor, temp_reference_path, ref_sr)
200
-
201
- # --- آماده سازی Content ---
202
- if isinstance(content_wav, tuple):
203
- content_sr, content_data = content_wav if isinstance(content_wav[0], int) else (content_wav[1], content_wav[0])
204
- else:
205
- content_sr, content_data = content_wav
206
-
207
- if len(content_data.shape) > 1 and content_data.shape[1] > 1:
208
- content_data = np.mean(content_data, axis=1)
209
 
210
- content_tensor = torch.FloatTensor(content_data).unsqueeze(0)
211
- if content_sr != 24000:
212
- content_tensor = torchaudio.functional.resample(content_tensor, content_sr, 24000)
213
- content_sr = 24000
214
-
215
- # نرمال سازی هوشمند: صدای ورودی را هم‌سطح صدای رفرنس می‌کنیم
216
- content_tensor = content_tensor / (torch.max(torch.abs(content_tensor)) + 1e-6) * 0.95
217
-
218
- # --- منطق Chunking ---
219
  pipeline = get_pipeline()
220
 
221
  SR = 24000
222
- CHUNK_LEN = 10 * SR
223
- OVERLAP = 1 * SR
 
 
224
  INPUT_SIZE = CHUNK_LEN + OVERLAP
225
 
226
  total_samples = content_tensor.shape[1]
227
- print(f"[{session_id}] High Quality Processing (64 Steps)... Duration: {total_samples/SR:.2f}s")
228
 
229
  final_parts = []
230
  overlap_buffer = None
@@ -239,7 +240,7 @@ def vevo_timbre(content_wav, reference_wav):
239
  gen = pipeline.inference_fm(
240
  src_wav_path=temp_content_path,
241
  timbre_ref_wav_path=temp_reference_path,
242
- flow_matching_steps=64, # <--- کیفیت بالا (قبلاً 32 بود)
243
  )
244
 
245
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
@@ -257,6 +258,7 @@ def vevo_timbre(content_wav, reference_wav):
257
  head_to_mix = gen[:mix_len]
258
  body_rest = gen[mix_len:]
259
 
 
260
  alpha = np.linspace(0, 1, mix_len)
261
  blended_segment = (overlap_buffer * (1 - alpha)) + (head_to_mix * alpha)
262
 
@@ -302,22 +304,15 @@ def vevo_timbre(content_wav, reference_wav):
302
  if os.path.exists(temp_content_path): os.remove(temp_content_path)
303
  if os.path.exists(temp_reference_path): os.remove(temp_reference_path)
304
 
305
- with gr.Blocks(title="Vevo-Timbre (Ultra Quality)") as demo:
306
- gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion (Ultra Quality)")
307
- gr.Markdown("""
308
- **ویژگی‌ها:**
309
- - **Steps 64:** کیفیت و دقت بافت صدا دو برابر شده است.
310
- - **Auto-Leveling:** سطح صدای شما با مدل تنظیم می‌شود.
311
- - **Seamless Stitching:** بدون پرش و بدون اضافه شدن زمان.
312
-
313
- **نکته مهم:** برای بهترین نتیجه، سعی کنید **لحن، سرعت و احساس** صدای خودتان را شبیه فایل هدف کنید. مدل فقط جنس صدا را تغییر می‌دهد، نه بازیگری شما را!
314
- """)
315
 
316
  with gr.Row():
317
  with gr.Column():
318
- timbre_content = gr.Audio(label="Source Audio (صدای شما)", type="numpy")
319
- timbre_reference = gr.Audio(label="Target Timbre (صدای هدف)", type="numpy")
320
- timbre_button = gr.Button("Generate (Ultra Quality)", variant="primary")
321
  with gr.Column():
322
  timbre_output = gr.Audio(label="Result")
323
 
 
174
  raise ValueError("Please upload audio files")
175
 
176
  try:
177
+ # --- آماده سازی Content ---
178
+ if isinstance(content_wav, tuple):
179
+ content_sr, content_data = content_wav if isinstance(content_wav[0], int) else (content_wav[1], content_wav[0])
180
+ else:
181
+ content_sr, content_data = content_wav
182
+
183
+ if len(content_data.shape) > 1 and content_data.shape[1] > 1:
184
+ content_data = np.mean(content_data, axis=1)
185
+
186
+ content_tensor = torch.FloatTensor(content_data).unsqueeze(0)
187
+ if content_sr != 24000:
188
+ content_tensor = torchaudio.functional.resample(content_tensor, content_sr, 24000)
189
+ content_sr = 24000
190
+
191
+ # نرمال سازی
192
+ content_tensor = content_tensor / (torch.max(torch.abs(content_tensor)) + 1e-6) * 0.95
193
+
194
+ # --- آماده سازی Reference ---
195
  if isinstance(reference_wav, tuple):
196
  ref_sr, ref_data = reference_wav if isinstance(reference_wav[0], int) else (reference_wav[1], reference_wav[0])
197
  else:
 
205
  ref_tensor = torchaudio.functional.resample(ref_tensor, ref_sr, 24000)
206
  ref_sr = 24000
207
 
208
+ # تنظیم لول رفرنس
209
+ ref_max = torch.max(torch.abs(ref_tensor)) + 1e-6
210
+ ref_tensor = ref_tensor / ref_max * 0.95
211
 
 
212
  if ref_tensor.shape[1] > 24000 * 20:
213
  ref_tensor = ref_tensor[:, :24000 * 20]
214
 
215
  save_audio_pcm16(ref_tensor, temp_reference_path, ref_sr)
 
 
 
 
 
 
 
 
 
216
 
217
+ # --- منطق Chunking (اصلاح شده: همپوشانی کوتاه) ---
 
 
 
 
 
 
 
 
218
  pipeline = get_pipeline()
219
 
220
  SR = 24000
221
+ CHUNK_LEN = 10 * SR # 10 ثانیه اصلی
222
+ # تغییر مهم: کاهش همپوشانی به 0.1 ثانیه (100 میلی ثانیه)
223
+ # این باعث می‌شود اکو از بین برود ولی اتصال همچنان نرم باشد
224
+ OVERLAP = int(0.1 * SR)
225
  INPUT_SIZE = CHUNK_LEN + OVERLAP
226
 
227
  total_samples = content_tensor.shape[1]
228
+ print(f"[{session_id}] Processing (High Quality 64 Steps)...")
229
 
230
  final_parts = []
231
  overlap_buffer = None
 
240
  gen = pipeline.inference_fm(
241
  src_wav_path=temp_content_path,
242
  timbre_ref_wav_path=temp_reference_path,
243
+ flow_matching_steps=64, # کیفیت بالا
244
  )
245
 
246
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
 
258
  head_to_mix = gen[:mix_len]
259
  body_rest = gen[mix_len:]
260
 
261
+ # میکس سریع (Fast Cross-Fade)
262
  alpha = np.linspace(0, 1, mix_len)
263
  blended_segment = (overlap_buffer * (1 - alpha)) + (head_to_mix * alpha)
264
 
 
304
  if os.path.exists(temp_content_path): os.remove(temp_content_path)
305
  if os.path.exists(temp_reference_path): os.remove(temp_reference_path)
306
 
307
+ with gr.Blocks(title="Vevo-Timbre (No Echo)") as demo:
308
+ gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion")
309
+ gr.Markdown("نسخه اصلاح شده: حذف اکو در نقاط اتصال + کیفیت بالای ۶۴ مرحله‌ای.")
 
 
 
 
 
 
 
310
 
311
  with gr.Row():
312
  with gr.Column():
313
+ timbre_content = gr.Audio(label="Source Audio", type="numpy")
314
+ timbre_reference = gr.Audio(label="Target Timbre", type="numpy")
315
+ timbre_button = gr.Button("Generate", variant="primary")
316
  with gr.Column():
317
  timbre_output = gr.Audio(label="Result")
318