Opera8 commited on
Commit
82faa29
·
verified ·
1 Parent(s): 1c15946

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -32
app.py CHANGED
@@ -11,6 +11,7 @@ from huggingface_hub import snapshot_download, hf_hub_download
11
  import subprocess
12
  import uuid
13
  import soundfile as sf
 
14
 
15
  # --- تنظیمات و نصب پیش‌نیازها ---
16
  downloaded_resources = {
@@ -174,9 +175,9 @@ def vevo_timbre(content_wav, reference_wav):
174
  # --- استراتژی Center-Only Processing (حذف لرزش) ---
175
  pipeline = get_pipeline()
176
 
177
- # تنظیمات اصلی (به ثانیه)
178
- CORE_CHUNK_SEC = 10.0 # مقداری که نهایتاً نگه می‌داریم
179
- PADDING_SEC = 2.0 # مقداری که از هر طرف اضافه می‌خوانیم و دور می‌ریزیم
180
 
181
  core_samples = int(CORE_CHUNK_SEC * SR)
182
  padding_samples = int(PADDING_SEC * SR)
@@ -188,26 +189,23 @@ def vevo_timbre(content_wav, reference_wav):
188
  print(f"[{session_id}] Starting Center-Only processing...")
189
 
190
  while cursor < total_samples:
191
- # محاسبه بازه خواندن از فایل اصلی (Source)
192
- # ما PADDING را از عقب و جلو اضافه می‌کنیم
193
  read_start = max(0, cursor - padding_samples)
194
  read_end = min(total_samples, cursor + core_samples + padding_samples)
195
 
196
- # اگر به ته فایل رسیدیم و چیزی برای پردازش نمانده
197
  if cursor >= total_samples:
198
  break
199
 
200
- # استخراج تکه "پد شده"
201
  chunk_input = content_full_np[read_start:read_end]
202
 
203
- # اگر تکه خیلی کوچک است (انتهای فایل)، فقط پردازش کن
204
  if len(chunk_input) < SR * 0.5:
205
  break
206
 
207
  save_audio_pcm16(torch.FloatTensor(chunk_input).unsqueeze(0), temp_content_path, SR)
208
 
209
  try:
210
- # تولید صدا با حاشیه امن
211
  gen = pipeline.inference_fm(
212
  src_wav_path=temp_content_path,
213
  timbre_ref_wav_path=temp_reference_path,
@@ -216,47 +214,34 @@ def vevo_timbre(content_wav, reference_wav):
216
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
217
  gen_np = gen.detach().cpu().squeeze().numpy()
218
 
219
- # --- برش هوشمند (Trimming) ---
220
- # حالا باید حاشیه‌های ناپایدار (لرزش دار) را حذف کنیم
221
 
222
- # 1. محاسبه مقدار برش از ابتدا (Front Trim)
223
- # اگر اولین تکه است، ما PADDING نداشتیم (چون read_start=0 بود)
224
  if cursor == 0:
225
- trim_front = 0
226
  else:
227
- # در غیر این صورت، دقیقاً به اندازه PADDING از جلو می‌بریم
228
- trim_front = padding_samples
229
 
230
- # 2. محاسبه مقدار برش از انتها (End Trim)
231
- # ما می‌خواهیم فقط به اندازه CORE (10 ثانیه) نگه داریم
232
- # اما باید مراقب انتهای فایل باشیم
233
-
234
- # طول معتبر این تکه در خروجی نهایی
235
  valid_length = min(core_samples, total_samples - cursor)
236
 
237
- # استخراج بخش مرکزی (Stable Core)
238
- # از trim_front شروع کن و به اندازه valid_length بردار
239
  if len(gen_np) > trim_front:
 
240
  core_audio = gen_np[trim_front : trim_front + valid_length]
241
 
242
- # --- اتصال میکروسکوپی (Micro Crossfade 50ms) ---
243
- # این فقط برای جلوگیری از کلیک دیجیتال است، نه برای تغییر لحن
244
- fade_len = int(0.05 * SR) # 50ms
245
 
246
  if len(final_output) > 0 and len(core_audio) > fade_len:
247
- # نرم کردن اتصال
248
  fade_out = np.linspace(1, 0, fade_len)
249
  fade_in = np.linspace(0, 1, fade_len)
250
 
251
- # آخرین تکه لیست
252
  prev_tail = final_output[-1][-fade_len:]
253
  curr_head = core_audio[:fade_len]
254
 
255
- # اگر سایزها یکی بود میکس کن
256
  if len(prev_tail) == fade_len:
257
  mixed = (prev_tail * fade_out) + (curr_head * fade_in)
258
  final_output[-1][-fade_len:] = mixed
259
- # حذف بخش میکس شده از تکه جدید
260
  core_audio = core_audio[fade_len:]
261
 
262
  final_output.append(core_audio)
@@ -266,7 +251,7 @@ def vevo_timbre(content_wav, reference_wav):
266
  missing = min(core_samples, total_samples - cursor)
267
  final_output.append(np.zeros(missing))
268
 
269
- # جلو رفتن نشانگر به اندازه هسته اصلی (بدون هم‌پوشانی منطقی)
270
  cursor += core_samples
271
 
272
  # چسباندن نهایی
@@ -284,7 +269,7 @@ def vevo_timbre(content_wav, reference_wav):
284
 
285
  with gr.Blocks(title="Vevo-Timbre (Stable Core)") as demo:
286
  gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion")
287
- gr.Markdown("Center-Only Processing Strategy: Generates extra padding and discards unstable edges to remove jitter.")
288
 
289
  with gr.Row():
290
  with gr.Column():
 
11
  import subprocess
12
  import uuid
13
  import soundfile as sf
14
+ import spaces # این خط برای ZeroGPU ضروری است
15
 
16
  # --- تنظیمات و نصب پیش‌نیازها ---
17
  downloaded_resources = {
 
175
  # --- استراتژی Center-Only Processing (حذف لرزش) ---
176
  pipeline = get_pipeline()
177
 
178
+ # تنظیمات: ۱۰ ثانیه تمیز نگه می‌داریم، ۲ ثانیه از هر طرف دور می‌ریزیم
179
+ CORE_CHUNK_SEC = 10.0
180
+ PADDING_SEC = 2.0
181
 
182
  core_samples = int(CORE_CHUNK_SEC * SR)
183
  padding_samples = int(PADDING_SEC * SR)
 
189
  print(f"[{session_id}] Starting Center-Only processing...")
190
 
191
  while cursor < total_samples:
192
+ # ۱. خواندن بازه وسیع‌تر (شامل پدینگ)
 
193
  read_start = max(0, cursor - padding_samples)
194
  read_end = min(total_samples, cursor + core_samples + padding_samples)
195
 
 
196
  if cursor >= total_samples:
197
  break
198
 
 
199
  chunk_input = content_full_np[read_start:read_end]
200
 
201
+ # اگر تکه انتهایی خیلی کوچک است، بیخیال شو
202
  if len(chunk_input) < SR * 0.5:
203
  break
204
 
205
  save_audio_pcm16(torch.FloatTensor(chunk_input).unsqueeze(0), temp_content_path, SR)
206
 
207
  try:
208
+ # ۲. تولید صدا
209
  gen = pipeline.inference_fm(
210
  src_wav_path=temp_content_path,
211
  timbre_ref_wav_path=temp_reference_path,
 
214
  if torch.isnan(gen).any(): gen = torch.nan_to_num(gen, nan=0.0)
215
  gen_np = gen.detach().cpu().squeeze().numpy()
216
 
217
+ # ۳. حذف حاشیه‌های خراب (Trimming)
 
218
 
219
+ # محاسبه برش از جلو
 
220
  if cursor == 0:
221
+ trim_front = 0 # در اولین تکه، پدینگ جلو نداریم
222
  else:
223
+ trim_front = padding_samples # در بقیه، به اندازه پدینگ جلو می‌بریم
 
224
 
225
+ # محاسبه طول مفید
 
 
 
 
226
  valid_length = min(core_samples, total_samples - cursor)
227
 
 
 
228
  if len(gen_np) > trim_front:
229
+ # استخراج فقط هسته مرکزی (بدون لرزش)
230
  core_audio = gen_np[trim_front : trim_front + valid_length]
231
 
232
+ # ۴. اتصال میکروسکوپی (۵۰ میلی ثانیه) فقط برای حذف کلیک
233
+ fade_len = int(0.05 * SR)
 
234
 
235
  if len(final_output) > 0 and len(core_audio) > fade_len:
 
236
  fade_out = np.linspace(1, 0, fade_len)
237
  fade_in = np.linspace(0, 1, fade_len)
238
 
 
239
  prev_tail = final_output[-1][-fade_len:]
240
  curr_head = core_audio[:fade_len]
241
 
 
242
  if len(prev_tail) == fade_len:
243
  mixed = (prev_tail * fade_out) + (curr_head * fade_in)
244
  final_output[-1][-fade_len:] = mixed
 
245
  core_audio = core_audio[fade_len:]
246
 
247
  final_output.append(core_audio)
 
251
  missing = min(core_samples, total_samples - cursor)
252
  final_output.append(np.zeros(missing))
253
 
254
+ # ۵. جلو رفتن دقیق به اندازه ۱۰ ثانیه
255
  cursor += core_samples
256
 
257
  # چسباندن نهایی
 
269
 
270
  with gr.Blocks(title="Vevo-Timbre (Stable Core)") as demo:
271
  gr.Markdown("## Vevo-Timbre: Zero-Shot Voice Conversion")
272
+ gr.Markdown("Stable Core Logic: Removes generated artifacts at boundaries.")
273
 
274
  with gr.Row():
275
  with gr.Column():