baouws commited on
Commit
516a0a0
Β·
verified Β·
1 Parent(s): ec46619

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -91
app.py CHANGED
@@ -282,42 +282,129 @@ def generate_working_strudel_code(prompt, genre="techno", complexity="moderate")
282
 
283
  return f"{comment_line}\n{base_pattern}"
284
 
285
- def create_visual_code(style="reactive"):
286
- """Create working visual code"""
287
- visual_styles = {
288
- "reactive": """osc(8, 0.1, 1.2)
289
- .color(1.8, 0.8, 1.5)
290
- .modulate(noise(2), 0.3)
 
 
 
 
 
 
 
 
291
  .kaleid(6)
292
  .out()""",
293
- "kaleidoscope": """shape(6, 0.3, 0.01)
294
- .repeat(3, 2)
295
- .rotate(0, 0.03)
296
- .color(1.2, 1.8, 0.8)
 
 
 
 
 
 
297
  .kaleid(8)
298
  .out()""",
299
- "flowing": """noise(3, 0.1)
300
- .color(1.5, 1.2, 0.8)
301
- .modulate(osc(2, 0.05), 0.4)
302
- .contrast(1.4)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  .out()""",
304
- "geometric": """osc(12, 0.02, 0.8)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  .pixelate(32, 24)
306
- .color(2, 0.8, 1.5)
307
  .contrast(1.6)
 
 
 
 
 
 
 
 
 
 
308
  .out()"""
 
309
  }
310
- return visual_styles.get(style, visual_styles["reactive"])
 
 
 
311
 
312
- def create_complete_strudel_code(generated_code, include_visuals=True, visual_style="reactive"):
313
- """Create complete, working Strudel code"""
314
 
315
  visual_code = ""
316
  if include_visuals:
317
  visual_code = f"""// Hydra visuals
318
  await initHydra({{feedStrudel:5}})
319
 
320
- {create_visual_code(visual_style)}
321
 
322
  """
323
 
