Spaces:
Running
Running
| import gradio as gr | |
| import requests | |
| import base64 | |
| import io | |
| import soundfile as sf | |
| # π₯ Your ngrok API endpoint β update this each time you restart Colab | |
| API_URL = "https://bustled-hertha-unprojective.ngrok-free.dev/generate" | |
| # Required to bypass ngrok browser warning page (fixes Invalid JSON error) | |
| HEADERS = {"ngrok-skip-browser-warning": "true"} | |
| def generate(prompt, duration, steps, cfg): | |
| try: | |
| print(f"π€ Sending request β prompt='{prompt}' duration={duration}s steps={steps}") | |
| res = requests.post( | |
| API_URL, | |
| json={ | |
| "prompt": prompt, | |
| "duration": float(duration), | |
| "steps": int(steps), | |
| "cfg_scale": float(cfg), | |
| }, | |
| headers=HEADERS, | |
| timeout=300, # 5 min β generation can be slow | |
| ) | |
| print(f"STATUS: {res.status_code}") | |
| if res.status_code != 200: | |
| print(f"β Backend error: {res.text[:500]}") | |
| return None | |
| if not res.text: | |
| print("β Empty response from backend") | |
| return None | |
| try: | |
| data = res.json() | |
| except Exception: | |
| print(f"β Invalid JSON (got HTML?): {res.text[:300]}") | |
| return None | |
| if "audio" not in data: | |
| print(f"β No audio key in response: {data}") | |
| return None | |
| # Decode base64 WAV β numpy | |
| audio_bytes = base64.b64decode(data["audio"]) | |
| audio, sr = sf.read(io.BytesIO(audio_bytes)) | |
| print(f"β Got audio: {len(audio)/sr:.2f}s @ {sr}Hz") | |
| return sr, audio | |
| except requests.exceptions.Timeout: | |
| print("β Request timed out β try fewer steps or shorter duration") | |
| return None | |
| except Exception as e: | |
| print(f"β Request failed: {e}") | |
| return None | |
| # ββ UI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks(title="AutoMix AI π΅") as demo: | |
| gr.Markdown("# π΅ AutoMix AI Beat Generator") | |
| gr.Markdown("Generate AI beats using a diffusion model fine-tuned on trap/rap/R&B π") | |
| with gr.Row(): | |
| with gr.Column(): | |
| prompt_in = gr.Textbox( | |
| label="π§ Prompt", | |
| placeholder="A dark trap beat at 140 BPM in C minor, featuring 808 bass and synth bells.", | |
| lines=3, | |
| ) | |
| duration_in = gr.Slider( | |
| minimum=5, maximum=47, value=30, step=1, | |
| label="β± Duration (seconds)", | |
| ) | |
| steps_in = gr.Slider( | |
| minimum=20, maximum=200, value=100, step=10, | |
| label="βοΈ Diffusion Steps (more = better quality, slower)", | |
| ) | |
| cfg_in = gr.Slider( | |
| minimum=1.0, maximum=15.0, value=7.0, step=0.5, | |
| label="π CFG Scale", | |
| ) | |
| btn = gr.Button("π Generate Beat", variant="primary") | |
| with gr.Column(): | |
| output = gr.Audio(label="π΅ Generated Beat", type="numpy") | |
| btn.click( | |
| fn=generate, | |
| inputs=[prompt_in, duration_in, steps_in, cfg_in], | |
| outputs=output, | |
| ) | |
| demo.launch() |