I originally had a more culturally oriented idea in mind for this composition, which I hope to return to later, but I found myself lacking inspiration and direction at this time. To reset, I went back to the class materials, the dirt samples, and revisited the class basics by running patterns again. From there, the piece began to grow more naturally and shifted into an exploration of buildup. I initially wanted to construct everything from my own sampled slices, but ran into challenges shaping them into clean drops and transitions, so the work became a blend of templates and personal material. This led me to a more open and exploratory process building intensity, compressing into darker moments, and then opening back up again.
Tidal
setcps (135/60/4)
visSec = \n -> ccv (pure $ fromIntegral n) # ccn "0" # s "midi"
visSpd = \p -> ccv p # ccn "1" # s "midi"
visHit = \p -> ccv p # ccn "2" # s "midi"
visDark = \p -> ccv p # ccn "3" # s "midi"
visGeom = \p -> ccv p # ccn "4" # s "midi"
visBus = \sec spd hit dark geom ->
stack
[ visSec sec
, visSpd spd
, visHit hit
, visDark dark
, visGeom geom
]
introDrone =
slow 8 $
slice 40 "3" $ s "sudan"
# speed 0.45
# room 0.8
# legato 2
# gain 0.9
airPad =
n (slow 4 "")
# sound "supersaw"
# legato 1.6
# lpf (range 500 1800 $ slow 6 sine)
# resonance 0.22
# room 0.7
# gain 0.45
# shape 0.18
voiceLine = stack
[ fast 2 $
s "simplesine"
>| note (arp "updown" (scale "minor" ("[0,2,4,6]" + "") + "c4"))
# gain 0.62
# lpf 2600
# room 0.55
, s "simplesine"
>| note (scale "minor" ("[,0,2](3,8)") + "c4")
# gain 0.58
# room 0.6
]
versePerc =
stack
[ s "~ cp" # room 0.45 # gain 0.95
, fast 2 $
s "hh*2 hh*2 hh*2 "
# room 0.65
# gain (range 0.9 1.15 rand)
]
habeshaTop =
slice 40 "18" $ s "habesha:1"
# legato 1
# room 0.55
# gain 0.95
kickMain =
s "[, ~ 808:3]"
# room 0.35
# gain 1.0
leadDrop =
n (fast 2 "")
# sound "supersaw"
# legato 0.2
# lpf (range 160 4200 $ slow 3 sine)
# room 0.28
# gain 0.72
# krush 5
# shape 0.3
# pan (slow 2 sine)
buildHat =
stack
[ s "~ cp" # room 0.45 # gain 1.0
, fast 2 $
s "hh*2 hh*2 hh*2 "
# room 0.65
# gain (range 0.95 1.2 rand)
]
# speed (slow 4 $ range 1 2 saw)
buildSnare =
qtrigger $ filterWhen (>=0) $ seqP
[ (0,1, s "feel:2*4")
, (1,2, s "feel:2*8")
, (2,3, s "feel:2*16")
, (3,4, s "feel:2*32")
]
# room 0.25
# hpf (slow 4 $ (1000 * saw + 200))
# speed (slow 4 $ range 1 3 saw)
# gain 0.95
buildPulse =
s ""
# gain 0.8
# lpf (slow 4 $ range 300 2200 saw)
# room 0.2
buildSynth =
n (slow 2 "")
# sound "supersaw"
# legato 0.8
# gain 0.5
# hpf (slow 4 $ range 200 1600 saw)
# lpf (slow 4 $ range 1200 5000 saw)
# room 0.45
# shape 0.25
kickFill =
s "[808bd:1 [~ 808bd:1*3]] [808bd:1 ~ 808bd:1*2]"
# room 0.45
# speed (range 7.6 2.1 saw)
# krush 10
# gain 1.0
dropKick =
s "[bd*2 ] [~ bd*2]"
# gain 1.15
# room 0.25
# shape 0.32
dropBass =
n ""
# sound "supersaw"
# octave 3
# legato 1
# gain 0.95
# lpf (range 120 700 $ slow 2 sine)
# room 0.2
# krush 6
dropPerc =
s ""
# room 0.85
# speed "2 1"
# gain 1.2
# squiz 1.05
# up "-2"
dropMetal =
s "[~ [hc*4 hc*8] ~ hc*16]"
# gain 0.7
# hpf 3500
# room 0.15
dropStab =
n ""
# sound "supersaw"
# legato 0.15
# gain 0.7
# room 0.25
# lpf 1800
# krush 8
silenceAll = do
d1 silence
d2 silence
d3 silence
d4 silence
d5 silence
d6 silence
d7 silence
d8 silence
section_intro = do
d1 $ visBus
0
(slow 8 $ range 8 20 sine)
(struct "t(3,8)" $ range 10 25 saw)
(slow 8 $ range 95 70 sine)
(slow 8 $ range 10 25 sine)
d2 introDrone
d3 airPad
d4 silence
d5 silence
d6 silence
d7 silence
d8 silence
section_verse = do
d1 $ visBus
1
(slow 6 $ range 18 35 sine)
(struct "t(3,8)" $ range 20 45 saw)
(slow 6 $ range 80 60 sine)
(slow 4 $ range 18 40 saw)
d2 voiceLine
d3 versePerc
d4 airPad
d5 habeshaTop
d6 silence
d7 silence
d8 silence
section_build1 = do
d1 $ visBus
2
(slow 4 $ range 30 75 saw)
(struct "t(3,8)" $ range 35 80 saw)
(slow 4 $ range 65 40 saw)
(slow 4 $ range 35 75 saw)
d2 $ qtrigger $ filterWhen (>=0) $ seqP
[ (0,3, voiceLine)
, (3,4, kickFill)
]
d3 buildHat
d4 buildSnare
d5 buildPulse
d6 buildSynth
d7 silence
d8 silence
section_build2 = do
d1 $ visBus
3
(segment 128 $ range 65 120 $ saw)
(segment 64 $ struct "" $ range 60 127 saw)
(segment 64 $ range 45 20 saw)
(segment 64 $ range 60 120 saw)
d2 buildHat
d3 buildSnare
d4 buildPulse
d5 buildSynth
d6 $ qtrigger $ filterWhen (>=0) $ seqP
[ (0,1, s "feel:2*4")
, (1,2, s "feel:2*8")
, (2,3, s "feel:2*16")
, (3,4, s "feel:2*32")
]
# room 0.2
# speed (slow 4 $ range 1 4 saw)
# hpf (slow 4 $ range 1200 8000 saw)
d7 kickFill
d8 silence
section_drop = do
d1 $ visBus
4
(slow 2 $ range 110 70 sine)
(struct "" $ range 90 127 square)
(slow 2 $ range 18 35 sine)
(slow 2 $ range 85 45 saw)
d2 dropKick
d3 dropBass
d4 dropPerc
d5 dropStab
d6 dropMetal
d7 silence
d8 silence
section_after = do
d1 $ visBus
5
(slow 6 $ range 25 45 tri)
(struct "t(3,8)" $ range 30 55 saw)
(slow 6 $ range 70 55 sine)
(slow 8 $ range 25 40 tri)
d2 kickMain
d3 voiceLine
d4 airPad
d5 habeshaTop
d6 silence
d7 silence
d8 silence
section_outro = do
d1 $ visBus
6
(segment 128 $ slow 8 $ range 40 8 sine)
(segment 128 $ slow 8 $ range 35 5 sine)
(segment 128 $ slow 8 $ range 80 100 sine)
(segment 128 $ slow 8 $ range 35 8 sine)
d2 introDrone
d3 silence
d4 silence
d5 silence
d6 silence
d7 silence
d8 silence
goI = section_intro
goV = section_verse
goB1 = section_build1
goB2 = section_build2
goD = section_drop
goA = section_after
goO = section_outro
goI
goB1
goB2
goD
goB1
goD
goA
goO
silenceAll
hush
Hydra
hush()
const ccv = (n, fallback = 0) => () => {
try {
return (cc[n] !== undefined ? cc[n] : fallback) / 127
} catch (e) {
return fallback / 127
}
}
const SECTION = ccv(0, 0)
const SPEED = ccv(1, 20)
const HIT = ccv(2, 0)
const DARK = ccv(3, 80)
const GEOM = ccv(4, 20)
const W = () => window.innerWidth
const H = () => window.innerHeight
const aspect = () => H() / W()
const colorFold = (src, n = 6) =>
new Array(n).fill().reduce(
(a) => a.colorama(() => 0.002 + GEOM() * 0.02),
src
)
const triGrid = () =>
shape(3, 0.32, 0.001)
.rotate(() => time * 0.04 + SPEED() * 0.4, () => 0.02 + HIT() * 0.08)
.repeat(
() => 2 + Math.floor(GEOM() * 6),
() => 2 + Math.floor(GEOM() * 4)
)
.scrollX(() => 0.02 * Math.sin(time * 0.3))
.scrollY(() => 0.02 * Math.cos(time * 0.2))
.luma(0.15, 0.2)
const quadGrid = () =>
shape(4, 0.45, 0.0001)
.repeat(
() => 2 + Math.floor(GEOM() * 5),
() => 2 + Math.floor(GEOM() * 5)
)
.rotate(() => time * 0.02 + SPEED() * 0.2)
.scale(1, aspect(), 1)
.luma(0.2, 0.15)
const movingOsc = () =>
osc(
() => 8 + SPEED() * 65,
() => 0.015 + SPEED() * 0.08,
() => 0.4 + HIT() * 3.2
)
.posterize(() => 3 + Math.floor(GEOM() * 4))
.kaleid(() => 3 + Math.floor(SECTION() * 8))
.scale(1, aspect(), 1)
.color(
() => 0.5 + DARK() * 0.4,
() => 0.15 + SECTION() * 0.35,
() => 0.35 + GEOM() * 0.4
)
const texture = () =>
noise(
() => 1.5 + GEOM() * 8,
() => 0.02 + SPEED() * 0.03
)
.pixelate(
() => 8 + GEOM() * 50,
() => 8 + GEOM() * 40
)
.luma(0.35, 0.25)
const darkWash = () =>
solid(0, 0, 0)
.add(
osc(
() => 6 + SPEED() * 18,
0.01,
0
)
.rotate(() => time * 0.01)
.luma(0.25, 0.25)
.color(0,0,0),
() => 0.15 + (1 - DARK()) * 0.55
)
const accentLines = () =>
osc(
() => 12 + HIT() * 35,
0.01,
1
)
.rotate(() => Math.PI/4 + time * 0.01)
.luma(0.78, 0.18)
.color(
() => 0.15 + SECTION() * 0.18,
() => 0.25 + DARK() * 0.2,
() => 0.35 + DARK() * 0.25
)
.mult(quadGrid())
.mult(
osc(3,0.02,0)
.rotate(Math.PI/2)
.luma(0.6,0.2)
)
const scene = () =>
colorFold(
movingOsc()
.modulate(
texture(),
() => 0.03 + GEOM() * 0.16
)
.mult(triGrid().add(quadGrid(), 0.5)),
8
)
.add(texture(), () => 0.05 + GEOM() * 0.08)
src(o1)
.modulateRotate(
noise(
() => 1 + GEOM() * 5,
() => 0.01 + SPEED() * 0.02
),
() => 0.003 + HIT() * 0.05
)
.scale(() => 1.0005 + HIT() * 0.01)
.rotate(() => 0.0008 + SPEED() * 0.01)
.blend(scene(), 0.82)
.add(accentLines(), () => 0.04 + DARK() * 0.06)
.add(darkWash(), () => 0.2 + (1 - DARK()) * 0.45)
.saturate(() => 1 + DARK() * 1.2)
.contrast(() => 1.0 + HIT() * 0.3)
.brightness(() => -0.18 + DARK() * 0.18)
.out(o1)
render(o1)