Vgjkmhf commited on
Commit
f3dd9e4
·
verified ·
1 Parent(s): d0c0da1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -61
app.py CHANGED
@@ -1,100 +1,166 @@
1
  import os
2
- import imageio_ffmpeg
 
3
  import inspect
 
 
 
4
  import gradio as gr
5
- from rvc_python.infer import RVCInference
6
- import static_ffmpeg
7
 
8
- # تنظیمات سیستمی و FFmpeg
9
- static_ffmpeg.add_paths()
10
- ffmpeg_path = imageio_ffmpeg.get_ffmpeg_exe()
11
- os.environ["PATH"] += os.pathsep + os.path.dirname(ffmpeg_path)
 
 
 
 
 
 
 
 
 
 
12
 
13
- def rvc_process(audio_path, model_file, index_file, pitch_change, f0_method, index_rate, protect_val, filter_radius):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if not audio_path or not model_file:
15
- return None, "⚠️ فایل‌ها کامل نیستند."
16
 
17
  try:
18
- model_path = model_file.name
19
- index_path = index_file.name if index_file else None
20
-
21
- print(f"Processing Model: {model_path}")
22
 
 
23
  rvc = RVCInference(device="cpu")
24
- rvc.load_model(model_path)
25
-
26
- out_path = "/tmp/output_persian_fix.wav"
27
- if os.path.exists(out_path): os.remove(out_path)
28
 
29
- # کشف پارامترهای تابع (برای سازگاری با نسخه‌های مختلف)
30
  sig = inspect.signature(rvc.infer_file)
31
  params = sig.parameters
 
32
 
33
- kwargs = {
34
- "input_path": audio_path,
35
- "output_path": out_path,
36
- }
37
-
38
- # 1. پیچ (Pitch)
39
  if "pitch" in params: kwargs["pitch"] = int(pitch_change)
40
  elif "f0_up_key" in params: kwargs["f0_up_key"] = int(pitch_change)
41
-
42
- # 2. متد (Method) - حتما RMVPE
43
  if "method" in params: kwargs["method"] = f0_method
44
  elif "f0_method" in params: kwargs["f0_method"] = f0_method
45
-
46
- # 3. ایندکس (Index)
47
- if "index_path" in params: kwargs["index_path"] = index_path
48
  if "index_rate" in params: kwargs["index_rate"] = float(index_rate)
49
-
50
- # 4. محافظت (Protect) - حیاتی برای فارسی
51
  if "protect" in params: kwargs["protect"] = float(protect_val)
52
-
53
- # 5. فیلتر (Filter Radius) - برای رفع لرزش صدا
54
  if "filter_radius" in params: kwargs["filter_radius"] = int(filter_radius)
 
 
 
55
 
56
- # 6. دقت زمانی (Hop Length) - برای کیفیت بهتر
57
- if "hop_length" in params: kwargs["hop_length"] = 64 # دقت بالاتر (پیشفرض 128 است)
58
-
59
- print(f"Running with: {kwargs}")
60
  rvc.infer_file(**kwargs)
 
 
 
 
61
 
62
- return out_path, "✅ تبدیل انجام شد (تنظیمات فارسی اعمال شد)"
 
 
63
 
64
  except Exception as e:
65
- return None, f"❌ خطا: {str(e)}"
66
 
67
- # رابط کاربری پیشرفته فارسی
68
- with gr.Blocks(title="Persian RVC", theme=gr.themes.Soft()) as demo:
69
- gr.Markdown("# 🇮🇷 مبدل صدای RVC (بهینه برای فارسی)")
70
- gr.Markdown("این نسخه برای رفع مشکل خش‌دار بودن صدا و تداخل لهجه تنظیم شده است.")
 
 
71
 
72
  with gr.Row():
 
73
  with gr.Column():
74
- gr.Markdown("### 1. فایل‌های ورودی")
75
- audio_in = gr.Audio(label="صدای ورودی (واضح و بدون نویز)", type="filepath")
76
- model_in = gr.File(label="فایل مدل (.pth)", file_types=[".pth"])
77
- index_in = gr.File(label="فایل ایندکس (.index)", file_types=[".index"])
 
78
 
 
79
  with gr.Column():
80
- gr.Markdown("### 2. تنظیمات حیاتی")
81
- pitch = gr.Slider(-12, 12, value=0, step=1, label="تغییر گام (Pitch)", info="مرد به زن: +12 | زن به مرد: -12")
82
- method = gr.Dropdown(["rmvpe", "pm"], value="rmvpe", label="الگوریتم", info="فقط RMVPE کیفیت مناسب دارد.")
83
-
84
- gr.Markdown("### 3. تنظیمات رفع خش و تداخل")
85
- index_rate = gr.Slider(0, 1, value=0.3, step=0.05, label="شدت ایندکس (Index Rate)", info="پیشنهاد فارسی: 0.3 تا 0.4 (کمتر = تداخل کمتر)")
86
- protect = gr.Slider(0, 0.5, value=0.5, step=0.01, label="محافظت (Protect)", info="پیشنهاد فارسی: 0.5 (حداکثر) برای جلوگیری از خش‌دار شدن")
87
- filter_radius = gr.Slider(0, 7, value=3, step=1, label="فیلتر نرم‌کننده (Filter Radius)", info="برای حذف لرزش‌های اضافه (پیشنهاد: 3)")
 
 
 
 
 
