Opera8 commited on
Commit
de91e11
·
verified ·
1 Parent(s): 9622192

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -43
app.py CHANGED
@@ -174,7 +174,7 @@ def vevo_timbre(content_wav, reference_wav):
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:
@@ -187,9 +187,11 @@ def vevo_timbre(content_wav, reference_wav):
187
  if content_sr != 24000:
188
  content_tensor = torchaudio.functional.resample(content_tensor, content_sr, 24000)
189
  content_sr = 24000
 
 
190
  content_tensor = content_tensor / (torch.max(torch.abs(content_tensor)) + 1e-6) * 0.95
191
 
192
- # --- آماده سازی Reference ---
193
  if isinstance(reference_wav, tuple):
194
  ref_sr, ref_data = reference_wav if isinstance(reference_wav[0], int) else (reference_wav[1], reference_wav[0])
195
  else:
@@ -203,7 +205,6 @@ def vevo_timbre(content_wav, reference_wav):
203
  ref_tensor = torchaudio.functional.resample(ref_tensor, ref_sr, 24000)
204
  ref_sr = 24000
205
 
206
- # تنظیم لول رفرنس
207
  ref_max = torch.max(torch.abs(ref_tensor)) + 1e-6
208
  ref_tensor = ref_tensor / ref_max * 0.95
209
 
@@ -212,69 +213,83 @@ def vevo_timbre(content_wav, reference_wav):
212
 
213
  save_audio_pcm16(ref_tensor, temp_reference_path, ref_sr)
214
 
215
- # --- منطق هوشمند (Smart Context Window) ---
216
- # ما هیچ صدایی را با هم میکس نمی‌کنیم (حذف اکو)
217
- # فقط از صدای قبلی به عنوان "زمینه" استفاده می‌کنیم و خروجی زمینه را دور می‌ریزیم
218
-
219
  pipeline = get_pipeline()
 
220
  SR = 24000
 
 
221
 
222
- CHUNK_LEN = 10 * SR # 10 ثانیه دیتای مفید
223
- CONTEXT_LEN = 3 * SR # 3 ثانیه نگاه به عقب (برای حفظ لحن)
224
 
225
  total_samples = content_tensor.shape[1]
226
- print(f"[{session_id}] Smart Processing (No Echo)...")
227
 
228
- final_parts = []
229
- current_ptr = 0
230
 
231
- while current_ptr < total_samples:
232
- # تعیین بازه ورودی
233
- # شروع: از 3 ثانیه قبل (اگر وجود داشته باشد)
234
- start_idx = max(0, current_ptr - CONTEXT_LEN)
235
- # پایان: 10 ثانیه بعد از نقطه فعلی
236
- end_idx = min(total_samples, current_ptr + CHUNK_LEN)
 
 
 
 
 
 
 
 
 
 
237
 
238
- # استخراج تکه ورودی (شامل کانتکست + دیتای جدید)
239
- current_input_chunk = content_tensor[:, start_idx:end_idx]
 
 
 
240
  save_audio_pcm16(current_input_chunk, temp_content_path, SR)
241
 
242
- # مقدار زمانی که باید از اول خروجی حذف کنیم (همان کانتکست)
243
- trim_amount = 0
244
- if current_ptr > 0:
245
- trim_amount = current_ptr - start_idx # معمولاً برابر CONTEXT_LEN است
246
 
247
  try:
248
  gen = pipeline.inference_fm(
249
  src_wav_path=temp_content_path,
250
  timbre_ref_wav_path=temp_reference_path,
251
- flow_matching_steps=64,
252
  )
253
 
254
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
255
  if gen.dim() == 1: gen = gen.unsqueeze(0)
256
  gen = gen.cpu().squeeze(0).numpy()
257
 
258
- # *** برش هوشمند ***
259
- # قسمت اول (که تکراری است و مربوط به کانتکست بوده) را دور می‌ریزیم
260
- useful_part = gen[trim_amount:]
 
 
 
 
 
 
261
 
262
- final_parts.append(useful_part)
263
 
264
- # حرکت به جلو
265
- current_ptr += CHUNK_LEN
266
 
267
  except Exception as e:
268
- print(f"Error: {e}")
269
- # در صورت خطا، سکوت اضافه کن (به اندازه دیتای جدیدی که قرار بود ساخته شود)
270
- missing = end_idx - current_ptr
271
- if missing > 0:
272
- final_parts.append(np.zeros(missing))
273
- current_ptr += CHUNK_LEN # تلاش برای تکه بعدی
274
-
275
- # چسباندن قطعات
276
- if len(final_parts) > 0:
277
- full_audio = np.concatenate(final_parts)
278
  else:
279
  full_audio = np.zeros(24000)
280
 
@@ -285,9 +300,9 @@ def vevo_timbre(content_wav, reference_wav):
285
  if os.path.exists(temp_content_path): os.remove(temp_content_path)
286
  if os.path.exists(temp_reference_path): os.remove(temp_reference_path)