@@ -336,61 +423,11 @@ def generate_interface(prompt, genre, complexity, include_visuals, visual_style,
336
  if not prompt.strip():
337
  return "Please enter a description of the music you want to create."
338
 
339
- if use_ai:
340
- # Use AI generation with better examples
341
- system_prompt = f"""Generate working Strudel live coding pattern for: {prompt}
342
- Genre: {genre}, Complexity: {complexity}
343
-
344
- Example Strudel patterns:
345
- s("bd*4, hh*8").gain(0.8)
346
- stack(s("bd ~ sn ~"), n("0 2 4").s("sine").octave(3).gain(0.7))
347
- n("[0 3 5 7]*2").s("sawtooth").octave(2).lpf(1200).gain(0.8).scale("a:minor")
348
-
349
- Generate a {complexity} {genre} pattern:"""
350
-
351
- try:
352
- outputs = code_generator(
353
- system_prompt,
354
- max_length=len(system_prompt.split()) + 80,
355
- temperature=0.8,
356
- do_sample=True,
357
- top_p=0.9,
358
- num_return_sequences=1
359
- )
360
-
361
- generated_text = outputs[0]['generated_text']
362
- strudel_code = generated_text[len(system_prompt):].strip()
363
-
364
- # Clean the AI output more thoroughly
365
- lines = strudel_code.split('\n')
366
- clean_lines = []
367
- for line in lines[:8]: # Limit to 8 lines
368
- line = line.strip()
369
- # More robust pattern matching for Strudel code
370
- if line and (line.startswith('s(') or line.startswith('n(') or line.startswith('stack(') or
371
- '.gain(' in line or '.s(' in line or '.octave(' in line or '.scale(' in line or
372
- line.endswith(')') or line.endswith(',') or '.lpf(' in line):
373
- clean_lines.append(line)
374
- # Stop at obvious non-Strudel patterns
375
- elif any(stop_word in line.lower() for stop_word in ['function', 'var ', 'let ', 'const ', 'import', '//']):
376
- break
377
-
378
- if clean_lines:
379
- strudel_code = '\n'.join(clean_lines)
380
- strudel_code = f"// AI Generated: {prompt}\n{strudel_code}"
381
- else:
382
- # Fallback to curated patterns if AI fails
383
- strudel_code = generate_working_strudel_code(prompt, genre, complexity)
384
- except Exception as e:
385
- # Fallback to curated patterns if AI fails
386
- print(f"AI generation failed: {e}")
387
- strudel_code = generate_working_strudel_code(prompt, genre, complexity)
388
- else:
389
- # Use curated pattern generation
390
- strudel_code = generate_working_strudel_code(prompt, genre, complexity)
391
-
392
- # Create complete working template
393
- complete_code = create_complete_strudel_code(strudel_code, include_visuals, visual_style)
394
 
395
  return complete_code
396
 
@@ -403,9 +440,9 @@ with gr.Blocks(title="Working Strudel Generator", theme=gr.themes.Soft()) as app
403
 
404
  βœ… **Premium curated patterns** - professional quality sounds
405
  πŸŽ›οΈ **Real Strudel syntax** - copy & paste ready
406
- 🎨 **Reactive Hydra visuals** included
407
  🎡 **6 genres** with authentic patterns
408
- πŸ€– **Optional AI** (recommended: keep AI off for speed)
409
 
410
  **Usage:** Describe music β†’ Generate β†’ Copy to [strudel.cc](https://strudel.cc) β†’ Play!
411
  """)
@@ -436,19 +473,8 @@ with gr.Blocks(title="Working Strudel Generator", theme=gr.themes.Soft()) as app
436
  label="🎨 Include visuals",
437
  value=True
438
  )
439
-
440
- use_ai = gr.Checkbox(
441
- label="πŸ€– Use AI (slower)",
442
- value=False
443
- )
444
-
445
- visual_style = gr.Dropdown(
446
- choices=["reactive", "kaleidoscope", "flowing", "geometric"],
447
- value="reactive",
448
- label="πŸ‘οΈ Visual Style"
449
- )
450
 
451
- generate_btn = gr.Button("🎡 Generate Premium Code", variant="primary", size="lg")
452
 
453
  with gr.Column():
454
  output_code = gr.Code(
@@ -496,8 +522,8 @@ with gr.Blocks(title="Working Strudel Generator", theme=gr.themes.Soft()) as app
496
  genre_dropdown,
497
  complexity_dropdown,
498
  include_visuals,
499
- visual_style,
500
- use_ai
501
  ],
502
  outputs=output_code
503
  )
 
282
 
283
  return f"{comment_line}\n{base_pattern}"
284
 
285
+ def create_visual_code(style="reactive", genre="techno"):
286
+ """Create working visual code with genre-appropriate randomization"""
287
+
288
+ # Genre-specific visual styles
289
+ genre_visuals = {
290
+ "techno": [
291
+ """osc(12, 0.1, 0.8)
292
+ .color(2, 0.5, 1.5)
293
+ .kaleid(4)
294
+ .rotate(0, 0.1)
295
+ .out()""",
296
+ """shape(4, 0.5, 0.01)
297
+ .repeat(4, 3)
298
+ .color(1.8, 0.8, 2)
299
  .kaleid(6)
300
  .out()""",
301
+ """osc(16, 0.05, 1)
302
+ .pixelate(24, 18)
303
+ .color(2, 1, 0.8)
304
+ .contrast(1.8)
305
+ .out()"""
306
+ ],
307
+ "house": [
308
+ """osc(6, 0.1, 1.2)
309
+ .color(1.5, 1.8, 0.8)
310
+ .modulate(noise(2), 0.2)
311
  .kaleid(8)
312
  .out()""",
313
+ """shape(6, 0.4, 0.02)
314
+ .repeat(3, 2)
315
+ .rotate(0, 0.05)
316
+ .color(1.2, 1.5, 1.8)
317
+ .out()""",
318
+ """noise(2, 0.1)
319
+ .color(1.8, 1.2, 1.5)
320
+ .modulate(osc(3, 0.08), 0.3)
321
+ .kaleid(4)
322
+ .out()"""
323
+ ],
324
+ "ambient": [
325
+ """noise(3, 0.05)
326
+ .color(0.8, 1.5, 1.8)
327
+ .modulate(osc(1, 0.1), 0.4)
328
+ .contrast(1.2)
329
+ .out()""",
330
+ """osc(4, 0.02, 1.5)
331
+ .color(1.2, 1.8, 1.5)
332
+ .modulate(noise(1), 0.5)
333
+ .kaleid(3)
334
  .out()""",
335
+ """shape(8, 0.2, 0.005)
336
+ .repeat(2, 2)
337
+ .color(0.8, 1.8, 1.2)
338
+ .rotate(0, 0.02)
339
+ .out()"""
340
+ ],
341
+ "breakbeat": [
342
+ """osc(20, 0.2, 0.5)
343
+ .pixelate(16, 12)
344
+ .color(2, 1.5, 0.5)
345
+ .contrast(2)
346
+ .out()""",
347
+ """shape(3, 0.8, 0.05)
348
+ .repeat(6, 4)
349
+ .color(1.8, 2, 1)
350
+ .kaleid(5)
351
+ .out()""",
352
+ """noise(4, 0.3)
353
+ .color(2, 1.8, 0.8)
354
+ .modulate(osc(8, 0.1), 0.6)
355
+ .pixelate(20, 15)
356
+ .out()"""
357
+ ],
358
+ "experimental": [
359
+ """noise(5, 0.4)
360
+ .color(2, 0.8, 1.8)
361
+ .modulate(osc(15, 0.3), 0.8)
362
+ .pixelate(8, 6)
363
+ .contrast(2.5)
364
+ .out()""",
365
+ """osc(25, 0.4, 0.2)
366
+ .color(1.8, 2, 0.5)
367
+ .kaleid(12)
368
+ .rotate(0, 0.2)
369
+ .out()""",
370
+ """shape(7, 0.9, 0.1)
371
+ .repeat(8, 6)
372
+ .color(2, 1, 2)
373
+ .modulate(noise(6), 0.7)
374
+ .out()"""
375
+ ],
376
+ "hiphop": [
377
+ """osc(8, 0.1, 1)
378
+ .color(1.8, 1.5, 0.8)
379
  .pixelate(32, 24)
 
380
  .contrast(1.6)
381
+ .out()""",
382
+ """shape(4, 0.6, 0.02)
383
+ .repeat(4, 3)
384
+ .color(2, 1.8, 1)
385
+ .kaleid(4)
386
+ .out()""",
387
+ """noise(3, 0.2)
388
+ .color(1.5, 1.8, 0.8)
389
+ .modulate(osc(4, 0.1), 0.3)
390
+ .pixelate(28, 20)
391
  .out()"""
392
+ ]
393
  }
394
+
395
+ # Get random visual from genre-specific options
396
+ visuals = genre_visuals.get(genre, genre_visuals["techno"])
397
+ return random.choice(visuals)
398
 
399
+ def create_complete_strudel_code(generated_code, include_visuals=True, genre="techno"):
400
+ """Create complete, working Strudel code with random visuals"""
401
 
402
  visual_code = ""
403
  if include_visuals:
404
  visual_code = f"""// Hydra visuals
405
  await initHydra({{feedStrudel:5}})
406
 
407
+ {create_visual_code("random", genre)}
408
 
409
  """
410
 
 
423
  if not prompt.strip():
424
  return "Please enter a description of the music you want to create."
425
 
426
+ # Always use curated pattern generation (removed AI for simplicity and speed)
427
+ strudel_code = generate_working_strudel_code(prompt, genre, complexity)
428
+
429
+ # Create complete working template with random visuals based on genre
430
+ complete_code = create_complete_strudel_code(strudel_code, include_visuals, genre)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
  return complete_code
433
 
 
440
 
441
  βœ… **Premium curated patterns** - professional quality sounds
442
  πŸŽ›οΈ **Real Strudel syntax** - copy & paste ready
443
+ 🎨 **Random genre-specific visuals** - different every time!
444
  🎡 **6 genres** with authentic patterns
445
+ ⚑ **Instant generation** - no waiting!
446
 
447
  **Usage:** Describe music β†’ Generate β†’ Copy to [strudel.cc](https://strudel.cc) β†’ Play!
448
  """)
 
473
  label="🎨 Include visuals",
474
  value=True
475
  )
 
 
 
 
 
 
 
 
 
 
 
476
 
477
+ generate_btn = gr.Button("Generate Code", variant="primary", size="lg")
478
 
479
  with gr.Column():
480
  output_code = gr.Code(
 
522
  genre_dropdown,
523
  complexity_dropdown,
524
  include_visuals,
525
+ gr.State("random"), # dummy visual_style
526
+ gr.State(False) # dummy use_ai
527
  ],
528
  outputs=output_code
529
  )