docs(generators): add an example of a continuous attractor and a discrete attractor

This commit is contained in:
Edgar Delgado Vega
2023-12-17 17:29:19 -05:00
parent ad6f8a5e91
commit f9bce56f9e

View File

@ -8,7 +8,7 @@ export const generators = (application: Editor): string => {
JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator" target="_blank">generators</a> are powerful functions for generating value sequences. They can be used to generate melodies, rhythms or control parameters. JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator" target="_blank">generators</a> 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 <ic>cache(key, function)</ic> 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 <ic>cache(key, function)</ic> 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. 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); const s = Math.tan(x/10)+Math.sin(x/20);
yield 2 * Math.pow(s, 3) - 6 * Math.pow(s, 2) + 5 * s + 200; yield 2 * Math.pow(s, 3) - 6 * Math.pow(s, 2) + 5 * s + 200;
x++; x++;
} }
} }
beat(.125) && sound("triangle").freq(cache("mathyshit",poly())).out() beat(.125) && sound("triangle").freq(cache("mathyshit",poly())).out()
`, `,
true, true,
)}; )};
When you want to dance with a dynamic system in controlled musical chaos, Topos is waiting for you:
${makeExample( ${makeExample(
"Truly scale free chaos inspired by Lorentz attractor", "Truly scale free chaos inspired by Lorentz attractor",
` `
@ -54,16 +56,16 @@ ${makeExample(
const dx = 10 * (y - x); const dx = 10 * (y - x);
const dy = x * (rho - z) - y; const dy = x * (rho - z) - y;
const dz = x * y - beta * z; const dz = x * y - beta * z;
x += dx * 0.01; x += dx * 0.01;
y += dy * 0.01; y += dy * 0.01;
z += dz * 0.01; z += dz * 0.01;
const value = 300 + 30 * (Math.sin(x) + Math.tan(y) + Math.cos(z)) const value = 300 + 30 * (Math.sin(x) + Math.tan(y) + Math.cos(z))
yield value; yield value;
} }
} }
beat(0.25) :: sound("triangle") beat(0.25) :: sound("triangle")
.freq(cache("stranger",strange(3,5,2))) .freq(cache("stranger",strange(3,5,2)))
.adsr(.15,.1,.1,.1) .adsr(.15,.1,.1,.1)
@ -72,9 +74,60 @@ ${makeExample(
true, 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 ## OEIS integer sequences
To find some inspiration - or to enter into the void - one can visit <a href="https://oeis.org/" target="_blank">The On-Line Encyclopedia of Integer Sequences (OEIS)</a> to find some interesting integer sequences. To find some inspiration - or to enter into the void - one can visit <a href="https://oeis.org/" target="_blank">The On-Line Encyclopedia of Integer Sequences (OEIS)</a> to find some interesting integer sequences.
Many of the sequences are implemented by <a href="https://github.com/acerix/jisg/tree/main/src/oeis" target="_blank">JISG</a> (Javascript Integer Sequence Generators) project. Those sequences can be referenced directly with the identifiers using the cache function. Many of the sequences are implemented by <a href="https://github.com/acerix/jisg/tree/main/src/oeis" target="_blank">JISG</a> (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++; x++;
} }
} }
z0(poly(1)).noteLength(0.5).semitones(2,2,3,2,2,2).sound("sine").out() 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() 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() z2(poly(-3)).noteLength(1.0).semitones(2,2,2,1,3,2).sound("sine").out()