Session 1
Session 2
Group Jam 1
Group Jam 2
Session 1
Session 2
Group Jam 1
Group Jam 2
Before reading this paper, I had never heard the word “technoshamanism” in my life. But after reading it, the concept actually made a lot of sense to me. Shanken explains that a shaman is a person in ancient cultures who had a special role in their community. Using tools like drums, chanting, and plant medicines, they would enter a deep spiritual state and use that experience to heal people. What surprised me is that Shanken argues modern artists are doing the exact same thing, just with technology instead.
The example that hit me the most was Roy Ascott. He traveled to the Amazon and participated in ceremonies using a plant medicine that makes you feel deeply connected to everything around you, like the boundaries between yourself and other people just disappear. He then looked at the internet and realized it creates the exact same feeling. As he wrote, “this ancient ritual mirrors our contemporary artistic aspirations using digital technologies.” That comparison felt so real to me because we experience that sense of connection online every single day.
In live coding, when you perform in a shared session with other people in real time, something interesting happens. You stop focusing on yourself as an individual and instead you become fully absorbed in the collective sound you are all building together. That feeling of losing yourself inside something bigger is exactly what Shanken is describing throughout the whole paper.
Solo session #1
Solo session #2
Group jam 1
Group jam 2
The word “live” originally meant something simple: a performer, on stage, in front of you, doing something in real time. But this paper complicated that definition in ways I did not expect. Auslander argues that “liveness and mediatization can co-occur” (Section 2), meaning something can be pre-built and still be considered live. That already tells you the word has lost a fixed meaning.
The contrast between Deadmau5 and Derek Bailey did not resolve this for me, it made it harder. Bailey believes music should be composed entirely in the moment with “no stylistic or idiomatic commitment” (Section 4), while Deadmau5 openly admits “we all hit play” (Section 3) and is completely comfortable with that. Personally, I side with Deadmau5.
Growing up in the UAE, the music I know is crafted, refined, and then presented. The artistry lives in the preparation, not in making things up on the spot. Deadmau5 himself said it best: “my skills shine where it needs to shine… in the goddamned studio” (Section 3). Showing your screen during a performance does not automatically make it more “live” than presenting finished work with intention. The paper frames live coding as closer to Bailey’s improvisation, but for me, performing your work in front of an audience is what makes it live, regardless of when the composition happened.
solo livecoding practice sessions #1 :
solo livecoding practice sessions #2 :
Group Jam:
When reading Rosa Menkman’s Glitch Studies Manifesto, I found it interesting how she changes the way we usually think about technological errors. Most of the time, we see glitches as annoying problems that should be fixed. But Menkman argues that trying to make technology completely perfect is not really possible. Instead, she encourages us to see glitches as moments that can lead to creativity and new ideas.
What stood out to me most was her point that a glitch only feels powerful for a short moment. Once we explain it too much or turn it into something normal, it loses that special effect. I also found her criticism of fake glitches interesting, especially when they are turned into filters or effects that anyone can use. That made me think about an important question: if we study glitches too much, do we take away the thing that makes them powerful in the first place?
“Matar” (مطر — Rain)
Rain is very rare in the UAE desert, sometimes only 2 or 3 rainy days per year. When it comes, it is considered a blessing. This piece takes you through the full cycle of a rainstorm: from bright sun, to clouds forming, to a full storm with thunder and lightning, to wind clearing the sky, and finally the sun returning peacefully.
This is a 3-minute audio/visual composition about a UAE rainstorm, built with TidalCycles and Hydra.
The piece has 7 sections that follow the story of rain:
A (sun slow) → B (sun bright) → C (clouds form) → D (storm) → E (wind) → F (sun returns) → G (fade out).
Each section adds or removes sound layers and switches the Hydra visuals automatically through MIDI. The audio uses hijaz and bayati scales with tabla for an Arabian feel, and bubble samples for rain, wind samples, and a low 808 kick for thunder. The visuals show a sun that pulses with the drums, clouds that grow, rain streaks falling, trees swaying in the wind, and the sun returning at the end.
Video:
Tidal Code block :
setcps (85/60/4)
sunTone = struct "t(3,8)" $ s "simplesine" >| note (scale "hijaz" "<0 3 5 0>" + "c5") # gain 0.75 # room 0.7
sunBright = struct "t(5,8)" $ sometimesBy 0.2 (shuffle 4) $ s "simplesine" >| note (scale "hijaz" "<0 3 5 7 3>" + "c5") # gain 0.8 # room 0.6
sitar1 = slow 4 $ s "sitar" # n (irand 8) # gain 0.5 # room 0.85 # speed 0.75
drumSlow = every 4 (# n "30 20 10 6") $ s "tabla2(3,8)" # n "2 12 20" # gain 0.75 # room 0.6
drumFast = sometimesBy 0.3 (# speed "1.5 0.8 2") $ s "tabla2(5,8)" # n "3 7 12 20 5" # gain 0.8 # room 0.5
cloudStart = s "bubble(3,16)" # n (irand 8) # gain 0.7 # room 0.7 # speed 0.6
cloudGrow = s "bubble(5,8)" # n (irand 8) # gain 0.75 # room 0.6 # speed "<0.6 0.8 1 0.5>" # lpf (range 800 4000 $ slow 4 saw)
cloudDrum = s "tabla2(3,8)" # n "5 15 25" # gain 0.7 # room 0.5 # speed 0.9
waterDrop = degradeBy 0.2 $ s "bubble*8" # n (irand 8) # gain 0.6 # room 0.8 # speed (range 0.4 1.2 rand)
waterHeavy = s "bubble*16" # n (irand 8) # gain 0.65 # room 0.85 # speed (range 0.3 1 rand)
windCont = s "wind:3" # gain 0.75 # room 0.5 # cut 1 # legato 2
windGust = s "wind:5 wind:3" # gain 0.85 # room 0.4 # cut 2 # legato 2 # speed 1.2
thunder = s "808bd:4(3,8)" # gain 1.1 # room 0.9 # lpf 300 # speed 0.5 # krush 3
stormTab = s "[tabla2*7, tabla2*5]" # n (irand 30) # gain 0.7 # room 0.35
stormMel = fast 2 $ s "simplesine" >| note (arp "pinkyup" (scale "bayati" "[0,1,5,8]" + "<0 -3 2 4>") + "c5") # gain 0.55 # room 0.5 # lpf (range 400 3500 $ slow 2 sine) # pan (slow 3 sine)
earth = slow 4 $ s "simplesine" >| note "c3" # gain 0.35 # lpf 400 # room 0.95
birds = slow 8 $ s "birds" # n (irand 10) # gain 0.55 # room 0.8
endMel = slow 2 $ s "simplesine" >| note (arp "converge" (scale "hijaz" "[0,3,5]" + "<0 4>") + "c5") # gain 0.45 # room 0.9 # delay 0.4 # delaytime 0.3 # delayfeedback 0.4
sec1 = do {
d1 $ sunTone;
d2 $ drumSlow;
d3 $ sitar1;
d4 silence;
d5 $ ccv 0 # ccn 0 # s "midi";
d6 $ ccv (stitch "t(3,8)" 60 15) # ccn 1 # s "midi";
d7 $ ccv (stitch "t(3,8)" 90 0) # ccn 2 # s "midi"
}
sec2 = do {
d1 $ sunBright;
d2 $ drumFast;
d3 $ sitar1 # gain 0.35;
d4 silence;
d5 $ ccv 1 # ccn 0 # s "midi";
d6 $ ccv (stitch "t(5,8)" 90 25) # ccn 1 # s "midi";
d7 $ ccv (stitch "t(5,8)" 110 0) # ccn 2 # s "midi"
}
sec3 = do {
d1 $ sunTone # gain 0.25;
d2 $ stack [cloudStart, cloudDrum];
d3 $ cloudGrow;
d4 $ stack [windCont # gain 0.3, waterDrop # gain 0.3];
d5 $ ccv 2 # ccn 0 # s "midi";
d6 $ ccv (segment 32 (range 20 100 saw)) # ccn 1 # s "midi";
d7 $ ccv (stitch "t(3,8)" 70 0) # ccn 2 # s "midi"
}
sec4 = do {
d1 $ thunder;
d2 $ stormTab;
d3 $ stack [waterHeavy, stormMel];
d4 $ windCont;
d5 $ ccv 3 # ccn 0 # s "midi";
d6 $ ccv (stitch "t(7,8)" 110 40) # ccn 1 # s "midi";
d7 $ ccv (stitch "t(3,8)" 100 0) # ccn 2 # s "midi"
}
sec5 = do {
d1 $ earth;
d2 silence;
d3 $ waterDrop # gain 0.2;
d4 $ windGust;
d5 $ ccv 4 # ccn 0 # s "midi";
d6 $ ccv (segment 32 (range 80 20 saw)) # ccn 1 # s "midi";
d7 $ ccv 0 # ccn 2 # s "midi"
}
sec6 = do {
d1 $ slow 2 $ sunTone # gain 0.5 # room 0.9;
d2 $ drumSlow # gain 0.5;
d3 $ birds;
d4 silence;
d5 $ ccv 5 # ccn 0 # s "midi";
d6 $ ccv (segment 32 (range 40 10 saw)) # ccn 1 # s "midi";
d7 $ ccv (stitch "t(3,8)" 50 0) # ccn 2 # s "midi"
}
sec7 = do {
d1 $ endMel;
d2 silence;
d3 silence;
d4 silence;
d5 $ ccv 6 # ccn 0 # s "midi";
d6 $ ccv (segment 32 (range 10 0 saw)) # ccn 1 # s "midi";
d7 $ ccv 0 # ccn 2 # s "midi"
}
sec1
sec2
sec3
sec4
sec5
sec6
sec7
hush
Hydra code block :
hush()
navigator.requestMIDIAccess().then(function(m) { for (var i of m.inputs.values()) { i.onmidimessage = function(msg) { var arr = msg.data; cc[arr[1]] = arr[2] / 127.0; ccActual[arr[1]] = arr[2]; } } }); var cc = Array(128).fill(0.5); var ccActual = Array(128).fill(0);
loadScript('/Users/salemalshamsi/Desktop/liveCoding/COMPOSITION/matar_visuals_load.js')
visuals[0]()
var whichVisual = 0
update = () => { if (whichVisual != ccActual[0]) { whichVisual = ccActual[0]; if (whichVisual < visuals.length) { visuals[whichVisual]() } } }
Visual load code block :
visuals = [
() => {
solid(0.05, 0.03, 0.12).modulateRotate(noise(1, 0.005), 0.02).out(o2)
shape(99, () => 0.12 + cc[2] * 0.08, 0.4).color(1, 0.85, 0.3).brightness(() => cc[2] * 0.3).out(o1)
src(o2).layer(src(o1)).out(o0)
render(o0)
},
() => {
solid(0.08, 0.05, 0.15).modulateRotate(noise(1, 0.008), 0.03).out(o2)
shape(99, () => 0.18 + cc[2] * 0.1, 0.5).color(1, 0.9, 0.4).brightness(() => cc[2] * 0.4).out(o1)
gradient(0.3).color(0.9, 0.6, 0.2).mult(shape(99, 0.4, 0.6)).hue(() => Math.sin(time * 0.3) * 0.02).out(o3)
src(o2).layer(src(o3).mult(solid(1,1,1), 0.15)).layer(src(o1)).out(o0)
render(o0)
},
() => {
solid(0.1, 0.1, 0.16).out(o2)
shape(99, 0.05, 0.2).color(0.6, 0.5, 0.2).scrollY(-0.12).out(o1)
noise(2.5, 0.04).color(0.8, 0.8, 0.85).thresh(() => 0.75 - cc[1] * 0.4, 0.12).modulate(voronoi(8, 0.02, 0.05), 0.02).scrollY(-0.1).out(o3)
src(o2).layer(src(o1)).layer(src(o3).mult(solid(1,1,1), 0.75)).out(o0)
render(o0)
},
() => {
solid(0.05, 0.06, 0.15).out(o2)
osc(100, 0, 0).thresh(0.9, 0.004).scrollY(0, 0.25).color(0.75, 0.78, 0.88).out(o1)
noise(3, 0.06).color(0.4, 0.4, 0.48).thresh(0.4, 0.15).scrollY(-0.18).modulatePixelate(noise(5, 0.05).pixelate(20, 20), 512).out(o3)
src(o0).diff(src(o2), 0.3).blend(src(o3), 0.06).layer(src(o1).mult(solid(1,1,1), 0.45)).brightness(() => cc[2] * 0.1).contrast(1.2).out(o0)
render(o0)
},
() => {
solid(0.22, 0.28, 0.35).out(o2)
noise(2, 0.05).color(0.5, 0.52, 0.56).thresh(0.5, 0.12).scrollX(0, 0.1).scrollY(-0.2).out(o3)
shape(3, 0.15, 0.02).color(0.15, 0.4, 0.12).rotate(() => Math.sin(time * 2) * 0.25).scrollY(0.22).kaleid(6).scale(0.5).scrollY(0.2).out(o1)
src(o0).diff(src(o0).scale(0.998), 0.6).blend(src(o2), 0.04).layer(src(o3).mult(solid(1,1,1), 0.45)).layer(src(o1).luma(0.08, 0.02)).out(o0)
render(o0)
},
() => {
solid(0.12, 0.18, 0.32).out(o2)
shape(99, 0.13, 0.4).color(1, 0.9, 0.5).brightness(0.15).scrollY(-0.18).out(o1)
solid(0.25, 0.45, 0.18).mult(shape(4, 1, 0.01).scrollY(0.15)).out(o3)
shape(3, 0.08, 0.01).color(0.15, 0.38, 0.1).scrollY(0.24).kaleid(4).scale(0.4).scrollY(0.18).out()
src(o2).layer(src(o3).mult(solid(1,1,1), 0.55)).layer(src(o1)).layer(shape(3, 0.08, 0.01).color(0.15, 0.38, 0.1).scrollY(0.28).scrollX(-0.1).luma(0.08, 0.02)).layer(shape(3, 0.07, 0.01).color(0.15, 0.38, 0.1).scrollY(0.28).scrollX(0.12).luma(0.08, 0.02)).out(o0)
render(o0)
},
() => {
solid(0.03, 0.03, 0.06).out(o2)
shape(99, 0.06, 0.5).color(0.7, 0.6, 0.3).brightness(-0.15).scrollY(-0.1).out(o1)
src(o0).blend(src(o2), 0.1).layer(src(o1).mult(solid(1,1,1), () => 0.5 - time * 0.01)).saturate(0.6).out(o0)
render(o0)
}
]
whichVisual = 0