import time import gradio as gr # --- Custom CSS to mimic your original look --- custom_css = """ :root { --primary: #6366f1; --primary-dark: #4f46e5; --secondary: #10b981; --dark: #1e293b; --light: #f8fafc; --gray: #94a3b8; --danger: #ef4444; } body { background: linear-gradient(135deg, #0f172a, #1e293b) !important; color: var(--light) !important; } .gradio-container { max-width: 1200px !important; margin: 0 auto !important; padding: 20px !important; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } h1, h2, h3 { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } .rvc-card { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(10px); border-radius: 16px; padding: 30px; margin-bottom: 30px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); } .rvc-title { font-size: 2.5rem; margin-bottom: 10px; background: linear-gradient(to right, #8b5cf6, #06b6d4); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); text-align: center; } .rvc-subtitle { font-size: 1.2rem; color: var(--gray); max-width: 600px; margin: 0 auto; text-align: center; } .rvc-card-title { font-size: 1.5rem; margin-bottom: 20px; color: #8b5cf6; display: flex; align-items: center; gap: 10px; } .rvc-status { padding: 15px; border-radius: 8px; margin-top: 20px; text-align: center; font-weight: 500; } .rvc-status-processing { background: rgba(59, 130, 246, 0.2); color: #3b82f6; } .rvc-status-success { background: rgba(16, 185, 129, 0.2); color: var(--secondary); } .rvc-status-error { background: rgba(239, 68, 68, 0.2); color: var(--danger); } /* Fake progress bar */ .rvc-progress-container { height: 8px; background: rgba(15, 23, 42, 0.5); border-radius: 4px; overflow: hidden; margin: 20px 0; } .rvc-progress-bar { height: 100%; background: linear-gradient(to right, var(--primary), var(--secondary)); width: 0%; transition: width 0.2s ease; } /* Make Gradio buttons vaguely match your buttons */ button, .gr-button { font-weight: 600 !important; border-radius: 8px !important; } /* Smaller screens tweaks */ @media (max-width: 768px) { .rvc-card { padding: 20px; } .rvc-title { font-size: 2rem; } } """ # --- Backend logic (simulated) --- def train_model(files, model_name, voice_type, quality, epochs, trained, progress=gr.Progress(track_tqdm=True)): """Simulate model training.""" if not files: # No files → error status_html = ( '
' "Please upload at least one audio file." "
" ) # progress_html with 0% progress_html = ( '
' '
' "
" ) return status_html, False, progress_html model_name = model_name or "MySingingVoice" steps = 20 # Simulate training loop for i in progress.tqdm(range(steps), desc=f'Training "{model_name}"'): time.sleep(0.15) status_html = ( '
' f'Model "{model_name}" trained successfully!' "
" ) progress_html = ( '
' '
' "
" ) return status_html, True, progress_html def preview_model(trained, model_name): """Simulate generating a preview.""" model_name = model_name or "MySingingVoice" if not trained: return ( '
' "Please train a model first." "
" ) # Fake delay for “preview generation” time.sleep(1.0) return ( '
' f'Preview generated successfully for "{model_name}"! ' "Imagine your custom voice playing here 🎵" "
" ) def export_model(trained, what): """Simulate export of model / sample / info.""" if not trained: return ( '
' "Please train a model before exporting." "
" ) time.sleep(0.8) return ( '
' f'{what} exported successfully! (Demo only – no real file generated)' "
" ) def reset_app(): """Reset everything to defaults.""" status_html = "" trained = False model_name = "MySingingVoice" voice_type = "soprano" quality = "high" epochs = 300 files = None progress_html = ( '
' '
' "
" ) return status_html, trained, model_name, voice_type, quality, epochs, files, progress_html # --- Gradio UI --- with gr.Blocks(css=custom_css, title="RVC Voice Model Creator") as demo: # Header gr.HTML( """

RVC Voice Model Creator

Upload your audio files to create custom singing voice models for AI voice conversion.

""" ) trained_state = gr.State(False) # --- Upload Card --- with gr.Group(elem_classes="rvc-card"): gr.HTML('

📁 Upload Audio Files

') files = gr.File( label="Drag & drop your audio files here or click to browse", file_types=["audio"], file_count="multiple", ) # --- Settings + Training Card --- with gr.Group(elem_classes="rvc-card"): gr.HTML('

⚙️ Model Settings

') with gr.Row(): with gr.Column(): model_name = gr.Textbox( label="Model Name", value="MySingingVoice", placeholder="Enter your model name", ) voice_type = gr.Dropdown( label="Voice Type", choices=[ "soprano", "alto", "tenor", "bass", "custom", ], value="soprano", ) with gr.Column(): quality = gr.Dropdown( label="Quality Level", choices=["high", "medium", "low"], value="high", ) epochs = gr.Slider( label="Training Epochs", minimum=50, maximum=1000, step=10, value=300, ) progress_html = gr.HTML( value=( '
' '
' "
" ) ) status_html = gr.HTML(value="") with gr.Row(): train_btn = gr.Button("🚀 Train Model", variant="primary") preview_btn = gr.Button("👁️ Preview Model", variant="secondary") reset_btn = gr.Button("🗑️ Reset All", variant="stop") # --- Export Card --- with gr.Group(elem_classes="rvc-card"): gr.HTML('

📥 Export Model

') with gr.Row(): with gr.Column(): gr.Markdown("**RVC Model** \n.pth weight file for voice conversion") export_rvc_btn = gr.Button("Download RVC") with gr.Column(): gr.Markdown("**Sample Audio** \nConverted sample with your voice") export_sample_btn = gr.Button("Download Sample") with gr.Column(): gr.Markdown("**Model Info** \nConfiguration and training details") export_info_btn = gr.Button("Download Info") # Footer note gr.Markdown( "> RVC Voice Model Creator | Create custom singing voices for AI applications \n" "> **Note:** This Space is a frontend/demo. Real RVC training needs a proper backend pipeline." ) # --- Wiring logic --- # Train button train_btn.click( fn=train_model, inputs=[files, model_name, voice_type, quality, epochs, trained_state], outputs=[status_html, trained_state, progress_html], ) # Preview button preview_btn.click( fn=preview_model, inputs=[trained_state, model_name], outputs=status_html, ) # Export buttons export_rvc_btn.click( fn=export_model, inputs=[trained_state, gr.State("RVC model (.pth)")], outputs=status_html, ) export_sample_btn.click( fn=export_model, inputs=[trained_state, gr.State("Sample audio")], outputs=status_html, ) export_info_btn.click( fn=export_model, inputs=[trained_state, gr.State("Model info")], outputs=status_html, ) # Reset button reset_btn.click( fn=reset_app, inputs=None, outputs=[ status_html, trained_state, model_name, voice_type, quality, epochs, files, progress_html, ], ) if __name__ == "__main__": demo.launch()