1--- 2title: First Notes 3layout: ../../layouts/MainLayout.astro 4--- 5 6import { MiniRepl } from '@src/docs/MiniRepl'; 7import { midi2note } from '@strudel/core'; 8import Box from '@components/Box.astro'; 9import QA from '@components/QA'; 10 11# First Notes 12 13Let's look at how we can play notes 14 15## numbers and notes 16 17**play notes with numbers** 18 19<MiniRepl 20 client:visible 21 tune={`note("48 52 55 59").sound("piano")`} 22 claviature 23 claviatureLabels={Object.fromEntries( 24 Array(49) 25 .fill() 26 .map((_, i) => [midi2note(i + 36), i + 36]), 27 )} 28/> 29 30<Box> 31 32Try out different numbers! 33 34Try decimal numbers, like 55.5 35 36</Box> 37 38**play notes with letters** 39 40<MiniRepl 41 client:visible 42 tune={`note("c e g b").sound("piano")`} 43 claviature 44 claviatureLabels={Object.fromEntries(['c3', 'd3', 'e3', 'f3', 'g3', 'a3', 'b3'].map((n) => [n, n.split('')[0]]))} 45/> 46 47<Box> 48 49Try out different letters (a - g). 50 51Can you find melodies that are actual words? Hint: ☕ 😉 ⚪ 52 53</Box> 54 55**add flats or sharps to play the black keys** 56 57<MiniRepl 58 client:visible 59 tune={`note("db eb gb ab bb").sound("piano")`} 60 claviature 61 claviatureLabels={Object.fromEntries( 62 ['db3', 'eb3', 'gb3', 'ab3', 'bb3'].map((n) => [n, n.split('').slice(0, 2).join('')]), 63 )} 64/> 65 66<MiniRepl 67 client:visible 68 tune={`note("c# d# f# g# a#").sound("piano")`} 69 claviature 70 claviatureLabels={Object.fromEntries( 71 ['c#3', 'd#3', 'f#3', 'g#3', 'a#3'].map((n) => [n, n.split('').slice(0, 2).join('')]), 72 )} 73/> 74 75**play notes with letters in different octaves** 76 77<MiniRepl 78 client:visible 79 tune={`note("c2 e3 g4 b5").sound("piano")`} 80 claviature 81 claviatureLabels={Object.fromEntries( 82 Array(49) 83 .fill() 84 .map((_, i) => [midi2note(i + 36), midi2note(i + 36)]), 85 )} 86/> 87 88<Box> 89 90Try out different octaves (1-8) 91 92</Box> 93 94If you are not comfortable with the note letter system, it should be easier to use numbers instead. 95Most of the examples below will use numbers for that reason. 96We will also look at ways to make it easier to play the right notes later. 97 98## changing the sound 99 100Just like with unpitched sounds, we can change the sound of our notes with `sound`: 101 102<MiniRepl client:visible tune={`note("36 43, 52 59 62 64").sound("piano")`} /> 103 104{/* c2 g2, e3 b3 d4 e4 */} 105 106<Box> 107 108Try out different sounds: 109 110- gm_electric_guitar_muted 111- gm_acoustic_bass 112- gm_voice_oohs 113- gm_blown_bottle 114- sawtooth 115- square 116- triangle 117- how about bd, sd or hh? 118- remove `.sound('...')` completely 119 120</Box> 121 122**switch between sounds** 123 124<MiniRepl 125 client:visible 126 tune={`note("48 67 63 [62, 58]") 127.sound("piano gm_electric_guitar_muted")`} 128/> 129 130**stack multiple sounds** 131 132<MiniRepl 133 client:visible 134 tune={`note("48 67 63 [62, 58]") 135.sound("piano, gm_electric_guitar_muted")`} 136/> 137 138<Box> 139 140The `note` and `sound` patterns are combined! 141 142We will see more ways to combine patterns later.. 143 144</Box> 145 146## Longer Sequences 147 148**Divide sequences with `/` to slow them down** 149 150<MiniRepl client:visible tune={`note("[36 34 41 39]/4").sound("gm_acoustic_bass")`} punchcard /> 151 152<Box> 153 154The `/4` plays the sequence in brackets over 4 cycles (=8s). 155 156So each of the 4 notes is 2s long. 157 158Try adding more notes inside the brackets and notice how it gets faster. 159 160</Box> 161 162**Play one per cycle with `< ... >`** 163 164In the last section, we learned that `< ... >` (angle brackets) can be used to play only one thing per cycle, 165which is useful for longer melodies too: 166 167<MiniRepl client:visible tune={`note("<36 34 41 39>").sound("gm_acoustic_bass")`} punchcard /> 168 169<Box> 170 171Try adding more notes inside the brackets and notice how the tempo stays the same. 172 173The angle brackets are actually just a shortcut: 174 175`<a b c>` = `[a b c]/3` 176 177`<a b c d>` = `[a b c d]/4` 178 179... 180 181</Box> 182 183**Play one sequence per cycle** 184 185We can combine the 2 types of brackets in all sorts of different ways. 186Here is an example of a repetitive bassline: 187 188<MiniRepl 189 client:visible 190 tune={`note("<[36 48]*4 [34 46]*4 [41 53]*4 [39 51]*4>") 191.sound("gm_acoustic_bass")`} 192 punchcard 193/> 194 195**Alternate between multiple things** 196 197<MiniRepl 198 client:visible 199 tune={`note("60 <63 62 65 63>") 200.sound("gm_xylophone")`} 201 punchcard 202/> 203 204This is also useful for unpitched sounds: 205 206<MiniRepl 207 client:visible 208 tune={`sound("bd*4, [~ <sd cp>]*2, [~ hh]*4") 209.bank("RolandTR909")`} 210 punchcard 211/> 212 213## Scales 214 215Finding the right notes can be difficult.. Scales are here to help: 216 217<MiniRepl 218 client:visible 219 tune={`setcpm(60) 220n("0 2 4 <[6,8] [7,9]>") 221.scale("C:minor").sound("piano")`} 222 punchcard 223/> 224 225<Box> 226 227Try out different numbers. Any number should sound good! 228 229Try out different scales: 230 231- C:major 232- A2:minor 233- D:dorian 234- G:mixolydian 235- A2:minor:pentatonic 236- F:major:pentatonic 237 238</Box> 239 240**automate scales** 241 242Just like anything, we can automate the scale with a pattern: 243 244<MiniRepl 245 client:visible 246 tune={`setcpm(60) 247n("<0 -3>, 2 4 <[6,8] [7,9]>") 248.scale("<C:major D:mixolydian>/4") 249.sound("piano")`} 250 punchcard 251/> 252 253<Box> 254 255If you have no idea what these scale mean, don't worry. 256These are just labels for different sets of notes that go well together. 257 258Take your time and you'll find scales you like! 259 260</Box> 261 262## Repeat & Elongate 263 264**Elongate with @** 265 266<MiniRepl client:visible tune={`note("c@3 eb").sound("gm_acoustic_bass")`} punchcard /> 267 268<Box> 269 270Not using `@` is like using `@1`. In the above example, c is 3 units long and eb is 1 unit long. 271 272Try changing that number! 273 274</Box> 275 276**Elongate within sub-sequences** 277 278<MiniRepl 279 client:visible 280 tune={`setcpm(60) 281n("<[4@2 4] [5@2 5] [6@2 6] [5@2 5]>*2") 282.scale("<C2:mixolydian F2:mixolydian>/4") 283.sound("gm_acoustic_bass")`} 284 punchcard 285/> 286 287<Box> 288 289This groove is called a `shuffle`. 290Each beat has two notes, where the first is twice as long as the second. 291This is also sometimes called triplet swing. You'll often find it in blues and jazz. 292 293</Box> 294 295**Replicate** 296 297<MiniRepl 298 client:visible 299 tune={`setcpm(60) 300note("c!2 [eb,<g a bb a>]").sound("piano")`} 301 punchcard 302/> 303 304<Box> 305 306Try switching between `!`, `*` and `@` 307 308What's the difference? 309 310</Box> 311 312## Recap 313 314Let's recap what we've learned in this chapter: 315 316| Concept | Syntax | Example | 317| --------- | ------ | -------------------------------------------------------- | 318| Slow down | \/ | <MiniRepl client:visible tune={`note("[c a f e]/2")`} /> | 319| Alternate | \<\> | <MiniRepl client:visible tune={`note("c a f <e g>")`} /> | 320| Elongate | @ | <MiniRepl client:visible tune={`note("c@3 e")`} /> | 321| Replicate | ! | <MiniRepl client:visible tune={`note("c!3 e")`} /> | 322 323New functions: 324 325| Name | Description | Example | 326| ----- | ----------------------------- | --------------------------------------------------------------------------------- | 327| note | set pitch as number or letter | <MiniRepl client:visible tune={`note("b g e c").sound("piano")`} /> | 328| scale | interpret `n` as scale degree | <MiniRepl client:visible tune={`n("6 4 2 0").scale("C:minor").sound("piano")`} /> | 329| $: | play patterns in parallel | <MiniRepl client:visible tune={'$: s("bd sd")\n$: note("c eb g")'} /> | 330 331## Examples 332 333**Classy Bassline** 334 335<MiniRepl 336 client:visible 337 tune={`note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>") 338.sound("gm_synth_bass_1") 339.lpf(800) // <-- we'll learn about this soon`} 340/> 341 342**Classy Melody** 343 344<MiniRepl 345 client:visible 346 tune={`n(\`< 347[~ 0] 2 [0 2] [~ 2] 348[~ 0] 1 [0 1] [~ 1] 349[~ 0] 3 [0 3] [~ 3] 350[~ 0] 2 [0 2] [~ 2] 351>*4\`).scale("C4:minor") 352.sound("gm_synth_strings_1")`} 353/> 354 355**Classy Drums** 356 357<MiniRepl 358 client:visible 359 tune={`sound("bd*4, [~ <sd cp>]*2, [~ hh]*4") 360.bank("RolandTR909")`} 361/> 362 363**If there just was a way to play all the above at the same time.......** 364 365<Box> 366 367You can use `$:` 😙 368 369</Box> 370 371## Playing multiple patterns 372 373If you want to play multiple patterns at the same time, make sure to write `$:` before each: 374 375<MiniRepl 376 client:visible 377 tune={`$: note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>") 378 .sound("gm_synth_bass_1").lpf(800) 379 380$: n(\`< 381 [~ 0] 2 [0 2] [~ 2] 382 [~ 0] 1 [0 1] [~ 1] 383 [~ 0] 3 [0 3] [~ 3] 384 [~ 0] 2 [0 2] [~ 2] 385 >*4\`).scale("C4:minor") 386 .sound("gm_synth_strings_1") 387 388$: sound("bd*4, [~ <sd cp>]*2, [~ hh]*4") 389.bank("RolandTR909")`} 390/> 391 392<Box> 393 394Try changing `$` to `_$` to mute a part! 395 396</Box> 397 398This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects)