This commit is contained in:
Bubobubobubobubo
2023-10-04 23:39:10 +00:00
parent 3c2d5b713d
commit 4990d9dc4b
2 changed files with 41 additions and 29 deletions

View File

@ -469,14 +469,14 @@ pulse([48/2, 48/3].beat(4)) :: snd('hand')
`,!0)}
${e("pulse is the OG rhythmic function in Topos",`
pulse([48, 24, 16].beat(4)) :: sound('linnhats').out()
beat(1)::snd('bd').out()
beat(1)::snd(['bd', '808oh'].beat(1)).out()
`,!1)};
- <ic>onbeat(...n: number[])</ic>: The <ic>onbeat</ic> function allows you to lock on to a specific beat from the clock to execute code. It can accept multiple arguments. It's usage is very straightforward and not hard to understand. You can pass either integers or floating point numbers. By default, topos is using a <ic>4/4</ic> bar meaning that you can target any of these beats (or in-between) with this function.
${e("Some simple yet detailed rhythms",`
onbeat(1,2,3,4)::snd('kick').out() // Bassdrum on each beat
onbeat(2,4)::snd('snare').n([0,2].beat(2.5)).out() // Snare on acccentuated beats
onbeat(2,4)::snd('snare').n([8,4].beat(4)).out() // Snare on acccentuated beats
onbeat(1.5,2.5,3.5, 3.75)::snd('hat').gain(r(0.9,1.1)).out() // Cool high-hats
`,!0)}
@ -491,22 +491,20 @@ beat([.25, 1/8].beat(1.5))::snd('hat').n(2)
- <ic>oncount(beats: number[], meter: number)</ic>: This function is similar to <ic>onbeat</ic> but it allows you to specify a custom number of beats as the last argument.
${e("Using oncount to create more variation in the rhythm",`
bpm(120)
z1('0.125 (0 2 3 4)+(0 2 4 6)').sound('sawtooth')
.cutoff([400,500,1000,2000].beat(1))
.lpadsr(2, 0, .2, 0, 0)
.delay(0.5).delayt(0.25).room(0.9).size(0.9).out()
onbeat(1,1.5,2,3,4) :: sound('bd').gain(2.0).out()
oncount([1,3,5.5,7,7.5,8],8) :: sound('hh').gain(irand(1.0,4.0)).out()
z1('1/16 (0 2 3 4)+(0 2 4 6)').scale('pentatonic').sound('sawtooth')
.cutoff([400,500,1000,2000].beat(1))
.lpadsr(2, 0, .2, 0, 0)
.delay(0.5).delayt(0.25).room(0.9).size(0.9).out()
onbeat(1,1.5,2,3,4) :: sound('bd').gain(2.0).out()
oncount([1,3,5.5,7,7.5,8],8) :: sound('hh').gain(irand(1.0,4.0)).out()
`,!0)}
${e("Using oncount to create rhythms with a custom meter",`
bpm(200)
oncount([1, 5, 9, 13],16) :: sound('bd').gain(1.0).out()
oncount([5, 6, 13],16) :: sound('cp').gain(0.9).out()
oncount([2, 3, 3.5, 6, 7, 10, 15],16) :: sound('hh').n(8).gain(0.8).out()
oncount([1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16],16) ::
sound('hh').out()
bpm(200)
oncount([1, 5, 9, 13],16) :: sound('808bd').n(4).shape(0.5).gain(1.0).out()
oncount([5, 6, 13],16) :: sound('shaker').room(0.25).gain(0.9).out()
oncount([2, 3, 3.5, 6, 7, 10, 15],16) :: sound('hh').n(8).gain(0.8).out()
oncount([1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16],16) :: sound('hh').out()
`,!0)}
## Rhythm generators
@ -516,23 +514,30 @@ We included a bunch of popular rhythm generators in Topos such as the euclidian
- <ic>euclid(iterator: number, pulses: number, length: number, rotate: number): boolean</ic>: generates <ic>true</ic> or <ic>false</ic> values from an euclidian rhythm sequence. This algorithm is very popular in the electronic music making world.
${e("Classic euclidian club music patterns",`
beat(.5) && euclid($(1), 5, 8) && snd('kick').out()
beat(.5) && euclid($(2), 2, 8) && snd('sd').out()
beat(4) :: sound('cp').out()
beat(.5) && euclid($(1), 4, 8) && snd('kick').n(4).out()
beat(.25) && euclid($(2), 5, 8) && snd('dr').n(21).out()
beat(.25) && euclid($(3), 3, 8) && snd('shaker')
.gain(r(0.7, 1)).cutoff(1000 + usine(1/8) * 3000)
.n(11).out()
beat(.25) && euclid($(3), 6, 8) && snd('shaker')
.gain(r(0.7, 1)).cutoff(1000 + usine(1/4) * 4000)
.speed(2).n(11).out()
`,!0)}
${e("And now something a bit more complex",`
bpm(145); // Setting a faster BPM
beat(.5) && euclid($(1), 5, 8) :: sound('bd').out()
beat(.5) && euclid($(2), [1,0].beat(8), 8)
:: sound('ST03').n(3).room(1).size(1).o(1).out()
:: sound('ST03').n(5).room(1).size(1).o(1).out()
beat(.5) && euclid($(6), [6,7].beat(8), 8) :: sound('hh').out()
`,!1)}
${e("Adding more rhythmic density",`
beat(.5) && euclid($(1), 5, 9) && snd('kick').out()
beat(.5) && euclid($(2), 2, 3, 1) && snd('east').end(0.5).n(5).speed([1,2].beat(2)).out()
beat(.5) && euclid($(3), 6, 9, 1) && snd('east').end(0.5).n(5).freq(200).speed([2,1].beat(2)).out()
beat(.5) && euclid($(1), 5, 9) && snd('kick').shape(r(0.2,0.5)).out()
beat(.5) && euclid($(2), 2, 3, 1) && snd('dr').end(0.5).n([8,9,13].beat(0.25))
.gain(r(0.5,1)).speed(1).out()
beat(.5) && euclid($(3), 6, 9, 1) && snd('dr').end(0.5).n(2).freq(200).speed(1)
.gain(r(0.5,1)).out()
beat(.25) && euclid($(4), 7, 9, 1) && snd('hh').out()
`,!1)}
@ -560,8 +565,8 @@ rhythm(speed, 7, 12) :: snd('east').n(9).out()
${e("Change the integers for a surprise rhythm!",`
bpm(135);
beat(.5) && bin($(1), 34) && snd('kick').n([1,3].beat(1)).out()
beat(.5) && bin($(2), 48) && snd('snare').n([1,4].beat(1)).out()
beat(.5) && bin($(1), 12) && snd('kick').n([4,9].beat(1.5)).out()
beat(.5) && bin($(2), 34) && snd('snare').n([3,5].beat(1)).out()
`,!0)}
${e("binrhythm for fast cool binary rhythms!",`
@ -688,8 +693,16 @@ beat(.5)::snd(flip(4) ? 'kick' : 'hat').out()
- <ic>flipbar(n: number = 1)</ic>: this method works just like <ic>flip</ic> but counts in bars instead of beats. It allows you to think about even larger time cycles. You can also pair it with regular <ic>flip</ic> for writing complex and long-spanning algorithmic beats.
${e("Thinking music over bars",`
flipbar(2) :: beat(1):: snd('kick').out()
flipbar(3) :: beat(.5):: snd('hat').out()
let roomy = (n) => n.room(1).size(1).cutoff(500 + usaw(1/8) * 5000);
function a() {
beat(1) && roomy(sound('kick')).out()
beat(.5) && roomy(sound('hat')).out()
}
function b() {
beat(1/4) && roomy(sound('shaker')).out()
}
flipbar(2) && a()
flipbar(3) && b()
`,!0)}
${e("Alternating over four bars",`
flipbar(2)
@ -2432,8 +2445,7 @@ I won't teach you how to play with Hydra. You can find some great resources on t
- [Hydra interactive documentation](https://hydra.ojack.xyz/docs/)
- [List of Hydra Functions](https://hydra.ojack.xyz/api/)
- [Source code on GitHub](https://github.com/hydra-synth/hydra)
`},Ot=n=>`<kbd class="lg:px-2 lg:py-1.5 px-1 py-1 lg:text-sm text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500">${n}</kbd>`,ln=n=>(t,r,i=!1)=>{const s=`codeExample${n.exampleCounter++}`;return n.api.codeExamples[s]=`bpm(120);
`+r,`
`},Ot=n=>`<kbd class="lg:px-2 lg:py-1.5 px-1 py-1 lg:text-sm text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500">${n}</kbd>`,ln=n=>(t,r,i=!1)=>{const s=`codeExample${n.exampleCounter++}`;return n.api.codeExamples[s]=r,`
<details ${i?"open":""}>
<summary >${t}
<button class="py-1 align-top text-base rounded-lg pl-2 pr-2 hover:bg-green-700 bg-green-600 inline-block" onclick="app.api._playDocExample(app.api.codeExamples['${s}'])"> Play</button>