// ═══════════════════════════════════════════════════════════════════════════
// 🎸 CrumbMidi ADVANCED COLLABORATIVE TECHNIQUES
// ═══════════════════════════════════════════════════════════════════════════
// Inspired by @eefano's patterns
// Techniques: register(), .pickRestart(), .superimpose(), velocity notation
// ═══════════════════════════════════════════════════════════════════════════

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 1: .superimpose() - Self-layering
// ─────────────────────────────────────────────────────────────────────────────
// Creates copies of a pattern with transformations

/*
// Basic: Add octave layer
$: note("")
.s("triangle")
.superimpose(x => x.add(12).gain(0.5)) // +1 octave, quieter
.room(0.3)

// Advanced: Multiple delay layers for stereo spread
$: note("")
.s("sine")
.superimpose(x => x.late(0.125).pan(1).gain(0.6)) // Right, delayed
.superimpose(x => x.late(0.25).pan(0).gain(0.3)) // Left, more delayed
.room(0.4)

// @eefano style: Complex superimpose with room and pan
$: note("")
.s("gm_oboe")
.superimpose(x => x.late(2).gain(0.5).pan("<0 1>/16").room(1.5))
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 2: .pickRestart() - Pattern selection with restart
// ─────────────────────────────────────────────────────────────────────────────
// Selects patterns AND restarts from beginning

/*
// Song structure: Verse β†’ Chorus β†’ Verse β†’ Bridge
$: note("<0 1 0 2>".pickRestart([
// 0 = Verse
"",
// 1 = Chorus
"",
// 2 = Bridge
""
]))
.s("piano")
.room(0.3)
.slow(2)

// With duration control (@)
$: note("<0@7 1 2@4>".pickRestart([
"", // Pattern 0 for 7 beats
"", // Pattern 1 for 1 beat
"" // Pattern 2 for 4 beats
]))
.s("gm_electric_guitar_muted")
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 3: : Velocity Notation
// ─────────────────────────────────────────────────────────────────────────────
// Add velocity/gain directly in the pattern string

/*
// Basic velocity
$: note("c4:0.5 e4:0.7 g4:1 e4:0.7") // Crescendo effect
.s("piano")

// Dynamic drums
$: s("bd:1 bd:0.5 bd:0.7 bd:0.5") // Accented first beat
.bank("tr909")

// Hi-hat groove with accents
$: s("hh:0.3 hh:0.5 hh:0.3 hh:1 hh:0.3 hh:0.5 hh:0.3 hh:0.7")
.bank("tr909")

// Complex pattern with multiple parameters
// note:velocity:param2:param3
$: note("d4:0.7!3 d4:1 c4:0.7!4")
.s("sine")
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 4: register() - Custom Functions
// ─────────────────────────────────────────────────────────────────────────────
// Create your own pattern functions!

/*
// Simple: Octave doubler
const double = register('double', (amount, pat) =>
pat.superimpose(x => x.add(amount))
)

// Usage:
$: note("").double(12).s("triangle") // +1 octave
$: note("").double(7).s("piano") // +fifth

// More complex: Split function (from @eefano)
// Splits pattern values into multiple parameters
const split = register('split', (deflt, callback, pat) =>
callback(deflt.map((d,i) => pat.withValue((v) => {
const isobj = v.value !== undefined
const value = isobj ? v.value : v
const result = Array.isArray(value)
? (i < value.length ? value[i] : d)
: (i == 0 ? value : d)
return (i == 0 && isobj) ? {...v, value: result} : result
})))
)
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 5: samples() - Load Custom Sounds
// ─────────────────────────────────────────────────────────────────────────────
// Load sounds from URLs (freesound.org etc.)

/*
// Load a guitar sample
samples({
'gtr': {
'g3': 'https://cdn.freesound.org/previews/705/705412_11110011-lq.mp3'
}
})

// Use it:
$: s("gtr")
.note("")
.room(0.5)
.slow(2)

// Load multiple samples
samples({
'mykit': {
'kick': 'https://url.to/kick.mp3',
'snare': 'https://url.to/snare.mp3',
'hat': 'https://url.to/hat.mp3'
}
})
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎯 TECHNIQUE 6: .begin() .end() .clip() - Sample Manipulation
// ─────────────────────────────────────────────────────────────────────────────
// Control which part of a sample plays

/*
// Play only part of a sample
$: s("gtr")
.begin(0.045) // Start at 4.5%
.end(0.5) // End at 50%
.clip(1) // Clip to pattern length
.note("g3")

// Create variations from one sample
$: s("bd")
.begin("<0 0.1 0.2 0.3>") // Different start points
.end("<0.5 0.6 0.7 0.8>") // Different end points
*/

// ─────────────────────────────────────────────────────────────────────────────
// 🎸 COMPLETE EXAMPLE: Collaborative Jam Template
// ─────────────────────────────────────────────────────────────────────────────

/*
// === TAB 1: DRUMS & BASS ===
setcps(119/60/4)

$: s("bd ~ bd ~").bank("RolandMT32").gain(0.4).room(0.2)
$: s("~ sd ~ sd").bank("RolandMT32").gain(0.2).room(0.2)
$: s("hh*8").bank("RolandMT32").gain(0.1)

$: note("")
.s("triangle")
.lpf(300)
.gain(0.5)
.slow(2)

// === TAB 2: CHORDS & MELODY ===
setcps(119/60/4)

$: n("0 1 2 3")
.chord("")
.anchor("g4")
.voicing()
.s("gm_electric_guitar_muted")
.gain(0.4)
.slow(2)

$: note("")
.s("sine")
.vib(5).vibmod(0.2)
.gain(0.3)
.superimpose(x => x.late(0.5).gain(0.15).pan(1))
*/

// ─────────────────────────────────────────────────────────────────────────────
// πŸ“‹ QUICK REFERENCE
// ─────────────────────────────────────────────────────────────────────────────
/
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ .superimpose(x => x.transform()) Layer with transformation β”‚
β”‚ .pickRestart([patterns]) Select pattern, restart from beginning β”‚
β”‚ "note:velocity" Inline velocity (0-1) β”‚
β”‚ register('name', fn) Create custom function β”‚
β”‚ samples({name: {note: 'url'}}) Load custom sounds β”‚
β”‚ .begin(0.1).end(0.5) Play part of sample β”‚
β”‚ .clip(1) Clip to pattern length β”‚
β”‚ β”‚
β”‚ MULTIPLAYER: β”‚
β”‚ - Open multiple browser tabs β”‚
β”‚ - They sync automatically! β”‚
β”‚ - Jam together! 🎸πŸ₯ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
/

// ─────────────────────────────────────────────────────────────────────────────
// πŸ™ CREDITS
// ─────────────────────────────────────────────────────────────────────────────
// Pattern techniques learned from @eefano
// Documented by CrumbMidi / FunkFox 🦊
// License: CKL (Children's Knowledge License)

// 🎸 Zusammen spielen - Zusammen wachsen! 🌲