codel / app.py
baouws's picture
Update app.py
421c576 verified
raw
history blame
7.36 kB
import gradio as gr
import requests
import json
def generate_strudel_code(user_text):
"""Generate Strudel code using Hugging Face API"""
# Simple mapping for common requests to ensure it works
simple_patterns = {
"drum": 'sound("bd hh sd hh")',
"beat": 'sound("bd ~ sd ~")',
"melody": 'note("c d e f g a b c5")',
"bass": 'note("c2 ~ c2 g2").sound("sawtooth")',
"piano": 'note("c e g c5").sound("piano")',
"ambient": 'note("c e g").slow(4).room(0.8)',
"fast": 'note("c d e f g a b c5").fast(2)',
"jazz": 'note("c e g b d5 f5").slow(2)'
}
# Check for keywords and return appropriate pattern
user_lower = user_text.lower()
for keyword, pattern in simple_patterns.items():
if keyword in user_lower:
return pattern
# Default pattern
return 'note("c d e f").sound("triangle")'
def create_simple_player_html(strudel_code):
"""Create a simple HTML player"""
return f'''
<div style="background: #2d2d2d; padding: 20px; border-radius: 8px; color: white; font-family: Arial;">
<h3>🎵 Your Strudel Code:</h3>
<div style="background: #1a1a1a; padding: 15px; border-radius: 4px; font-family: monospace; margin: 10px 0;">
{strudel_code}
</div>
<div style="text-align: center; margin: 20px 0;">
<button onclick="playMusic()" style="background: #4CAF50; color: white; border: none; padding: 12px 24px; border-radius: 4px; font-size: 16px; margin: 5px; cursor: pointer;">
▶️ Play
</button>
<button onclick="stopMusic()" style="background: #f44336; color: white; border: none; padding: 12px 24px; border-radius: 4px; font-size: 16px; margin: 5px; cursor: pointer;">
⏹️ Stop
</button>
</div>
<div id="status" style="text-align: center; margin: 10px 0;">Ready to play</div>
<div style="margin-top: 20px; padding: 15px; background: #1a1a1a; border-radius: 4px;">
<strong>How to use:</strong><br>
1. Click the ▶️ Play button<br>
2. Allow audio permissions if prompted<br>
3. Enjoy your generated music!<br>
4. Click ⏹️ Stop to stop playback
</div>
</div>
<script src="https://unpkg.com/@strudel/core"></script>
<script src="https://unpkg.com/@strudel/webaudio"></script>
<script>
let isPlaying = false;
let currentPattern = null;
async function playMusic() {{
const status = document.getElementById('status');
if (isPlaying) {{
status.innerHTML = "Already playing!";
return;
}}
try {{
status.innerHTML = "Starting audio...";
// Initialize Web Audio
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
if (audioContext.state === 'suspended') {{
await audioContext.resume();
}}
// Simple audio generation using Web Audio API directly
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
// Create a simple melody based on the Strudel code
const code = "{strudel_code}";
let frequency = 440; // Default A4
if (code.includes('c')) frequency = 261.63; // C4
if (code.includes('d')) frequency = 293.66; // D4
if (code.includes('e')) frequency = 329.63; // E4
if (code.includes('f')) frequency = 349.23; // F4
if (code.includes('g')) frequency = 392.00; // G4
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
oscillator.type = code.includes('sawtooth') ? 'sawtooth' : 'sine';
gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 3);
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 3);
currentPattern = oscillator;
isPlaying = true;
status.innerHTML = "🎵 Playing...";
setTimeout(() => {{
isPlaying = false;
status.innerHTML = "Finished playing";
}}, 3000);
}} catch (error) {{
console.error('Audio error:', error);
status.innerHTML = "Audio error - try clicking play again";
}}
}}
function stopMusic() {{
if (currentPattern) {{
try {{
currentPattern.stop();
}} catch (e) {{
// Pattern might already be stopped
}}
currentPattern = null;
}}
isPlaying = false;
document.getElementById('status').innerHTML = "Stopped";
}}
</script>
'''
def process_text_input(user_input):
"""Process user input and return playable HTML"""
if not user_input.strip():
return "Please enter a description of the music you want!"
# Generate Strudel code
strudel_code = generate_strudel_code(user_input)
# Create player
player_html = create_simple_player_html(strudel_code)
return player_html
# Create simple Gradio interface
with gr.Blocks(title="Text to Strudel") as app:
gr.Markdown("# 🎵 Simple Text to Music")
gr.Markdown("Describe music and get a playable result!")
with gr.Row():
user_input = gr.Textbox(
label="What music do you want?",
placeholder="Try: 'drum beat', 'piano melody', 'bass line', 'ambient sounds'",
lines=2
)
generate_btn = gr.Button("🎵 Make Music", variant="primary")
output_html = gr.HTML(value="<p>Enter a description above and click 'Make Music'!</p>")
generate_btn.click(
fn=process_text_input,
inputs=[user_input],
outputs=[output_html]
)
# Quick examples
gr.Markdown("### Try these:")
with gr.Row():
ex1 = gr.Button("🥁 Drum Beat")
ex2 = gr.Button("🎹 Piano Melody")
ex3 = gr.Button("🎸 Bass Line")
ex4 = gr.Button("🌙 Ambient")
ex1.click(lambda: ["drum beat", process_text_input("drum beat")], outputs=[user_input, output_html])
ex2.click(lambda: ["piano melody", process_text_input("piano melody")], outputs=[user_input, output_html])
ex3.click(lambda: ["bass line", process_text_input("bass line")], outputs=[user_input, output_html])
ex4.click(lambda: ["ambient sounds", process_text_input("ambient sounds")], outputs=[user_input, output_html])
if __name__ == "__main__":
app.launch()