// ═══════════════════════════════════════════════════════════════════════════
// πŸŽ΅πŸ‘οΈ CrumbVisuals - Audio-Visual Live Patterns
// ═══════════════════════════════════════════════════════════════════════════
// Kopiere diese Patterns direkt in Strudel REPL (https://strudel.cc)
// Drücke Play und genieße Sound + Visuals!
// ═══════════════════════════════════════════════════════════════════════════

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 1: HOUSE KALEIDOSCOPE (128 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Disco vibes, colorful kaleidoscope reacting to the beat

/*
await initHydra({ detectAudio: true })

// VISUALS: Kaleidoscope pulsing with bass
osc(10, 0.3, () => a.fft[0] * 2)
.color(
() => 0.5 + a.fft[1] * 0.5,
0.3,
() => 0.5 + a.fft[2] * 0.5
)
.rotate(() => time * 0.1)
.kaleid(() => 4 + a.fft[0] * 6)
.modulate(noise(() => a.fft[3] * 2), 0.1)
.saturate(1.5)
.contrast(1.2)
.out()

// AUDIO: House beat
setcps(128/60/2)
$: sound("bd bd bd bd").gain(1).lpf(200)
$: sound("~ hh ~ hh ~ hh oh hh").gain(0.4).hpf(6000)
$: sound("~ ~ cp ~").gain(0.7).room(0.2)
$: note("c2 ~ [c2 c3] ~, ~ ~ e2 g2").s("sawtooth")
.lpf(sine.range(300, 1200).slow(8)).gain(0.5)
$: note("").s("sine").gain(0.2).delay(0.4).room(0.5)
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 2: REGGAE ROOTS (75 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Green/Gold vibes, slow pulse, one drop feeling

/*
await initHydra({ detectAudio: true })

// VISUALS: Roots colors, slow movement
osc(3, 0.1, 1)
.color(0.2, 0.9, 0.1) // Green
.rotate(() => time * 0.02)
.modulate(
osc(5, 0.2, 0).color(1, 0.8, 0), // Gold modulation
() => a.fft[0] * 0.15
)
.mult(
shape(4, () => 0.3 + a.fft[0] * 0.3, 0.1)
.color(0.9, 0.2, 0.1) // Red accent
)
.saturate(1.3)
.out()

// AUDIO: One Drop Reggae
setcps(75/60/2)
$: sound("~ ~ bd ~").gain(1).lpf(150).room(0.2)
$: sound("~ ~ rim ~").gain(0.6).hpf(800).delay(0.5).dfb(0.5)
$: sound("hh ~ hh ~ hh ~ hh ~").gain(0.25).hpf(6000)
$: note("a1 ~ ~ a1, ~ a2 ~ ~, c2 ~ c2 ~, ~ e2 ~ a1")
.s("triangle").lpf(300).gain(0.8).slow(2)
$: note("~ ").chord().s("pluck")
.gain(0.4).lpf(2000).room(0.3).slow(2)
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 3: DNB CHAOS (196 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Fast, glitchy, high energy jungle vibes

/*
await initHydra({ detectAudio: true })

// VISUALS: Fast, chaotic, glitchy
voronoi(15, () => 1 + a.fft[0] * 3, 0.3)
.thresh(() => 0.3 + a.fft[1] * 0.3)
.color(
() => a.fft[2],
() => 0.5 - a.fft[0] * 0.3,
() => 1 - a.fft[3] * 0.5
)
.kaleid(() => 6 + a.fft[0] * 6)
.rotate(() => time * 0.3)
.pixelate(
() => 50 + a.fft[0] * 100,
() => 50 + a.fft[0] * 100
)
.contrast(1.5)
.out()

// AUDIO: Jungle breaks
setcps(196/60/2)
$: sound("[bd ~ bd [~ bd]] [~ sd ~ sd]").gain(1).lpf(200)
$: sound("bd:3(3,8)").gain(0.8).hpf(60).lpf(100)
$: sound("hh8").gain(0.35).hpf(8000).pan(sine.slow(2))
$: note("e1 ~ e1 ~, ~ e2 ~ e1, g1 ~ ~ g1, ~ e1 e2 ~")
.s("sawtooth").lpf(400).gain(0.7).distort(0.1).slow(2)
/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 4: AMBIENT SPACE (30 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Slow, ethereal, infinite feedback space

/*
await initHydra({ detectAudio: true })

// VISUALS: Slow feedback, ethereal
src(o0)
.scale(1.008)
.rotate(() => 0.003)
.saturate(0.99)
.blend(
osc(4, 0.1, () => a.fft[1] * 2)
.color(0.3, 0.2, () => 0.5 + a.fft[2] * 0.5)
.modulate(noise(() => a.fft[0] * 0.5), 0.05)
, () => 0.02 + a.fft[0] * 0.05
)
.out()

// AUDIO: Ambient drones
setcps(0.5)
$: note("").s("supersaw")
.lpf(sine.range(300, 1500).slow(16)).gain(0.3).room(0.9)
$: note("<[0 2 5 3 -1 2]>").s("sine")
.gain(0.2).delay(0.6).dfb(0.7).scale("c:minor")
$: n(irand(7).struct("<~ x [x ~] ~>")).s("triangle")
.gain(0.15).hpf(1000).delay(0.5).room(0.8).scale("c:minor")
$: note("c1").s("sine").gain(0.4).lpf(80)
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 5: BAOBAB POLYRHYTHM (110 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Earth tones, organic movement, African vibes

/*
await initHydra({ detectAudio: true })

// VISUALS: Earth tones, organic
noise(4, () => a.fft[0] * 0.5)
.color(0.7, 0.4, 0.2) // Earth brown
.modulate(
voronoi(8, () => 0.5 + a.fft[1], 0.3),
() => a.fft[2] * 0.15
)
.rotate(() => time * 0.03)
.mult(
shape(() => 5 + a.fft[0] * 3, 0.5, 0.1)
.color(0.9, 0.7, 0.1) // Gold
)
.saturate(1.2)
.out()

// AUDIO: Baobab polyrhythm
setcps(110/60/2)
$: sound("bell:1 ~ bell:1 bell:1 ~ bell:1 ~ bell:1 bell:1 ~ ~ bell:1")
.gain(0.5).hpf(2000)
$: sound("bd:3 ~ ~ bd:3 ~ ~ bd:3 ~").gain(0.9).lpf(150)
$: sound("rim:3").euclid(7, 12).gain(0.4).hpf(1000).delay(0.2)
$: note("g2 ~ ~ g2, ~ ~ g2 ~, bb2 ~ d3 ~, ~ g2 ~ ~")
.s("triangle").lpf(400).gain(0.6).slow(2)
$: note("").s("pluck")
.gain(0.3).delay(0.3).room(0.4).slow(2)
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 6: G-FUNK SUNSET (98 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Sunset colors, smooth, west coast vibes

/*
await initHydra({ detectAudio: true })

// VISUALS: Sunset, smooth gradients
gradient(0.3)
.color(1, 0.5, 0.2) // Orange
.rotate(() => time * 0.02)
.modulate(
osc(3, 0.1, () => a.fft[1]).color(1, 0.3, 0.5), // Pink
() => a.fft[0] * 0.1
)
.blend(
shape(50, () => 0.1 + a.fft[0] * 0.2, 0.8)
.color(0.9, 0.7, 0.1), // Sun
0.3
)
.saturate(1.4)
.contrast(1.1)
.out()

// AUDIO: G-Funk
setcps(98/60/2)
$: sound("bd ~ ~ bd, ~ ~ bd ~, ~ ~ bd ~, sd ~ ~ ~")
.gain(0.9).lpf(150).slow(2)
$: sound("~ ~ cp ~").gain(0.7).room(0.3)
$: sound("~ hh ~ hh").gain(0.4).hpf(6000)
$: note("c2 ~ ~ [c2 eb2], ~ ~ g1 ~, ab1 ~ ~ ab1, ~ g1 ~ ~")
.s("sine").lpf(200).gain(0.8).slow(2)
$: note("").s("sine")
.lpf(1500).gain(0.3).vib(4).slow(2)
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 7: BONESPURS VISUAL (@eefano tribute)
// ─────────────────────────────────────────────────────────────────────────────
// Hypnotic, evolving, 12-cycle form with matching visuals

/*
await initHydra({ detectAudio: true })

// VISUALS: Evolving over time
src(o0)
.scale(() => 1 + 0.005 * (1 + a.fft[0]))
.rotate(() => 0.002 + a.fft[1] * 0.001)
.saturate(0.995)
.blend(
shape(() => 3 + a.fft[2] * 3, () => 0.3 + a.fft[0] * 0.2, 0.1)
.color(
() => 0.3 + a.fft[0] * 0.3,
() => 0.2 + a.fft[1] * 0.2,
() => 0.6 + a.fft[2] * 0.4
)
.rotate(() => time * 0.05)
, () => 0.03 + a.fft[0] * 0.03
)
.out()

// AUDIO: Bonespurs by @eefano
setcps(90/60/3)
$: "<[-3,0] [-4,0] [-2,0]>/4".layer(
x=>x.sub(7).struct("").n().s('supersaw').clip(1)
.lpf("<300>/12").lpa(0).lpe("<1 1.5 2 2!3>/12").lpd(.15),
x=>x.add(7).s('triangle').gain("<0 .1 .15 .2!3>/12")
.adsr([.5,0,1,.5]).hpf(500)
)
$: "<[0 2 5 0 3 -1 2 3 -1 -2 3 2]>".s('sine').gain("<0 0 .3 .6!3>/12")
$: n(irand(7).add(6).struct("<~@2 [x x] [x ~]>")).s('square')
.hpf(800).lpf(2000).gain(.3).adsr([.01,.2,.1,.4])
.delay(0.2).dfb(.2).mask("<~@3 1!3>/12")
$: s("[bd [~ <~ bd>] sd]").bank('linndrum')
.lpf("<600 800 1000 1200!3>/12").gain(.7)
$: s("rd3").hpf(8000).gain(.1)
all(x=>x.room(.8).scale("f3:minor"))
/

// ─────────────────────────────────────────────────────────────────────────────
// πŸŽ΅πŸ‘οΈ PATTERN 8: MINIMAL TECHNO (130 BPM)
// ─────────────────────────────────────────────────────────────────────────────
// Dark, hypnotic, Berlin vibes

/*
await initHydra({ detectAudio: true })

// VISUALS: Dark, minimal, hypnotic
osc(20, 0.01, 0)
.thresh(() => 0.5 + a.fft[0] * 0.3)
.color(0.1, 0.1, () => 0.2 + a.fft[2] * 0.3)
.rotate(() => time * 0.02)
.kaleid(4)
.modulate(noise(() => a.fft[1] * 2), () => a.fft[0] * 0.1)
.contrast(1.3)
.out()

// AUDIO: Minimal techno
setcps(130/60/2)
$: sound("bd bd bd bd").gain(1).lpf(100)
$: sound("~ ~ ~ ~, ~ ~ ~ cp").gain(0.6).room(0.2)
$: sound("hh8").gain(() => 0.1 + Math.random() * 0.2).hpf(8000)
$: note("")
.s("sawtooth").lpf(sine.range(100, 400).slow(16)).gain(0.6)
$: note("c3").struct("<~ ~ x ~>")
.s("sine").gain(0.2).delay(0.3).dfb(0.6).room(0.4)
/

// ─────────────────────────────────────────────────────────────────────────────
// πŸ”§ HYDRA CHEATSHEET
// ─────────────────────────────────────────────────────────────────────────────
/*
AUDIO REACTIVE:
a.fft[0] = Bass (kick, sub)
a.fft[1] = Low-Mid (snare, bass harmonics)
a.fft[2] = High-Mid (vocals, leads)
a.fft[3] = Highs (hi-hats, cymbals)

SOURCES:
osc(freq, sync, offset)
noise(scale)
shape(sides, radius, smooth)
voronoi(scale, speed, blend)
gradient(speed)
solid(r, g, b, a)
src(o0) // Feedback!

TRANSFORMS:
.rotate(angle)
.scale(amount)
.kaleid(sides)
.pixelate(x, y)
.modulate(source, amount)
.color(r, g, b)
.saturate(amount)
.contrast(amount)
.thresh(threshold)

TIPS:
() => value // Animation
() => a.fft[0] // Audio reactive
() => time // Time-based
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸ™ CREDITS
// ─────────────────────────────────────────────────────────────────────────────
// Strudel: Felix Roos, Alex McLean
// Hydra: Olivia Jack
// Bonespurs: @eefano
// CrumbVisuals: FunkFox 🦊 / Crumbforest
// License: CKL (Children's Knowledge License)