making music with code, in the web with js
more detailed notes
my attempts
- was trying to go for ambient, moody game music :p
- a first attempt from me
- eerie
- second attempt
- tried layered piano, just wanted to use the crow sample lol
- strudel bases
- a first attempt from me
⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⣼⣿⣿⣦⠀⠀⠀ ⠀⠀⠀⠀⠀⢰⣿⠁⠀⢹⡄⠀⠀ ⠀⠀⠀⠀⠀⢸⣿⠀⠀⣾⡇⠀⠀ ⠀⠀⠀⠀⠀⠈⣿⢀⣾⣿⠀⠀⠀ ⠀⠀⠀⠀⠀⣀⣿⣿⣿⠃⠀⠀⠀ ⠀⠀⠀⣠⣾⣿⣿⡟⠁⠀⠀⠀⠀ ⠀⢠⣾⣿⠟⠁⠘⡇⠀⠀⠀⠀⠀ ⢀⣿⡟⠁⠀⣠⣶⣿⣶⣶⣤⡀⠀ ⢸⣿⠀⠀⣼⣿⠟⢻⡛⠻⣿⣷⠀ ⠘⣿⡀⠀⢹⣇⠀⠘⡇⠀⠘⣿⠇ ⠀⠙⣷⡄⠀⠙⠂⠀⣷⠀⣸⡟⠀ ⠀⠀⠈⠙⠷⢦⣤⣤⣼⡞⠋⠀⠀ ⠀⠀⠀⠀⢀⣀⡀⠀⠸⡇⠀⠀⠀ ⠀⠀⠀⠀⣿⣿⣿⠀⢠⡇⠀⠀⠀ ⠀⠀⠀⠀⠈⠛⠷⠖⠋⠀⠀⠀⠀
Basic Tutorial!
https://strudel.cc/workshop/first-sounds/ i had a lot more fun with this than i expected
all functions covered: https://strudel.cc/workshop/recap/
drums + sequencing
bd= bass drum- base
sd= snare drumrim= rimshot- brief
hh= hihat- soft
oh= open hihat- rings
lt= low tom- deep low
mt= middle tomht= high tomrd= ride cymbal- light cymbal
cr= crash cymbal.bank("")to specify drum machine
drum examples:
- RolandTR909
- famous for house and techno beats
- AkaiLinn
- 80s
- RhythmAce
- analog sound
- RolandTR707
Sequences
- space-separated arrays - longer = faster
sound("bd hh sd oh rim")
- sequence content is squished into a cycle
< >plays one sound per cycle- change speed with
*n
- change speed with
- can also set tempo
setcpm(90/4)- cycles per minute- default is 120cycles/4min = 1 cycle per 2 seconds
-for pauses[ ]for sub-sequences, which are squished and same as sequences- can create pitch with really fast rhythmns like
hh*32 - use commas to play sequences in parallel
sound(hh hh hh, bd casio)
- can select samples granularly or with
nfunctionsound("jazz:0 jazz:1 [jazz:4 jazz:2] jazz:3*2")n("0 1 [4 2] 3*2").sound("jazz")
examples
- Rock:
setcpm(100/4)
sound("[bd sd]*2, hh*8").bank("RolandTR505")
- Classic House
sound("bd*4, [- cp]*2, [- hh]*4").bank("RolandTR909")
- `cp` = clap
setcpm(90/4)
sound(`
[- - oh - ] [- - - - ] [- - - - ] [- - - - ],
[hh hh - - ] [hh - hh - ] [hh - hh - ] [hh - hh - ],
[- - - - ] [cp - - - ] [- - - - ] [cp - - - ],
[bd - - - ] [- - - bd] [- - bd - ] [- - - bd]
`)
notes
note("48 52 55 59").sound("piano")
note("c e g b").sound("piano")
note("c# d# fb g# a#").sound("piano") // mysterious
note("c2 e3 g4 b5").sound("piano") // octaves
note("36 43, 52 59 62 64").sound("sawtooth") // i like how this sounds
- numbers for pitch! use decimals for microtonal pitches
- letters for pitch! add b or # for sharps/flats
- specify octaves with numbers (1-8)
- lower octaves more ominous
note sounds
- piano
- sawtooth (good for game)
- square (makes me think of distortion and fnaf animatronics)
- triangle (muted electronic sounding)
- can also pitch drums
- gm_electric_guitar_muted
- gm_voice_oohs (veeery creepy game vibes)
- gm_blown_bottle
switch between sounds (by beat/cycle count)
note("48 67 63 [62, 58]")
.sound("piano gm_electric_guitar_muted")
stack sounds
note("48 67 63 [62, 58]")
.sound("piano, gm_electric_guitar_muted")
// use $: to stack multiple lines
- multiply / divide sequences to change speed
- angle brakets useful for longer melodies
play one sequence per cycle
- for ex., repetitive bassline
note("<[36 48]*4 [34 46]*4 [41 53]*4 [39 51]*4>")
.sound("gm_acoustic_bass")
can alternate between things
note("60 <63 62 65 63>")
.sound("gm_xylophone")
// good for beats
sound("bd*4, [~ <sd cp>]*2, [~ hh]*4")
.bank("RolandTR909")
can use scales and relative pitch
setcpm(60)
n("0 2 4 <[6,8] [7,9]>")
.scale("D:dorian").sound("piano")
can automate scales with a pattern
setcpm(60)
n("<0 -3>, 2 4 <[6,8] [7,9]>")
.scale("<C:major D:mixolydian>/4")
.sound("piano")
repeat and elongate notes - @unit
note("c@3 eb").sound("gm_acoustic_bass")
example: shuffle groove / triplet swing
setcpm(60)
n("<[4@2 4] [5@2 5] [6@2 6] [5@2 5]>*2")
.scale("<C2:mixolydian F2:mixolydian>/4")
.sound("gm_acoustic_bass")
*affects speed within the unit/count,!affects speed within the cycle??
setcpm(60)
note("c!4 [eb,<g a bb a>]").sound("piano")
effects
note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
.sound("sawtooth").lpf(800)
// can pattern the filter, which does not affect rhythmn
note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
.sound("sawtooth").lpf("200 1000 200 1000")
-
.lpf()= low-pass filter -
.vowel()- a e i o -
.gain()- gain -
short notation
adsr(".1:.1:.5:.2")
-
.delay(".8:.06:.8")- a: delay volume
- b: delay time
- c: feedback (smaller num = quicker fade)
-
reverb
.room(2)
-
pan
.pan(0 0.3 .6 1)
-
speed (of pitch?)
sound("bd rim [~ bd] rim").speed("<1 2 -1 -2>").room(.2)
modulation w waves
sound(hh*16).gain(sine)- sine
- saw (like crescendo or decrescendo)
- square
- tri
- rand
- perlin
- can change values that waves oscillate between
sound("hh*16").lpf(saw.range(500, 2000))
// can change modulation speed with .slow or .fast, which replace * and /
note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
.sound("sawtooth")
.lpf(sine.range(100, 2000).slow(4))
pattern effects
…more complicated stuff
- multiple tempos
- reverse patterns, .jux splits left/right
- ply
- add numbers to notes to change pitch within patterns
setcpm(60)
note("c2 [eb3,g3] ".add("<0 <1 -1>>"))
.color("<cyan <magenta yellow>>").adsr("[.1 0]:.2:[1 0]")
.sound("gm_acoustic_bass").room(.5)
- .off - offset the given pattern
n("0 [4 <3 2>] <2 3> [~ 1]"
.off(1/16, x=>x.add(4))
//.off(1/8, x=>x.add(7))
).scale("<C5:minor Db5:mixolydian>/2")
.s("triangle").room(.5).dec(.1)
Synths
todo https://strudel.cc/learn/synths/