Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import numpy as np | |
| import wave | |
| import struct | |
| import uuid | |
| from content_generator.hooks import generate_hooks | |
| from content_generator.captions import generate_captions | |
| from content_generator.ideas import generate_content_ideas | |
| from content_generator.scripts import generate_short_scripts | |
| from pack_builder.zip_builder import build_creator_pack | |
| # -------------------------------------------------- | |
| # CPU-SAFE BEAT GENERATOR (NO SCIPY) | |
| # -------------------------------------------------- | |
| def generate_cpu_safe_beat(style, bpm): | |
| sr = 44100 | |
| seconds = 8 | |
| t = np.linspace(0, seconds, int(sr * seconds)) | |
| beat = np.zeros_like(t) | |
| if style == "Country Rap": | |
| kick_freq, snare_freq, hat_freq = 55, 180, 8000 | |
| elif style == "Trap": | |
| kick_freq, snare_freq, hat_freq = 45, 200, 10000 | |
| elif style == "Dark Outlaw": | |
| kick_freq, snare_freq, hat_freq = 60, 150, 6000 | |
| elif style == "Drill": | |
| kick_freq, snare_freq, hat_freq = 40, 160, 9000 | |
| else: | |
| kick_freq, snare_freq, hat_freq = 70, 190, 7000 | |
| beat_interval = 60.0 / float(bpm) | |
| hits = int(seconds / beat_interval) | |
| for i in range(hits): | |
| pos = int(i * beat_interval * sr) | |
| if pos + 2000 <= len(beat): | |
| beat[pos:pos+2000] += np.sin(2 * np.pi * kick_freq * t[:2000]) * 0.9 | |
| if i % 2 == 1 and pos + 2000 <= len(beat): | |
| beat[pos:pos+2000] += np.sin(2 * np.pi * snare_freq * t[:2000]) * 0.5 | |
| if pos + 500 <= len(beat): | |
| beat[pos:pos+500] += np.random.randn(500) * 0.1 | |
| max_val = float(np.max(np.abs(beat))) or 1.0 | |
| beat = beat / max_val | |
| beat_int16 = (beat * 32767).astype(np.int16) | |
| filename = f"beat_{uuid.uuid4().hex}.wav" | |
| filepath = f"/tmp/{filename}" | |
| with wave.open(filepath, "w") as wf: | |
| wf.setnchannels(1) | |
| wf.setsampwidth(2) | |
| wf.setframerate(sr) | |
| wf.writeframes(beat_int16.tobytes()) | |
| return filepath | |
| def ui_generate_beats(style, bpm, loops): | |
| audio = None | |
| for _ in range(int(loops)): | |
| audio = generate_cpu_safe_beat(style, bpm) | |
| return audio | |
| def ui_generate_content(niche, tone, goal): | |
| return ( | |
| "\n".join(generate_hooks(niche, tone)), | |
| "\n".join(generate_captions(niche, tone)), | |
| "\n".join(generate_content_ideas(niche, goal)), | |
| "\n".join(generate_short_scripts(niche, tone)) | |
| ) | |
| def ui_build_pack(niche, style, bpm, tone, goal): | |
| return build_creator_pack(niche, style, bpm, tone, goal) | |
| # -------------------------------------------------- | |
| # EMBEDDED BRUSHED GUNMETAL BACKGROUND (BASE64) | |
| # -------------------------------------------------- | |
| gunmetal_bg = """ | |
| <style> | |
| body { | |
| margin: 0 !important; | |
| padding: 0 !important; | |
| background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAYAAAA+j9gPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAABjBJREFUeJzt3b1u2kgQQNHTQF+giNBDbDE5jBqFaUGUcRgxN6E466+vWXTmFRrM8Nl1N8MPv+2MvmP0x+g6u40qGgfHdCqfpNNpJBWlAbIYWCA2PASi6DPd7OJbRRqtZIOSk5MTx0uvvZk90un0n0n0n0n0n0n0n0n0n0n8n2n2zcz5z7XnGO/czkRgZNpmjQqYh6gMPkTFogyXv3gZH/BqhGlywbn4T/6KrAE98FAd7iGouVp21HbQJseb3CidRubc4QpfAl8MwVzKhI6+w4n1vCLaYB9rqx8uxFazc2D/qKyfinBmMOPqlmkavRKu0kUQeFkCvhq/i323iDL49myIIZeF1P0uohsEiL/KZ8nfdXbra+XUl3Bd4mV9Ezg1QF/Nb+YPFQyu1HFDigONydMUuN1ZpFdEyAJ9MkdaZ7n0ANKPOuUMGAfJOyrUo9qeycGQ21MCH2RKDWE/YBYdz/BPZt6r9Ga6IpiObOqYkbKx2+Y8OobQIEkgyDAh9g0Rj62LF8oT+yQUwSWOSJyYwcmBHQYaWV7kngakdUSHcauD1ynjUTduVdJN9WewtG/XAIN5e8wZsM+dAf5BgC984wgKLF6t84yAogPSFqdtYY4cYNSeNBY0d5hDnzL2wv30IZHuZOKhHvJ3C0cFLbFhF38sZ4N2VNivg393XcX4Jt9V7H5P4xMIOKgHdwNwp0UrEGouGZWlznImPi0tLxe3LjXLp8dkUBaRdOy+nK8BPVKx/aRXefxWWEXUOYaL6VLdystD5nq2WEYLRh3SeDsICoZ6RiMUiP+6JGZveHFkNjEcNWef39/C4R2tQeM+c/37yHUsctNk6heAQ7Ez+KQEiC5EvhczHxMMz9Yx8RJWb1x1o1t4bm/FvGV8eK3opgDdBrYqYElw3ZTNhbmPDMv8YDn8ApX2HFqRSbVAAAAAElFTkSuQmCC'); | |
| background-size: cover !important; | |
| background-position: center !important; | |
| background-attachment: fixed !important; | |
| } | |
| /* HEADER */ | |
| #main-title { | |
| font-size: 38px; | |
| font-weight: 900; | |
| color: #eeeeee; | |
| text-align: center; | |
| margin-bottom: 15px; | |
| text-shadow: | |
| 0px 0px 18px #00f0ff, | |
| 0px 0px 28px #00f0ff, | |
| 0px 0px 18px #ff4800; | |
| } | |
| /* PANEL STYLING */ | |
| .gradio-container { | |
| background: rgba(10, 10, 10, 0.55) !important; | |
| backdrop-filter: blur(8px) !important; | |
| border-radius: 14px !important; | |
| border: 1px solid rgba(0,255,255,0.25) !important; | |
| box-shadow: 0px 0px 22px rgba(0,255,255,0.35); | |
| } | |
| /* BUTTONS */ | |
| button { | |
| background: linear-gradient(90deg, #00eaff, #0088cc) !important; | |
| color: black !important; | |
| font-weight: bold !important; | |
| border-radius: 10px !important; | |
| padding: 12px !important; | |
| border: none !important; | |
| font-size: 18px !important; | |
| box-shadow: 0px 0px 15px #00eaff; | |
| transition: 0.15s ease-in-out; | |
| } | |
| button:hover { | |
| transform: scale(1.06); | |
| box-shadow: 0px 0px 25px #00ffff; | |
| } | |
| /* INPUTS */ | |
| input, textarea, select { | |
| background: rgba(20,20,20,0.8) !important; | |
| color: #e5e5e5 !important; | |
| border: 1px solid #0099aa !important; | |
| } | |
| /* AUDIO PLAYER */ | |
| audio { | |
| outline: 2px solid #00ffff !important; | |
| border-radius: 8px; | |
| } | |
| label { | |
| color: #e5e5e5 !important; | |
| } | |
| </style> | |
| """ | |
| # -------------------------------------------------- | |
| # APP UI | |
| # -------------------------------------------------- | |
| with gr.Blocks(title="304 Reaper AI Content + Beat Generator") as demo: | |
| gr.HTML(gunmetal_bg) | |
| gr.HTML("<h1 id='main-title'>π₯ 304 REAPER β AI CONTENT & BEAT FORGE π₯</h1>") | |
| with gr.Tab("π΅ Beat Forge"): | |
| gr.Markdown("### Build outlaw beats with neon precision.") | |
| style = gr.Dropdown( | |
| ["Country Rap", "Trap", "Dark Outlaw", "Drill", "BoomBap"], | |
| label="Beat Style" | |
| ) | |
| bpm = gr.Slider(60, 180, value=120, label="BPM") | |
| loops = gr.Slider(1, 5, value=1, label="Number of Loops") | |
| gen_btn = gr.Button("β‘ Generate Beat") | |
| audio_out = gr.Audio(label="Beat Output", type="filepath") | |
| gen_btn.click( | |
| ui_generate_beats, | |
| inputs=[style, bpm, loops], | |
| outputs=audio_out | |
| ) | |
| with gr.Tab("π§ Content Lab"): | |
| gr.Markdown("### Hooks, captions, ideas, and scripts β outlaw branded.") | |
| niche = gr.Textbox(label="Niche") | |
| tone = gr.Textbox(label="Tone") | |
| goal = gr.Textbox(label="Goal") | |
| gen_btn2 = gr.Button("β‘ Generate Content") | |
| hooks_out = gr.Textbox(label="Hooks") | |
| captions_out = gr.Textbox(label="Captions") | |
| ideas_out = gr.Textbox(label="Ideas") | |
| scripts_out = gr.Textbox(label="Scripts") | |
| gen_btn2.click( | |
| ui_generate_content, | |
| inputs=[niche, tone, goal], | |
| outputs=[hooks_out, captions_out, ideas_out, scripts_out] | |
| ) | |
| with gr.Tab("π¦ Creator Pack"): | |
| gr.Markdown("### One click. Full outlaw creator pack.") | |
| niche2 = gr.Textbox(label="Niche") | |
| style2 = gr.Dropdown( | |
| ["Country Rap", "Trap", "Dark Outlaw", "Drill", "BoomBap"], | |
| label="Beat Style" | |
| ) | |
| bpm2 = gr.Slider(60, 180, value=120, label="BPM") | |
| tone2 = gr.Textbox(label="Tone") | |
| goal2 = gr.Textbox(label="Goal") | |
| build_btn = gr.Button("β‘ Build Pack") | |
| zip_out = gr.File(label="Download ZIP") | |
| build_btn.click( | |
| ui_build_pack, | |
| inputs=[niche2, style2, bpm2, tone2, goal2], | |
| outputs=zip_out | |
| ) | |
| demo.launch() | |