Woogiepark commited on
Commit
3a0d15e
·
verified ·
1 Parent(s): 505db19

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +362 -0
app.py ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import gradio as gr
3
+
4
+ # --- Custom CSS to mimic your original look ---
5
+ custom_css = """
6
+ :root {
7
+ --primary: #6366f1;
8
+ --primary-dark: #4f46e5;
9
+ --secondary: #10b981;
10
+ --dark: #1e293b;
11
+ --light: #f8fafc;
12
+ --gray: #94a3b8;
13
+ --danger: #ef4444;
14
+ }
15
+
16
+ body {
17
+ background: linear-gradient(135deg, #0f172a, #1e293b) !important;
18
+ color: var(--light) !important;
19
+ }
20
+
21
+ .gradio-container {
22
+ max-width: 1200px !important;
23
+ margin: 0 auto !important;
24
+ padding: 20px !important;
25
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
26
+ }
27
+
28
+ h1, h2, h3 {
29
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
30
+ }
31
+
32
+ .rvc-card {
33
+ background: rgba(30, 41, 59, 0.7);
34
+ backdrop-filter: blur(10px);
35
+ border-radius: 16px;
36
+ padding: 30px;
37
+ margin-bottom: 30px;
38
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
39
+ border: 1px solid rgba(255, 255, 255, 0.1);
40
+ }
41
+
42
+ .rvc-title {
43
+ font-size: 2.5rem;
44
+ margin-bottom: 10px;
45
+ background: linear-gradient(to right, #8b5cf6, #06b6d4);
46
+ -webkit-background-clip: text;
47
+ -webkit-text-fill-color: transparent;
48
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
49
+ text-align: center;
50
+ }
51
+
52
+ .rvc-subtitle {
53
+ font-size: 1.2rem;
54
+ color: var(--gray);
55
+ max-width: 600px;
56
+ margin: 0 auto;
57
+ text-align: center;
58
+ }
59
+
60
+ .rvc-card-title {
61
+ font-size: 1.5rem;
62
+ margin-bottom: 20px;
63
+ color: #8b5cf6;
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 10px;
67
+ }
68
+
69
+ .rvc-status {
70
+ padding: 15px;
71
+ border-radius: 8px;
72
+ margin-top: 20px;
73
+ text-align: center;
74
+ font-weight: 500;
75
+ }
76
+
77
+ .rvc-status-processing {
78
+ background: rgba(59, 130, 246, 0.2);
79
+ color: #3b82f6;
80
+ }
81
+
82
+ .rvc-status-success {
83
+ background: rgba(16, 185, 129, 0.2);
84
+ color: var(--secondary);
85
+ }
86
+
87
+ .rvc-status-error {
88
+ background: rgba(239, 68, 68, 0.2);
89
+ color: var(--danger);
90
+ }
91
+
92
+ /* Fake progress bar */
93
+ .rvc-progress-container {
94
+ height: 8px;
95
+ background: rgba(15, 23, 42, 0.5);
96
+ border-radius: 4px;
97
+ overflow: hidden;
98
+ margin: 20px 0;
99
+ }
100
+
101
+ .rvc-progress-bar {
102
+ height: 100%;
103
+ background: linear-gradient(to right, var(--primary), var(--secondary));
104
+ width: 0%;
105
+ transition: width 0.2s ease;
106
+ }
107
+
108
+ /* Make Gradio buttons vaguely match your buttons */
109
+ button, .gr-button {
110
+ font-weight: 600 !important;
111
+ border-radius: 8px !important;
112
+ }
113
+
114
+ /* Smaller screens tweaks */
115
+ @media (max-width: 768px) {
116
+ .rvc-card {
117
+ padding: 20px;
118
+ }
119
+ .rvc-title {
120
+ font-size: 2rem;
121
+ }
122
+ }
123
+ """
124
+
125
+
126
+ # --- Backend logic (simulated) ---
127
+
128
+ def train_model(files, model_name, voice_type, quality, epochs, trained, progress=gr.Progress(track_tqdm=True)):
129
+ """Simulate model training."""
130
+ if not files:
131
+ # No files → error
132
+ status_html = (
133
+ '<div class="rvc-status rvc-status-error">'
134
+ "Please upload at least one audio file."
135
+ "</div>"
136
+ )
137
+ # progress_html with 0%
138
+ progress_html = (
139
+ '<div class="rvc-progress-container">'
140
+ '<div class="rvc-progress-bar" style="width:0%"></div>'
141
+ "</div>"
142
+ )
143
+ return status_html, False, progress_html
144
+
145
+ model_name = model_name or "MySingingVoice"
146
+ steps = 20
147
+ # Simulate training loop
148
+ for i in progress.tqdm(range(steps), desc=f'Training "{model_name}"'):
149
+ time.sleep(0.15)
150
+
151
+ status_html = (
152
+ '<div class="rvc-status rvc-status-success">'
153
+ f'Model "{model_name}" trained successfully!'
154
+ "</div>"
155
+ )
156
+ progress_html = (
157
+ '<div class="rvc-progress-container">'
158
+ '<div class="rvc-progress-bar" style="width:100%"></div>'
159
+ "</div>"
160
+ )
161
+ return status_html, True, progress_html
162
+
163
+
164
+ def preview_model(trained, model_name):
165
+ """Simulate generating a preview."""
166
+ model_name = model_name or "MySingingVoice"
167
+ if not trained:
168
+ return (
169
+ '<div class="rvc-status rvc-status-error">'
170
+ "Please train a model first."
171
+ "</div>"
172
+ )
173
+ # Fake delay for “preview generation”
174
+ time.sleep(1.0)
175
+ return (
176
+ '<div class="rvc-status rvc-status-success">'
177
+ f'Preview generated successfully for "{model_name}"! '
178
+ "Imagine your custom voice playing here 🎵"
179
+ "</div>"
180
+ )
181
+
182
+
183
+ def export_model(trained, what):
184
+ """Simulate export of model / sample / info."""
185
+ if not trained:
186
+ return (
187
+ '<div class="rvc-status rvc-status-error">'
188
+ "Please train a model before exporting."
189
+ "</div>"
190
+ )
191
+ time.sleep(0.8)
192
+ return (
193
+ '<div class="rvc-status rvc-status-success">'
194
+ f'{what} exported successfully! (Demo only – no real file generated)'
195
+ "</div>"
196
+ )
197
+
198
+
199
+ def reset_app():
200
+ """Reset everything to defaults."""
201
+ status_html = ""
202
+ trained = False
203
+ model_name = "MySingingVoice"
204
+ voice_type = "soprano"
205
+ quality = "high"
206
+ epochs = 300
207
+ files = None
208
+ progress_html = (
209
+ '<div class="rvc-progress-container">'
210
+ '<div class="rvc-progress-bar" style="width:0%"></div>'
211
+ "</div>"
212
+ )
213
+ return status_html, trained, model_name, voice_type, quality, epochs, files, progress_html
214
+
215
+
216
+ # --- Gradio UI ---
217
+
218
+ with gr.Blocks(css=custom_css, title="RVC Voice Model Creator") as demo:
219
+ # Header
220
+ gr.HTML(
221
+ """
222
+ <h1 class="rvc-title">RVC Voice Model Creator</h1>
223
+ <p class="rvc-subtitle">
224
+ Upload your audio files to create custom singing voice models for AI voice conversion.
225
+ </p>
226
+ """
227
+ )
228
+
229
+ trained_state = gr.State(False)
230
+
231
+ # --- Upload Card ---
232
+ with gr.Group(elem_classes="rvc-card"):
233
+ gr.HTML('<h2 class="rvc-card-title">📁 Upload Audio Files</h2>')
234
+ files = gr.File(
235
+ label="Drag & drop your audio files here or click to browse",
236
+ file_types=["audio"],
237
+ file_count="multiple",
238
+ )
239
+
240
+ # --- Settings + Training Card ---
241
+ with gr.Group(elem_classes="rvc-card"):
242
+ gr.HTML('<h2 class="rvc-card-title">⚙️ Model Settings</h2>')
243
+
244
+ with gr.Row():
245
+ with gr.Column():
246
+ model_name = gr.Textbox(
247
+ label="Model Name",
248
+ value="MySingingVoice",
249
+ placeholder="Enter your model name",
250
+ )
251
+ voice_type = gr.Dropdown(
252
+ label="Voice Type",
253
+ choices=[
254
+ "soprano",
255
+ "alto",
256
+ "tenor",
257
+ "bass",
258
+ "custom",
259
+ ],
260
+ value="soprano",
261
+ )
262
+ with gr.Column():
263
+ quality = gr.Dropdown(
264
+ label="Quality Level",
265
+ choices=["high", "medium", "low"],
266
+ value="high",
267
+ )
268
+ epochs = gr.Slider(
269
+ label="Training Epochs",
270
+ minimum=50,
271
+ maximum=1000,
272
+ step=10,
273
+ value=300,
274
+ )
275
+
276
+ progress_html = gr.HTML(
277
+ value=(
278
+ '<div class="rvc-progress-container">'
279
+ '<div class="rvc-progress-bar" style="width:0%"></div>'
280
+ "</div>"
281
+ )
282
+ )
283
+
284
+ status_html = gr.HTML(value="")
285
+
286
+ with gr.Row():
287
+ train_btn = gr.Button("🚀 Train Model", variant="primary")
288
+ preview_btn = gr.Button("👁️ Preview Model", variant="secondary")
289
+ reset_btn = gr.Button("🗑️ Reset All", variant="stop")
290
+
291
+ # --- Export Card ---
292
+ with gr.Group(elem_classes="rvc-card"):
293
+ gr.HTML('<h2 class="rvc-card-title">📥 Export Model</h2>')
294
+
295
+ with gr.Row():
296
+ with gr.Column():
297
+ gr.Markdown("**RVC Model** \n.pth weight file for voice conversion")
298
+ export_rvc_btn = gr.Button("Download RVC")
299
+ with gr.Column():
300
+ gr.Markdown("**Sample Audio** \nConverted sample with your voice")
301
+ export_sample_btn = gr.Button("Download Sample")
302
+ with gr.Column():
303
+ gr.Markdown("**Model Info** \nConfiguration and training details")
304
+ export_info_btn = gr.Button("Download Info")
305
+
306
+ # Footer note
307
+ gr.Markdown(
308
+ "> RVC Voice Model Creator | Create custom singing voices for AI applications \n"
309
+ "> **Note:** This Space is a frontend/demo. Real RVC training needs a proper backend pipeline."
310
+ )
311
+
312
+ # --- Wiring logic ---
313
+
314
+ # Train button
315
+ train_btn.click(
316
+ fn=train_model,
317
+ inputs=[files, model_name, voice_type, quality, epochs, trained_state],
318
+ outputs=[status_html, trained_state, progress_html],
319
+ )
320
+
321
+ # Preview button
322
+ preview_btn.click(
323
+ fn=preview_model,
324
+ inputs=[trained_state, model_name],
325
+ outputs=status_html,
326
+ )
327
+
328
+ # Export buttons
329
+ export_rvc_btn.click(
330
+ fn=export_model,
331
+ inputs=[trained_state, gr.State("RVC model (.pth)")],
332
+ outputs=status_html,
333
+ )
334
+ export_sample_btn.click(
335
+ fn=export_model,
336
+ inputs=[trained_state, gr.State("Sample audio")],
337
+ outputs=status_html,
338
+ )
339
+ export_info_btn.click(
340
+ fn=export_model,
341
+ inputs=[trained_state, gr.State("Model info")],
342
+ outputs=status_html,
343
+ )
344
+
345
+ # Reset button
346
+ reset_btn.click(
347
+ fn=reset_app,
348
+ inputs=None,
349
+ outputs=[
350
+ status_html,
351
+ trained_state,
352
+ model_name,
353
+ voice_type,
354
+ quality,
355
+ epochs,
356
+ files,
357
+ progress_html,
358
+ ],
359
+ )
360
+
361
+ if __name__ == "__main__":
362
+ demo.launch()