287
 
288
- with gr.Blocks(title="Vevo-Timbre (Clean)") as demo:
289
  gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion")
290
- gr.Markdown("نسخه نهایی بدون اکو: استفاده از تکنیک Smart Context Window.")
291
 
292
  with gr.Row():
293
  with gr.Column():
 
174
  raise ValueError("Please upload audio files")
175
 
176
  try:
177
+ # --- پردازش ورودی ---
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:
 
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
+ # --- پردازش رفرنس ---
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
  ref_max = torch.max(torch.abs(ref_tensor)) + 1e-6
209
  ref_tensor = ref_tensor / ref_max * 0.95
210
 
 
213
 
214
  save_audio_pcm16(ref_tensor, temp_reference_path, ref_sr)
215
 
216
+ # --- منطق Look-back Splicing (حذف قطعی اکو) ---
 
 
 
217
  pipeline = get_pipeline()
218
+
219
  SR = 24000
220
+ MAIN_CHUNK_SEC = 10.0
221
+ CONTEXT_SEC = 1.0 # مقدار نگاه به عقب
222
 
223
+ MAIN_CHUNK = int(MAIN_CHUNK_SEC * SR)
224
+ CONTEXT = int(CONTEXT_SEC * SR)
225
 
226
  total_samples = content_tensor.shape[1]
227
+ print(f"[{session_id}] Processing (High Quality 64 Steps)... Zero Echo Mode.")
228
 
229
+ final_output = []
 
230
 
231
+ # اشاره‌گر جاری روی فایل اصلی
232
+ cursor = 0
233
+
234
+ while cursor < total_samples:
235
+ if cursor == 0:
236
+ # تکه اول: بدون کانتکست
237
+ input_start = 0
238
+ input_end = min(MAIN_CHUNK, total_samples)
239
+ # در تکه اول چیزی را دور نمی‌ریزیم
240
+ crop_from = 0
241
+ else:
242
+ # تکه‌های بعدی: با کانتکست (نگاه به عقب)
243
+ input_start = cursor - CONTEXT
244
+ input_end = min(cursor + MAIN_CHUNK, total_samples)
245
+ # در خروجی، قسمت کانتکست را دور می‌ریزیم (Cut)
246
+ crop_from = CONTEXT
247
 
248
+ # اگر به انتهای فایل رسیدیم و طول باقی‌مانده خیلی کم است
249
+ if input_start >= input_end:
250
+ break
251
+
252
+ current_input_chunk = content_tensor[:, input_start:input_end]
253
  save_audio_pcm16(current_input_chunk, temp_content_path, SR)
254
 
255
+ print(f"[{session_id}] Processing chunk: {cursor/SR:.1f}s -> {(input_end-input_start)/SR:.1f}s len")
 
 
 
256
 
257
  try:
258
  gen = pipeline.inference_fm(
259
  src_wav_path=temp_content_path,
260
  timbre_ref_wav_path=temp_reference_path,
261
+ flow_matching_steps=64, # کیفیت بالا
262
  )
263
 
264
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
265
  if gen.dim() == 1: gen = gen.unsqueeze(0)
266
  gen = gen.cpu().squeeze(0).numpy()
267
 
268
+ # *** نکته کلیدی: برش قسمت تکراری ***
269
+ # فقط قسمت "جدید" را نگه می‌داریم
270
+ if crop_from > 0:
271
+ if len(gen) > crop_from:
272
+ valid_audio = gen[crop_from:]
273
+ else:
274
+ valid_audio = np.array([]) # اگر خروجی خیلی کوتاه بود
275
+ else:
276
+ valid_audio = gen
277
 
278
+ final_output.append(valid_audio)
279
 
280
+ # حرکت مکان‌نما به اندازه دیتای مفیدی که تولید کردیم
281
+ cursor = input_end
282
 
283
  except Exception as e:
284
+ print(f"Error in chunk: {e}")
285
+ # اگر ارور داد، سکوت جایگزین کن که تایمینگ به هم نریزد
286
+ needed_len = input_end - (cursor if cursor > 0 else 0)
287
+ final_output.append(np.zeros(needed_len))
288
+ cursor = input_end
289
+
290
+ # چسباندن تکه‌ها (Concatenate)
291
+ if len(final_output) > 0:
292
+ full_audio = np.concatenate(final_output)
 
293
  else:
294
  full_audio = np.zeros(24000)
295
 
 
300
  if os.path.exists(temp_content_path): os.remove(temp_content_path)
301
  if os.path.exists(temp_reference_path): os.remove(temp_reference_path)
302
 
303
+ with gr.Blocks(title="Vevo-Timbre (Zero Echo)") as demo:
304
  gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion")
305
+ gr.Markdown("نسخه نهایی: استفاده از روش Look-back Splicing برای حذف کامل اکو و حفظ پیوستگی لحن.")
306
 
307
  with gr.Row():
308
  with gr.Column():