88
 
89
- btn = gr.Button(" شروع پردازش", variant="primary")
 
 
 
90
 
91
- with gr.Row():
92
- audio_out = gr.Audio(label="خروجی نهایی")
93
- status = gr.Textbox(label="پیام سیستم")
 
94
 
95
  btn.click(
96
- rvc_process,
97
- [audio_in, model_in, index_in, pitch, method, index_rate, protect, filter_radius],
98
  [audio_out, status]
99
  )
100
 
 
1
  import os
2
+ import sys
3
+ import time
4
  import inspect
5
+ import numpy as np
6
+ import soundfile as sf
7
+ import librosa
8
  import gradio as gr
9
+ from scipy.signal import butter, lfilter
 
10
 
11
+ # ==========================================
12
+ # 1. تنظیمات اولیه
13
+ # ==========================================
14
+ try:
15
+ import imageio_ffmpeg
16
+ import static_ffmpeg
17
+ from rvc_python.infer import RVCInference
18
+ static_ffmpeg.add_paths()
19
+ ffmpeg_path = imageio_ffmpeg.get_ffmpeg_exe()
20
+ os.environ["PATH"] += os.pathsep + os.path.dirname(ffmpeg_path)
21
+ print("✅ سیستم آماده است.")
22
+ except ImportError as e:
23
+ print(f"❌ خطای ایمپورت: {e}")
24
+ sys.exit(1)
25
 
26
+ TEMP_DIR = "/tmp/rvc_studio"
27
+ os.makedirs(TEMP_DIR, exist_ok=True)
28
+
29
+ # ==========================================
30
+ # 2. توابع پردازش فرکانس (برای رفع گنگی صدا)
31
+ # ==========================================
32
+
33
+ def anti_muffle_filter(y, sr):
34
+ """فیلتر برای کاهش فرکانس‌های گنگ و تو دماغی (400-800Hz)"""
35
+ try:
36
+ from scipy.signal import iirpeak
37
+ # کاهش 3 دسی‌بل در فرکانس 600Hz
38
+ b, a = iirpeak(600, Q=1.5, fs=sr, ftype='notch')
39
+ return lfilter(b, a, y)
40
+ except:
41
+ return y
42
+
43
+ def clarity_boost(y, sr):
44
+ """تقویت فرکانس‌های بالا برای شفافیت بیشتر"""
45
+ try:
46
+ # افزایش 2 دسی‌بل در فرکانس 8000Hz
47
+ from scipy.signal import iirpeak
48
+ b, a = iirpeak(8000, Q=1.0, fs=sr, ftype='peak')
49
+ return lfilter(b, a, y)
50
+ except:
51
+ return y
52
+
53
+ def preprocess_audio(input_path):
54
+ """پیش‌پردازش صدا: نرمال‌سازی و فیلتر ضد گنگ"""
55
+ y, sr = librosa.load(input_path, sr=None, mono=True)
56
+ y = librosa.util.normalize(y) * 0.95
57
+ y = anti_muffle_filter(y, sr)
58
+ processed_path = os.path.join(TEMP_DIR, "preprocessed.wav")
59
+ sf.write(processed_path, y, sr)
60
+ return processed_path, f"✅ پیش‌پردازش انجام شد (SR: {sr}Hz, Anti-Muffle)"
61
+
62
+ def postprocess_audio(input_path):
63
+ """پس‌پردازش: تقویت شفافیت"""
64
+ y, sr = librosa.load(input_path, sr=None, mono=True)
65
+ y = clarity_boost(y, sr)
66
+ post_path = os.path.join(TEMP_DIR, "postprocessed.wav")
67
+ sf.write(post_path, y, sr)
68
+ return post_path, "✅ پس‌پردازش انجام شد (Clarity Boost)"
69
+
70
+ # ==========================================
71
+ # 3. موتور اصلی تبدیل
72
+ # ==========================================
73
+
74
+ def rvc_process_pipeline(
75
+ audio_path, model_file, index_file, pitch_change, f0_method,
76
+ index_rate, protect_val, filter_radius, resample_sr, envelope_mix, hop_length
77
+ ):
78
  if not audio_path or not model_file:
79
+ return None, " ورودی‌ها کامل نیست."
80
 
81
  try:
82
+ # پیش‌پردازش
83
+ clean_audio, log1 = preprocess_audio(audio_path)
 
 
84
 
85
+ # تبدیل RVC
86
  rvc = RVCInference(device="cpu")
87
+ rvc.load_model(model_file.name)
88
+ rvc_out_path = os.path.join(TEMP_DIR, "rvc_output.wav")
 
 
89
 
 
90
  sig = inspect.signature(rvc.infer_file)
91
  params = sig.parameters
92
+ kwargs = {"input_path": clean_audio, "output_path": rvc_out_path}
93
 
 
 
 
 
 
 
94
  if "pitch" in params: kwargs["pitch"] = int(pitch_change)
95
  elif "f0_up_key" in params: kwargs["f0_up_key"] = int(pitch_change)
 
 
96
  if "method" in params: kwargs["method"] = f0_method
97
  elif "f0_method" in params: kwargs["f0_method"] = f0_method
98
+ if "index_path" in params and index_file: kwargs["index_path"] = index_file.name
 
 
99
  if "index_rate" in params: kwargs["index_rate"] = float(index_rate)
 
 
100
  if "protect" in params: kwargs["protect"] = float(protect_val)
 
 
101
  if "filter_radius" in params: kwargs["filter_radius"] = int(filter_radius)
102
+ if "resample_sr" in params: kwargs["resample_sr"] = int(resample_sr)
103
+ if "rms_mix_rate" in params: kwargs["rms_mix_rate"] = float(envelope_mix)
104
+ if "hop_length" in params: kwargs["hop_length"] = int(hop_length)
105
 
 
 
 
 
106
  rvc.infer_file(**kwargs)
107
+ log2 = "✅ تبدیل RVC انجام شد."
108
+
109
+ # پس‌پردازش
110
+ final_output, log3 = postprocess_audio(rvc_out_path)
111
 
112
+ return final_output, f"{log1}
113
+ {log2}
114
+ {log3}"
115
 
116
  except Exception as e:
117
+ return None, f"❌ خطا: {traceback.format_exc()}"
118
 
119
+ # ==========================================
120
+ # 4. رابط کاربری (UI)
121
+ # ==========================================
122
+
123
+ with gr.Blocks(title="RVC Studio Pro", theme=gr.themes.Monochrome()) as demo:
124
+ gr.Markdown("# 🎙️ RVC Studio Pro - Edition")
125
 
126
  with gr.Row():
127
+ # ستون ورودی
128
  with gr.Column():
129
+ audio_in = gr.Audio(label="صدای ورودی", type="filepath")
130
+ with gr.Row():
131
+ model_in = gr.File(label="فایل مدل (.pth)", file_types=[".pth"])
132
+ index_in = gr.File(label="فایل ایندکس (.index)", file_types=[".index"])
133
+ btn = gr.Button("✨ شروع پردازش", variant="primary")
134
 
135
+ # ستون خروجی
136
  with gr.Column():
137
+ audio_out = gr.Audio(label="صدای نهایی")
138
+ status = gr.Textbox(label="گزارش عملیات", lines=4)
139
+
140
+ # تب‌های تنظیمات
141
+ with gr.Tabs():
142
+ with gr.TabItem("تنظیمات اصلی"):
143
+ pitch = gr.Slider(-24, 24, value=0, step=1, label="Pitch (تغییر گام)")
144
+ method = gr.Dropdown(
145
+ ["rmvpe", "harvest", "crepe", "pm"],
146
+ value="harvest",
147
+ label="الگوریتم",
148
+ info="برای فارسی Harvest یا RMVPE بهترین هستند"
149
+ )
150
 
151
+ with gr.TabItem("تنظیمات کیفیت (رفع خش و تداخل)"):
152
+ index_rate = gr.Slider(0, 1, value=0.3, label="Index Rate (شدت لهجه مدل)")
153
+ protect = gr.Slider(0, 0.5, value=0.4, label="Protect (محافظت از حروف بی‌صدا)")
154
+ filter_radius = gr.Slider(3, 7, value=3, label="Filter Radius (نرم‌کننده لرزش)")
155
 
156
+ with gr.TabItem("تنظیمات فرکانس (رفع گنگی صدا)"):
157
+ hop_length = gr.Slider(32, 256, value=64, step=32, label="Hop Length (دقت زمانی)")
158
+ envelope_mix = gr.Slider(0, 1, value=0.2, label="Volume Envelope Mix (میکس حجم صدا)")
159
+ resample_sr = gr.Slider(0, 48000, value=40000, step=8000, label="Resample SR (قفل فرکانس)")
160
 
161
  btn.click(
162
+ rvc_process_pipeline,
163
+ [audio_in, model_in, index_in, pitch, method, index_rate, protect, filter_radius, resample_sr, envelope_mix, hop_length],
164
  [audio_out, status]
165
  )
166