From f9bce56f9e9f2ccd01c74e774a4d94b5da149f76 Mon Sep 17 00:00:00 2001 From: Edgar Delgado Vega Date: Sun, 17 Dec 2023 17:29:19 -0500 Subject: [PATCH] docs(generators): add an example of a continuous attractor and a discrete attractor --- src/documentation/patterns/generators.ts | 69 +++++++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/documentation/patterns/generators.ts b/src/documentation/patterns/generators.ts index ba80105..c3a4d93 100644 --- a/src/documentation/patterns/generators.ts +++ b/src/documentation/patterns/generators.ts @@ -8,7 +8,7 @@ export const generators = (application: Editor): string => { JavaScript generators are powerful functions for generating value sequences. They can be used to generate melodies, rhythms or control parameters. -In Topos generator functions should be called using the cache(key, function) function to store the current state of the generator. This function takes two arguments: the name for the cache and the generator instance. +In Topos generator functions should be called using the cache(key, function) function to store the current state of the generator. This function takes two arguments: the name for the cache and the generator instance. Once the generator is cached the values will be returned from the named cache even if the generator function is modified. To clear the current cache and to re-evaluate the modified generator use the **Shift+Ctrl+Backspace** shortcut. Alternatively you can cache the modified generator using a different name. @@ -38,14 +38,16 @@ ${makeExample( const s = Math.tan(x/10)+Math.sin(x/20); yield 2 * Math.pow(s, 3) - 6 * Math.pow(s, 2) + 5 * s + 200; x++; - } + } } - + beat(.125) && sound("triangle").freq(cache("mathyshit",poly())).out() `, true, )}; +When you want to dance with a dynamic system in controlled musical chaos, Topos is waiting for you: + ${makeExample( "Truly scale free chaos inspired by Lorentz attractor", ` @@ -54,16 +56,16 @@ ${makeExample( const dx = 10 * (y - x); const dy = x * (rho - z) - y; const dz = x * y - beta * z; - + x += dx * 0.01; y += dy * 0.01; z += dz * 0.01; - + const value = 300 + 30 * (Math.sin(x) + Math.tan(y) + Math.cos(z)) yield value; } } - + beat(0.25) :: sound("triangle") .freq(cache("stranger",strange(3,5,2))) .adsr(.15,.1,.1,.1) @@ -72,9 +74,60 @@ ${makeExample( true, )}; +${makeExample( + "Henon and his discrete music", + ` + function* henonmap(x = 0, y = 0, a = 1.4, b = 0.3) { + while (true) { + const newX = 1 - a * x ** 2 + y; + const newY = b * x; + const fusionPoint = newX + newY + yield fusionPoint * 300; + [x, y] = [newX, newY] + } + } + + beat(0.25) :: sound("sawtooth") + .semitones(1,1,2,2,2,1,2,1) + .freq(cache("henonSynth", henonmap())) + .adsr(0, 0.1, 0.1, 0.5).out() + + z0('1 {-2}').octave(-2).sound('bd').out() + z1('e. 1 s 3!2 e 3!2 s 9 8 1') + .sound('dr').gain(0.3).octave(-5).out() + `, + true, + )}; + +${makeExample( + "1970s fractal dream", + ` + function* rossler(x = 0.1, y = 0.1, z = 0.1, a = 0.2, b = 0.2, c = 5.7) { + while (true) { + const dx = - y - z; + const dy = x + (a * y); + const dz = b + (x * z) - (c * z); + + x += dx * 0.01; + y += dy * 0.01; + z += dz * 0.01; + + const value = 250 * (Math.cosh(x*z) + Math.sinh(y*z)) + yield value % 120 + 100; + } + } + + beat(0.25) :: sound("triangle") + .freq(cache("rossler attractor", rossler(3,4,1))) + .adsr(0,.1,.1,.1) + .log("freq").out() + `, + true, +)}; + ## OEIS integer sequences -To find some inspiration - or to enter into the void - one can visit The On-Line Encyclopedia of Integer Sequences (OEIS) to find some interesting integer sequences. +To find some inspiration - or to enter into the void - one can visit The On-Line Encyclopedia of Integer Sequences (OEIS) to find some interesting integer sequences. Many of the sequences are implemented by JISG (Javascript Integer Sequence Generators) project. Those sequences can be referenced directly with the identifiers using the cache function. @@ -106,7 +159,7 @@ function* poly(x) { x++; } } - + z0(poly(1)).noteLength(0.5).semitones(2,2,3,2,2,2).sound("sine").out() z1(poly(8)).noteLength(0.25).semitones(2,1,2,1,2,2).sound("sine").out() z2(poly(-3)).noteLength(1.0).semitones(2,2,2,1,3,2).sound("sine").out()