Updating the entire documentation
This commit is contained in:
@ -6,7 +6,7 @@ declare global {
|
||||
add(amount: number): number[];
|
||||
sub(amount: number): number[];
|
||||
mult(amount: number): number[];
|
||||
division(amount: number): number[];
|
||||
div(amount: number): number[];
|
||||
palindrome(): T[];
|
||||
random(index: number): T;
|
||||
rand(index: number): T;
|
||||
@ -74,7 +74,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => x * amount);
|
||||
};
|
||||
|
||||
Array.prototype.division = function (amount: number): number[] {
|
||||
Array.prototype.div = function (amount: number): number[] {
|
||||
/**
|
||||
* @param amount - The value to divide each element in the array by.
|
||||
* @returns New array with divided values. Throws if division by zero.
|
||||
|
||||
@ -34,8 +34,8 @@ Stopping **Hydra** is simple:
|
||||
${makeExample(
|
||||
"Stopping Hydra",
|
||||
`
|
||||
mod(4) :: stop_hydra() // this one
|
||||
mod(4) :: app.hydra.hush() // or this one
|
||||
beat(4) :: stop_hydra() // this one
|
||||
beat(4) :: app.hydra.hush() // or this one
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -16,7 +16,7 @@ All functions from the sound object can be used to modify the event, for example
|
||||
${makeExample(
|
||||
"Modifying sound events with probabilities",
|
||||
`
|
||||
mod(.5) && sound('numbers')
|
||||
beat(.5) && sound('numbers')
|
||||
.odds(1/4, s => s.speed(irand(1,4)))
|
||||
.rarely(s => s.crush(3))
|
||||
.out()
|
||||
@ -27,7 +27,7 @@ ${makeExample(
|
||||
"Chance to change to a different note",
|
||||
`
|
||||
rhythm(.5, 3, 8) && sound('pluck').note(38).out()
|
||||
mod(.5) && sound('pluck').note(60)
|
||||
beat(.5) && sound('pluck').note(60)
|
||||
.often(s => s.note(57))
|
||||
.sometimes(s => s.note(64).n(irand(1,4)))
|
||||
.note(62)
|
||||
@ -41,7 +41,7 @@ All the functions from the MIDI object can be used to modify the event with prob
|
||||
|
||||
${makeExample(
|
||||
"Modifying midi events with probabilities",
|
||||
`mod(.5) && midi(60).channel(1)
|
||||
`beat(.5) && midi(60).channel(1)
|
||||
.odds(1/4, n => n.channel(2))
|
||||
.often(n => n.note+=4)
|
||||
.sometimes(s => s.velocity(irand(50,100)))
|
||||
@ -63,7 +63,7 @@ ${makeExample(
|
||||
"Ziffer player using a sound chain and probabilities!",
|
||||
`
|
||||
z1('s 0 5 7 0 3 7 0 2 7 0 1 7 0 1 6 5 4 3 2')
|
||||
.octave([0, 1].div(2) - 1)
|
||||
.octave([0, 1].beat(2) - 1)
|
||||
.scale('pentatonic').sound('pluck')
|
||||
.odds(1/4, n => n.delay(0.5).delayt(0.25))
|
||||
.odds(1/2, n => n.speed(0.5))
|
||||
|
||||
@ -34,12 +34,12 @@ ${makeExample(
|
||||
"Shortening your if conditions",
|
||||
`
|
||||
// The && symbol (overriden by :: in Topos) is very often used for conditions!
|
||||
mod(.75) :: snd('linnhats').n([1,4,5].beat()).out()
|
||||
mod(1) :: snd('bd').out()
|
||||
beat(.75) :: snd('linnhats').n([1,4,5].beat()).out()
|
||||
beat(1) :: snd('bd').out()
|
||||
//if (true) && log('very true')
|
||||
// These two lines are the same:
|
||||
// mod(1) && snd('bd').out()
|
||||
//// mod(1) :: snd('bd').out()
|
||||
// beat(1) && snd('bd').out()
|
||||
//// beat(1) :: snd('bd').out()
|
||||
|
||||
`,
|
||||
true
|
||||
@ -49,7 +49,7 @@ ${makeExample(
|
||||
"More complex conditions using ?",
|
||||
`
|
||||
// The ? symbol can be used to write a if/true/false condition
|
||||
mod(4) ? snd('kick').out() : mod(2)::snd('snare').out()
|
||||
beat(4) ? snd('kick').out() : beat(2) :: snd('snare').out()
|
||||
// (true) ? log('very true') : log('very false')
|
||||
`,
|
||||
false
|
||||
@ -60,14 +60,12 @@ ${makeExample(
|
||||
"Using not and other short symbols",
|
||||
`
|
||||
// The ! symbol can be used to reverse a condition
|
||||
mod(4) ? snd('kick').out() : mod(2)::snd('snare').out()
|
||||
!mod(2) :: mod(0.5)::snd('clap').out()
|
||||
beat(4) ? snd('kick').out() : beat(2) :: snd('snare').out()
|
||||
!beat(2) :: beat(0.5) :: snd('clap').out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
|
||||
|
||||
|
||||
## About crashes and bugs
|
||||
|
||||
Things will crash, that's also part of the show. You will learn progressively to avoid mistakes and to write safer code. Do not hesitate to kill the page or to stop the transport if you feel overwhelmed by an algorithm blowing up. There are no safeties in place to save you. This is to ensure that you have all the available possible room to write bespoke code and experiment with your ideas through code.
|
||||
|
||||
@ -15,8 +15,8 @@ The basic function to play a sound is... <ic>sound(name: string)</ic> (you can a
|
||||
${makeExample(
|
||||
"Playing sounds is easy",
|
||||
`
|
||||
mod(1) && sound('bd').out()
|
||||
mod(0.5) && sound('hh').out()
|
||||
beat(1) && sound('bd').out()
|
||||
beat(0.5) && sound('hh').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -31,8 +31,8 @@ Let's make it slightly more complex:
|
||||
${makeExample(
|
||||
"Adding some effects",
|
||||
`
|
||||
mod(1) && sound('bd').coarse(0.25).room(0.5).orbit(2).out();
|
||||
mod(0.5) && sound('hh').delay(0.25).delaytime(0.125).out();
|
||||
beat(1) && sound('bd').coarse(0.25).room(0.5).orbit(2).out();
|
||||
beat(0.5) && sound('hh').delay(0.25).delaytime(0.125).out();
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -51,7 +51,7 @@ Let's pause for a moment to explain what we just wrote. There are many things to
|
||||
${makeExample(
|
||||
'"Composing" a sound or making a sound chain',
|
||||
`
|
||||
mod(1) :: sound('pad')
|
||||
beat(1) :: sound('pad')
|
||||
.begin(rand(0, 0.4))
|
||||
.freq([50,52].beat())
|
||||
.size(0.9)
|
||||
@ -85,7 +85,7 @@ The <ic>.n(number)</ic> method can be used to pick a sample from the currently s
|
||||
${makeExample(
|
||||
"Picking a sample",
|
||||
`
|
||||
mod(1) && sound('kick').n([1,2,3,4,5,6,7,8].pick()).out()
|
||||
beat(1) && sound('kick').n([1,2,3,4,5,6,7,8].pick()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -96,7 +96,7 @@ ${makeExample(
|
||||
"Picking a sample... with your mouse!",
|
||||
`
|
||||
// Move your mouse to change the sample being used!
|
||||
mod(.25) && sound('numbers').n(Math.floor(mouseX())).out()`,
|
||||
beat(.25) && sound('numbers').n(Math.floor(mouseX())).out()`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -108,7 +108,7 @@ As we said earlier, the <ic>sound('sample_name')</ic> function can be chained to
|
||||
${makeExample(
|
||||
"Learning through repetition",
|
||||
`
|
||||
mod(0.5) && sound('hh')
|
||||
beat(0.5) && sound('hh')
|
||||
.sometimes(s=>s.speed([1,5,10].pick()))
|
||||
.room(0.5)
|
||||
.cutoff(usine(2) * 5000)
|
||||
@ -129,7 +129,7 @@ There is a special method to choose the _orbit_ that your sound is going to use:
|
||||
|
||||
| Method | Alias | Description |
|
||||
|----------|-------|------------------------------------------------------------|
|
||||
| orbit | | Orbit number |
|
||||
| orbit | | Orbit number |
|
||||
|
||||
|
||||
## Amplitude
|
||||
@ -145,7 +145,7 @@ Simple controls over the amplitude (volume) of a given sound.
|
||||
${makeExample(
|
||||
"Velocity manipulated by a counter",
|
||||
`
|
||||
mod(.5)::snd('cp').vel($(1)%10 / 10).out()`,
|
||||
beat(.5)::snd('cp').vel($(1)%10 / 10).out()`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -165,10 +165,10 @@ Note that the **sustain** value is not a duration but an amplitude value (how lo
|
||||
${makeExample(
|
||||
"Simple synthesizer",
|
||||
`
|
||||
mod(4)::sound('sawtooth').note(50).decay(0.5).sustain(0.5).release(2).gain(0.25).out();
|
||||
mod(2)::sound('sawtooth').note(50+7).decay(0.5).sustain(0.6).release(2).gain(0.25).out();
|
||||
mod(1)::sound('sawtooth').note(50+12).decay(0.5).sustain(0.7).release(2).gain(0.25).out();
|
||||
mod(.25)::sound('sawtooth').note([50,57,62].pick() + [12, 24, 0].div(2))
|
||||
beat(4)::sound('sawtooth').note(50).decay(0.5).sustain(0.5).release(2).gain(0.25).out();
|
||||
beat(2)::sound('sawtooth').note(50+7).decay(0.5).sustain(0.6).release(2).gain(0.25).out();
|
||||
beat(1)::sound('sawtooth').note(50+12).decay(0.5).sustain(0.7).release(2).gain(0.25).out();
|
||||
beat(.25)::sound('sawtooth').note([50,57,62].pick() + [12, 24, 0].beat(2))
|
||||
.cutoff(5000).sustain(0.5).release(0.1).gain(0.25).out()
|
||||
`,
|
||||
true
|
||||
@ -192,9 +192,9 @@ ${makeExample(
|
||||
"Complex sampling duties",
|
||||
`
|
||||
// Using some of the modifiers described above :)
|
||||
mod(.5)::snd('pad').begin(0.2)
|
||||
.speed([1, 0.9, 0.8].div(4))
|
||||
.n([0, 0, 2, 4].div(4)).pan(usine(.5))
|
||||
beat(.5)::snd('pad').begin(0.2)
|
||||
.speed([1, 0.9, 0.8].beat(4))
|
||||
.n([0, 0, 2, 4].beat(4)).pan(usine(.5))
|
||||
.end(rand(0.3,0.8))
|
||||
.room(0.8).size(0.5)
|
||||
.clip(1).out()
|
||||
@ -220,7 +220,7 @@ There are three basic filters: a _lowpass_, _highpass_ and _bandpass_ filters wi
|
||||
${makeExample(
|
||||
"Filter sweep using a low frequency oscillator",
|
||||
`
|
||||
mod(.5) && snd('sawtooth')
|
||||
beat(.5) && snd('sawtooth')
|
||||
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
||||
.resonance(0.9).freq([100,150].pick())
|
||||
.out()
|
||||
@ -240,7 +240,7 @@ A basic reverberator that you can use to give some depth to your sounds. This si
|
||||
${makeExample(
|
||||
"Clapping in the cavern",
|
||||
`
|
||||
mod(2)::snd('cp').room(1).size(0.9).out()
|
||||
beat(2)::snd('cp').room(1).size(0.9).out()
|
||||
`,
|
||||
true
|
||||
)};
|
||||
@ -259,9 +259,9 @@ A good sounding delay unit that can go into feedback territory. Use it without m
|
||||
${makeExample(
|
||||
"Who doesn't like delay?",
|
||||
`
|
||||
mod(2)::snd('cp').delay(0.5).delaytime(0.75).delayfb(0.8).out()
|
||||
mod(4)::snd('snare').out()
|
||||
mod(1)::snd('kick').out()
|
||||
beat(2)::snd('cp').delay(0.5).delaytime(0.75).delayfb(0.8).out()
|
||||
beat(4)::snd('snare').out()
|
||||
beat(1)::snd('kick').out()
|
||||
`,
|
||||
true
|
||||
)};
|
||||
@ -278,8 +278,8 @@ mod(1)::snd('kick').out()
|
||||
${makeExample(
|
||||
"Crunch... crunch... crunch!",
|
||||
`
|
||||
mod(.5)::snd('pad').coarse($(1) % 16).clip(.5).out(); // Comment me
|
||||
mod(.5)::snd('pad').crush([16, 8, 4].div(2)).clip(.5).out()
|
||||
beat(.5)::snd('pad').coarse($(1) % 16).clip(.5).out(); // Comment me
|
||||
beat(.5)::snd('pad').crush([16, 8, 4].beat(2)).clip(.5).out()
|
||||
`,
|
||||
true
|
||||
)};
|
||||
|
||||
@ -86,7 +86,7 @@ You can control scripts programatically. This is the core concept of Topos after
|
||||
${makeExample(
|
||||
"Calling a script! The most important feature!",
|
||||
`
|
||||
mod(1) :: script(1)
|
||||
beat(1) :: script(1)
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -94,7 +94,7 @@ mod(1) :: script(1)
|
||||
${makeExample(
|
||||
"Calling mutliple scripts at the same time.",
|
||||
`
|
||||
mod(1) :: script(1, 3, 5)
|
||||
beat(1) :: script(1, 3, 5)
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -111,7 +111,7 @@ You can get the current position of the mouse on the screen by using the followi
|
||||
${makeExample(
|
||||
"FM Synthesizer controlled using the mouse",
|
||||
`
|
||||
mod(.25) :: sound('sine')
|
||||
beat(.25) :: sound('sine')
|
||||
.fmi(mouseX() / 100)
|
||||
.fmh(mouseY() / 100)
|
||||
.vel(0.2)
|
||||
@ -129,7 +129,7 @@ Current mouse position can also be used to generate notes:
|
||||
${makeExample(
|
||||
"The same synthesizer, with note control!",
|
||||
`
|
||||
mod(.25) :: sound('sine')
|
||||
beat(.25) :: sound('sine')
|
||||
.fmi(mouseX() / 100)
|
||||
.note(noteX())
|
||||
.fmh(mouseY() / 100)
|
||||
@ -148,7 +148,7 @@ Low Frequency Oscillators (_LFOs_) are an important piece in any digital audio w
|
||||
|
||||
${makeExample(
|
||||
"Modulating the speed of a sample player using a sine LFO",
|
||||
`mod(.25) && snd('cp').speed(1 + usine(0.25) * 2).out()`,
|
||||
`beat(.25) && snd('cp').speed(1 + usine(0.25) * 2).out()`,
|
||||
true
|
||||
)};
|
||||
|
||||
@ -158,7 +158,7 @@ ${makeExample(
|
||||
|
||||
${makeExample(
|
||||
"Modulating the speed of a sample player using a triangle LFO",
|
||||
`mod(.25) && snd('cp').speed(1 + utriangle(0.25) * 2).out()`,
|
||||
`beat(.25) && snd('cp').speed(1 + utriangle(0.25) * 2).out()`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -168,7 +168,7 @@ ${makeExample(
|
||||
|
||||
${makeExample(
|
||||
"Modulating the speed of a sample player using a saw LFO",
|
||||
`mod(.25) && snd('cp').speed(1 + usaw(0.25) * 2).out()`,
|
||||
`beat(.25) && snd('cp').speed(1 + usaw(0.25) * 2).out()`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -177,7 +177,7 @@ ${makeExample(
|
||||
|
||||
${makeExample(
|
||||
"Modulating the speed of a sample player using a square LFO",
|
||||
`mod(.25) && snd('cp').speed(1 + usquare(0.25, 0, 0.25) * 2).out()`,
|
||||
`beat(.25) && snd('cp').speed(1 + usquare(0.25, 0, 0.25) * 2).out()`,
|
||||
true
|
||||
)};
|
||||
|
||||
@ -185,7 +185,7 @@ ${makeExample(
|
||||
|
||||
${makeExample(
|
||||
"Modulating the speed of a sample player using noise",
|
||||
`mod(.25) && snd('cp').speed(1 + noise() * 2).out()`,
|
||||
`beat(.25) && snd('cp').speed(1 + noise() * 2).out()`,
|
||||
true
|
||||
)};
|
||||
|
||||
@ -254,8 +254,8 @@ ${makeExample(
|
||||
${makeExample(
|
||||
"Using chance with other operators",
|
||||
`
|
||||
frequently() :: mod(1) :: sound('kick').out();
|
||||
often() :: mod(0.5) :: sound('hh').out();
|
||||
frequently() :: beat(1) :: sound('kick').out();
|
||||
often() :: beat(0.5) :: sound('hh').out();
|
||||
sometimes() :: onbeat(1,3) :: sound('snare').out();
|
||||
`,
|
||||
true
|
||||
@ -264,12 +264,12 @@ ${makeExample(
|
||||
${makeExample(
|
||||
"Using chance with chaining",
|
||||
`
|
||||
mod(0.5) && sound("bd")
|
||||
beat(0.5) && sound("bd")
|
||||
.freq(100)
|
||||
.sometimes(s=>s.crush(2.5))
|
||||
.out()
|
||||
|
||||
mod(0.5) && sound('arp').freq(100)
|
||||
beat(0.5) && sound('arp').freq(100)
|
||||
.sometimes(n=>n.freq(200).delay(0.5))
|
||||
.rarely(n=>n.freq(300).delay(2.5))
|
||||
.almostNever(n=>n.freq(400))
|
||||
@ -293,8 +293,8 @@ ${makeExample(
|
||||
"Phased woodblocks",
|
||||
`
|
||||
// Some very low-budget version of phase music
|
||||
mod(.5) :: delay(usine(.125) * 80, () => sound('east').out())
|
||||
mod(.5) :: delay(50, () => sound('east').out())
|
||||
beat(.5) :: delay(usine(.125) * 80, () => sound('east').out())
|
||||
beat(.5) :: delay(50, () => sound('east').out())
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -304,8 +304,8 @@ mod(.5) :: delay(50, () => sound('east').out())
|
||||
${makeExample(
|
||||
"Another woodblock texture",
|
||||
`
|
||||
mod(1) :: delayr(50, 4, () => sound('east').speed([0.5,.25].beat()).out())
|
||||
div(2) :: mod(2) :: delayr(150, 4, () => sound('east').speed([0.5,.25].beat() * 4).out())
|
||||
beat(1) :: delayr(50, 4, () => sound('east').speed([0.5,.25].beat()).out())
|
||||
flip(2) :: beat(2) :: delayr(150, 4, () => sound('east').speed([0.5,.25].beat() * 4).out())
|
||||
`,
|
||||
true
|
||||
)};
|
||||
|
||||
@ -23,7 +23,7 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "delayr",
|
||||
category: "time",
|
||||
description: "Delay a function <i>n</i> times by <i>t</i> ms",
|
||||
example: "delayr(50, 3, () => mod(1) :: log('delayed'))",
|
||||
example: "delayr(50, 3, () => beat(1) :: log('delayed'))",
|
||||
},
|
||||
toss: {
|
||||
name: "toss",
|
||||
@ -115,12 +115,12 @@ const completionDatabase: CompletionDatabase = {
|
||||
description: "Log a value in the console",
|
||||
example: "log('Hello, world')",
|
||||
},
|
||||
div: {
|
||||
name: "div",
|
||||
flip: {
|
||||
name: "flip",
|
||||
category: "patterns",
|
||||
description:
|
||||
"Returns next value every <i>n</i> beats or true and false alternatively",
|
||||
example: "div(4, 50) // 2 beats of true, 2 beats of false, 50/50.",
|
||||
"Returns true and false alternatively or next value every <i>n</i> beats (arrays)",
|
||||
example: "flip(4, 50) // 2 beats of true, 2 beats of false, 50/50.",
|
||||
},
|
||||
n: {
|
||||
name: "n",
|
||||
@ -192,7 +192,7 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "coarse",
|
||||
category: "synthesis",
|
||||
description: "Artificial sample-rate lowering",
|
||||
example: "mod(.5)::snd('pad').coarse($(1) % 16).clip(.5).out();",
|
||||
example: "beat(.5)::snd('pad').coarse($(1) % 16).clip(.5).out();",
|
||||
},
|
||||
crush: {
|
||||
name: "crush",
|
||||
@ -335,17 +335,17 @@ const completionDatabase: CompletionDatabase = {
|
||||
example:
|
||||
"oncount([1,2,3], 4) // true on beats 1, 2 and 3 in a 4 beats period",
|
||||
},
|
||||
mod: {
|
||||
name: "mod",
|
||||
beat: {
|
||||
name: "beat",
|
||||
category: "rhythm",
|
||||
description: "return true every <i>n</i> pulsations.",
|
||||
example: "mod(1) :: log(rand(1,5))",
|
||||
description: "return true every <i>n</i> beats.",
|
||||
example: "beat(1) :: log(rand(1,5))",
|
||||
},
|
||||
modp: {
|
||||
name: "modp",
|
||||
pulse: {
|
||||
name: "pulse",
|
||||
category: "rhythm",
|
||||
description: "return true every <i>n</i> ticks.",
|
||||
example: "modp(8) :: log(rand(1,5))",
|
||||
description: "return true every <i>n</i> pulses.",
|
||||
example: "pulse(8) :: log(rand(1,5))",
|
||||
},
|
||||
euclid: {
|
||||
name: "euclid",
|
||||
@ -399,61 +399,61 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "odds",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of <i>n</i> %",
|
||||
example: "odds(1/2) // 50% probability"
|
||||
example: "odds(1/2) // 50% probability",
|
||||
},
|
||||
never: {
|
||||
name: "never",
|
||||
category: "randomness",
|
||||
description: "Return false",
|
||||
example: "never() // false"
|
||||
example: "never() // false",
|
||||
},
|
||||
almostNever: {
|
||||
name: "almostNever",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 2.5%",
|
||||
example: "almostNever() // 2.5% chance"
|
||||
example: "almostNever() // 2.5% chance",
|
||||
},
|
||||
rarely: {
|
||||
name: "rarely",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 10%",
|
||||
example: "rarely() // 10% chance"
|
||||
example: "rarely() // 10% chance",
|
||||
},
|
||||
scarcely: {
|
||||
name: "scarcely",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 25%",
|
||||
example: "scarcely() // 25% chance"
|
||||
example: "scarcely() // 25% chance",
|
||||
},
|
||||
sometimes: {
|
||||
name: "sometimes",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 50%",
|
||||
example: "sometimes() // 50% chance"
|
||||
example: "sometimes() // 50% chance",
|
||||
},
|
||||
often: {
|
||||
name: "often",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 75%",
|
||||
example: "often() // 75% chance"
|
||||
example: "often() // 75% chance",
|
||||
},
|
||||
frequently: {
|
||||
name: "frequently",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 90%",
|
||||
example: "frequently() // chance"
|
||||
example: "frequently() // chance",
|
||||
},
|
||||
almostAlways: {
|
||||
name: "almostAlways",
|
||||
category: "randomness",
|
||||
description: "Return true with a probability of 98.5%",
|
||||
example: "almostAlways() // 98.5% chance"
|
||||
example: "almostAlways() // 98.5% chance",
|
||||
},
|
||||
always: {
|
||||
name: "always",
|
||||
category: "randomness",
|
||||
description: "Return true",
|
||||
example: "always() // true"
|
||||
example: "always() // true",
|
||||
},
|
||||
sound: {
|
||||
name: "sound",
|
||||
@ -484,7 +484,7 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "script",
|
||||
category: "core",
|
||||
description: "Execute one or more local scripts",
|
||||
example: "mod(1) :: script(1)",
|
||||
example: "beat(1) :: script(1)",
|
||||
},
|
||||
clear_script: {
|
||||
name: "clear_script",
|
||||
@ -514,14 +514,14 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "divbar",
|
||||
category: "time",
|
||||
description:
|
||||
"works just like <i>div</i> but at the level of bars instead of beats",
|
||||
example: "divbar(2)::mod(1)::snd('kick').out()",
|
||||
"works just like <i>flip</i> but at the level of bars instead of beats",
|
||||
example: "divbar(2)::beat(1)::snd('kick').out()",
|
||||
},
|
||||
onbar: {
|
||||
name: "onbar",
|
||||
category: "time",
|
||||
description: "return true when targetted bar(s) is/are reached in period",
|
||||
example: "onbar(4, 4)::mod(.5)::snd('hh').out();",
|
||||
example: "onbar(4, 4)::beat(.5)::snd('hh').out();",
|
||||
},
|
||||
begin: {
|
||||
name: "begin",
|
||||
@ -629,7 +629,7 @@ const completionDatabase: CompletionDatabase = {
|
||||
name: "speak",
|
||||
category: "synthesis",
|
||||
description: "Text to speech synthesizer",
|
||||
example: "mod(2) :: speak('Topos!','fr',irand(0,5))",
|
||||
example: "beat(2) :: speak('Topos!','fr',irand(0,5))",
|
||||
},
|
||||
midi_outputs: {
|
||||
name: "midi_outputs",
|
||||
@ -775,11 +775,11 @@ const completionDatabase: CompletionDatabase = {
|
||||
description: "Multiply each element of the given array by a value",
|
||||
example: "[0,1,2,3].mul(2)",
|
||||
},
|
||||
division: {
|
||||
div: {
|
||||
name: "div",
|
||||
category: "patterns",
|
||||
description: "Divide each element of the given array by a value",
|
||||
example: "[0,1,2,3].division(2)",
|
||||
example: "[0,1,2,3].div(2)",
|
||||
},
|
||||
scale: {
|
||||
name: "scale",
|
||||
|
||||
@ -35,8 +35,8 @@ Every Topos session is composed of several small scripts. A set of scripts is ca
|
||||
${makeExample(
|
||||
"To take the most out of Topos...",
|
||||
`// Write your code in multiple scripts. Use all the code buffers!
|
||||
mod(1) :: script(1)
|
||||
div(4) :: mod(.5) :: script(2)
|
||||
beat(1) :: script(1)
|
||||
flip(4) :: beat(.5) :: script(2)
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -44,8 +44,8 @@ div(4) :: mod(.5) :: script(2)
|
||||
${makeExample(
|
||||
"Script execution can become musical too!",
|
||||
`// You can play your scripts... algorithmically.
|
||||
mod(1) :: script([1,3,5].pick())
|
||||
div(4) :: mod([.5, .25].div(16)) :: script([5,6,7,8].loop($(2)))
|
||||
beat(1) :: script([1,3,5].pick())
|
||||
flip(4) :: beat([.5, .25].beat(16)) :: script([5,6,7,8].loop($(2)))
|
||||
`,
|
||||
false
|
||||
)}
|
||||
|
||||
@ -16,17 +16,16 @@ ${makeExample(
|
||||
|
||||
|
||||
bpm(110)
|
||||
mod(0.125) && sound('sawtooth')
|
||||
.note([60, 62, 63, 67, 70].div(.125) +
|
||||
beat(0.125) && sound('sawtooth')
|
||||
.note([60, 62, 63, 67, 70].beat(.125) +
|
||||
[-12,0,12].beat() + [0, 0, 5, 7].bar())
|
||||
.sustain(0.1).fmi(0.25).fmh(2).room(0.9)
|
||||
.gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar())
|
||||
.delay(0.5).delayt(0.25).delayfb(0.25)
|
||||
.out();
|
||||
mod(1) && snd('kick').out();
|
||||
mod(2) && snd('snare').out();
|
||||
mod(.5) && snd('hat').out();
|
||||
|
||||
beat(1) && snd('kick').out();
|
||||
beat(2) && snd('snare').out();
|
||||
beat(.5) && snd('hat').out();
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -39,16 +38,16 @@ Topos is an _algorithmic_ sequencer. Topos uses small algorithms to represent mu
|
||||
${makeExample(
|
||||
"Small algorithms for direct musical expression",
|
||||
`
|
||||
mod(1) :: sound(['kick', 'hat', 'snare', 'hat'].div(1)).out()
|
||||
mod(.5) :: sound('jvbass').note(35 + [0,12].beat()).out()
|
||||
mod([0.5, 0.25, 1, 2].div(1)) :: sound('east')
|
||||
beat(1) :: sound(['kick', 'hat', 'snare', 'hat'].beat(1)).out()
|
||||
beat(.5) :: sound('jvbass').note(35 + [0,12].beat()).out()
|
||||
beat([0.5, 0.25, 1, 2].beat(1)) :: sound('east')
|
||||
.room(.5).size(0.5).n(irand(1,5)).out()`,
|
||||
false
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Computer music should be immediate and intuitive",
|
||||
`mod(.5)::snd('sine')
|
||||
`beat(.5)::snd('sine')
|
||||
.delay(0.5).delayt(0.25).delayfb(0.7)
|
||||
.room(0.8).size(0.8)
|
||||
.freq(mouseX()).out()`,
|
||||
@ -58,9 +57,9 @@ ${makeExample(
|
||||
${makeExample(
|
||||
"Making the web less dreadful, one beep at at time",
|
||||
`
|
||||
mod(.5) :: sound('sid').n($(2)).out()
|
||||
mod(.25) :: sound('sid').note(
|
||||
[34, 36, 41].div(.25) + [[0,-24].pick(),12].beat())
|
||||
beat(.5) :: sound('sid').n($(2)).out()
|
||||
beat(.25) :: sound('sid').note(
|
||||
[34, 36, 41].beat(.25) + [[0,-24].pick(),12].beat())
|
||||
.room(0.9).size(0.9).n(4).out()`,
|
||||
false
|
||||
)}
|
||||
|
||||
@ -81,10 +81,10 @@ ${makeExample(
|
||||
"Playing some piano",
|
||||
`
|
||||
bpm(80) // Setting a default BPM
|
||||
mod(.5) && midi(36 + seqbeat(0,12)).sustain(0.02).out()
|
||||
mod(.25) && midi([64, 76].pick()).sustain(0.05).out()
|
||||
mod(.75) && midi(seqbeat(64, 67, 69)).sustain(0.05).out()
|
||||
sometimes() && mod(.25) && midi(seqbeat(64, 67, 69) + 24).sustain(0.05).out()
|
||||
beat(.5) && midi(36 + [0,12].beat()).sustain(0.02).out()
|
||||
beat(.25) && midi([64, 76].pick()).sustain(0.05).out()
|
||||
beat(.75) && midi([64, 67, 69].beat()).sustain(0.05).out()
|
||||
beat(.25) && midi([64, 67, 69].beat() + 24).sustain(0.05).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -133,7 +133,7 @@ sysex(0x90, 0x40, 0x7f)
|
||||
${makeExample(
|
||||
"Tic, tac, tic, tac...",
|
||||
`
|
||||
mod(.25) && midi_clock() // Sending clock to MIDI device from the global buffer
|
||||
beat(.25) && midi_clock() // Sending clock to MIDI device from the global buffer
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -12,30 +12,30 @@ Music really comes to life when you start playing with algorithmic patterns. The
|
||||
|
||||
JavaScript is using [Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) as a data structure for lists. Topos is extending them with custom methods that allow you to enter softly into a universe of musical patterns. These methods can often be chained to compose a more complex expression: <ic>[1, 2, 3].repeatOdd(5).palindrome().beat()</ic>.
|
||||
|
||||
- <ic>div(division: number)</ic>: this method will return the next value in the list every _n_ pulses. By default, <ic>1</ic> equals to one beat but integer and floating point number values are supported as well. This method is extremely powerful and can be used for many different purposes. Check out the examples.
|
||||
- <ic>beat(division: number)</ic>: this method will return the next value in the list every _n_ pulses. By default, <ic>1</ic> equals to one beat but integer and floating point number values are supported as well. This method is extremely powerful and can be used for many different purposes. Check out the examples.
|
||||
|
||||
${makeExample(
|
||||
"Light drumming",
|
||||
`
|
||||
// Every bar, use a different rhythm
|
||||
mod([1, 0.75].div(4)) :: sound('cp').out()
|
||||
mod([0.5, 1].div(4)) :: sound('kick').out()
|
||||
mod(2)::snd('snare').shape(.5).out()
|
||||
beat([1, 0.75].beat(4)) :: sound('cp').out()
|
||||
beat([0.5, 1].beat(4)) :: sound('kick').out()
|
||||
beat(2)::snd('snare').shape(.5).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
${makeExample(
|
||||
"Using div to create arpeggios",
|
||||
"Using beat to create arpeggios",
|
||||
`
|
||||
// Arpeggio using pulse divisions
|
||||
mod([.5, .25].div(2)) :: sound('sine')
|
||||
beat([.5, .25].div(2)) :: sound('sine')
|
||||
.hcutoff(400)
|
||||
.fmi([1,2].div(8))
|
||||
.fmh([0.5,0.25,1].div(2))
|
||||
.note([50,53,57].div(.25) + [12,24].div(2))
|
||||
.sustain([0.25, 0.5].div(8))
|
||||
.fmi([1,2].beat(8))
|
||||
.fmh([0.5,0.25,1].beat(2))
|
||||
.note([50,53,57].beat(.25) + [12,24].beat(2))
|
||||
.sustain([0.25, 0.5].beat(8))
|
||||
.room(0.9).size(0.5)
|
||||
.delay(0.25).delayt([0.5,0.25].div(16))
|
||||
.delay(0.25).delayt([0.5,0.25].beat(16))
|
||||
.delayfb(0.5)
|
||||
.out()
|
||||
`,
|
||||
@ -44,48 +44,44 @@ mod([.5, .25].div(2)) :: sound('sine')
|
||||
${makeExample(
|
||||
"Cool ambiance",
|
||||
`
|
||||
mod(.5) :: snd(['kick', 'hat'].div(4)).out()
|
||||
mod([2,4].div(2)) :: snd('shaker').delay(.5).delayfb(.75).delayt(0.125).out()
|
||||
div(2)::mod(1)::snd('clap').out()
|
||||
div(4)::mod(2)::snd('pad').n(2).shape(.5).orbit(2).room(0.9).size(0.9).release(0.5).out()
|
||||
beat(.5) :: snd(['kick', 'hat'].beat(4)).out()
|
||||
beat([2,4].beat(2)) :: snd('shaker').delay(.5).delayfb(.75).delayt(0.125).out()
|
||||
flip(2)::beat(1)::snd('clap').out()
|
||||
flip(4)::beat(2)::snd('pad').n(2).shape(.5).orbit(2).room(0.9).size(0.9).release(0.5).out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
|
||||
|
||||
|
||||
- <ic>beat()</ic>: returns the index of the list corresponding to current beat (with wrapping). This allows you to return a different value for each beat.
|
||||
- <ic>pulse()</ic>: returns the index of the list corresponding to the current pulse (with wrapping). This method will return a different value for each pulse.
|
||||
- <ic>bar()</ic>: returns the index of the list corresponding to the current bar (with wrapping). This method will return a different value for each bar.
|
||||
|
||||
${makeExample(
|
||||
"A simple drumbeat in no time!",
|
||||
`
|
||||
mod(1)::sound(['kick', 'hat', 'snare', 'hat'].beat()).out()
|
||||
mod(1.5)::sound(['jvbass', 'clap'].beat()).out()
|
||||
beat(1)::sound(['kick', 'hat', 'snare', 'hat'].beat()).out()
|
||||
beat(1.5)::sound(['jvbass', 'clap'].beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Using beat, pulse and bar in the same code",
|
||||
`mod(2)::snd('snare').out()
|
||||
mod([1, 0.5].beat()) :: sound(['bass3'].bar())
|
||||
`beat(2)::snd('snare').out()
|
||||
beat([1, 0.5].beat()) :: sound(['bass3'].bar())
|
||||
.freq(100).n([12, 14].bar())
|
||||
.speed([1,2,3].pulse())
|
||||
.out()
|
||||
`
|
||||
)}
|
||||
|
||||
|
||||
- <ic>palindrome()</ic>: Concatenates a list with the same list in reverse.
|
||||
|
||||
${makeExample(
|
||||
"Palindrome filter sweep",
|
||||
`
|
||||
mod([1,.5,.25].beat()) :: snd('sine')
|
||||
.freq([100,200,300].div(0.25))
|
||||
.fmi([1,2,3].palindrome().div(0.5))
|
||||
beat([1,.5,.25].beat()) :: snd('sine')
|
||||
.freq([100,200,300].beat(0.25))
|
||||
.fmi([1,2,3].palindrome().beat(0.5))
|
||||
.fmh([4, 8].palindrome().beat())
|
||||
.cutoff([500,1000,2000,4000].palindrome().beat())
|
||||
.sustain(0.1)
|
||||
@ -94,7 +90,6 @@ mod([1,.5,.25].beat()) :: snd('sine')
|
||||
true
|
||||
)}
|
||||
|
||||
|
||||
- <ic>random(index: number)</ic>: pick a random element in the given list.
|
||||
- <ic>rand(index: number)</ic>: shorter alias for the same method.
|
||||
- <ic>pick()</ic>: pick a random element in the list.
|
||||
@ -103,8 +98,8 @@ mod([1,.5,.25].beat()) :: snd('sine')
|
||||
${makeExample(
|
||||
"Sipping some gasoline at the robot bar",
|
||||
`
|
||||
mod(1)::snd('kick').shape(0.5).out()
|
||||
mod([.5, 1].random() / 2) :: snd(
|
||||
beat(1)::snd('kick').shape(0.5).out()
|
||||
beat([.5, 1].random() / 2) :: snd(
|
||||
['amencutup', 'synth2'].random())
|
||||
.n(irand(4,10))
|
||||
.cutoff(2000)
|
||||
@ -116,9 +111,7 @@ mod([.5, 1].random() / 2) :: snd(
|
||||
|
||||
${makeExample(
|
||||
"Generate a list of random numbers",
|
||||
`
|
||||
mod(0.5) && sound('arp').freq([].gen(300,600,10).div(3)).out()
|
||||
`,
|
||||
`beat(0.5) && sound('arp').freq([].gen(300,600,10).div(3)).out()`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -128,7 +121,7 @@ ${makeExample(
|
||||
"Amen break suffering from data loss",
|
||||
`
|
||||
// Tweak the value to degrade this amen break even more!
|
||||
mod(.25)::snd('amencutup').n([1,2,3,4,5,6,7,8,9].degrade(20).loop($(1))).out()
|
||||
beat(.25)::snd('amencutup').n([1,2,3,4,5,6,7,8,9].degrade(20).loop($(1))).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -141,7 +134,7 @@ ${makeExample(
|
||||
"Repeating samples a given number of times",
|
||||
`
|
||||
// Please take this repeat number down a bit!
|
||||
mod(.25)::sound('amencutup').n([1,2,3,4,5,6,7,8].repeatAll(4).beat()).out()
|
||||
beat(.25)::sound('amencutup').n([1,2,3,4,5,6,7,8].repeatAll(4).beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -151,7 +144,7 @@ mod(.25)::sound('amencutup').n([1,2,3,4,5,6,7,8].repeatAll(4).beat()).out()
|
||||
${makeExample(
|
||||
"Don't you know how to count up to 5?",
|
||||
`
|
||||
mod(1) :: sound('numbers').n([1,2,3,4,5].loop($(3, 10, 2))).out()
|
||||
beat(1) :: sound('numbers').n([1,2,3,4,5].loop($(3, 10, 2))).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -161,7 +154,7 @@ mod(1) :: sound('numbers').n([1,2,3,4,5].loop($(3, 10, 2))).out()
|
||||
${makeExample(
|
||||
"Shuffling a list for extra randomness",
|
||||
`
|
||||
mod(1) :: sound('numbers').n([1,2,3,4,5].shuffle().loop($(1)).out()
|
||||
beat(1) :: sound('numbers').n([1,2,3,4,5].shuffle().loop($(1)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -171,7 +164,7 @@ mod(1) :: sound('numbers').n([1,2,3,4,5].shuffle().loop($(1)).out()
|
||||
${makeExample(
|
||||
"To make things more complex... here you go",
|
||||
`
|
||||
mod(.5) :: snd('sine')
|
||||
beat(.5) :: snd('sine')
|
||||
.freq([100, 150, 200, 250, ,300, 400]
|
||||
.rotate([1,2,3].bar()) // The list of frequencies is rotating
|
||||
.beat()) // while being indexed over!
|
||||
@ -187,7 +180,7 @@ ${makeExample(
|
||||
"Demonstrative filtering. Final list is [100, 200]",
|
||||
`
|
||||
// Remove unique and 100 will repeat four times!
|
||||
mod(1)::snd('sine').sustain(0.1).freq([100,100,100,100,200].unique().beat()).out()
|
||||
beat(1)::snd('sine').sustain(0.1).freq([100,100,100,100,200].unique().beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -199,9 +192,5 @@ mod(1)::snd('sine').sustain(0.1).freq([100,100,100,100,200].unique().beat()).out
|
||||
|
||||
${makeExample("Simple addition", `[1, 2 ,3].add(2).beat()`, true)}
|
||||
|
||||
## Simple patterns
|
||||
|
||||
- <ic>divseq(div: number, ...values:any[])</ic>
|
||||
|
||||
`;
|
||||
};
|
||||
|
||||
@ -19,7 +19,7 @@ The <ic>sound</ic> function can take the name of a synthesizer as first argument
|
||||
${makeExample(
|
||||
"Simple synthesizer voice with filter",
|
||||
`
|
||||
mod(.5) && snd('sawtooth')
|
||||
beat(.5) && snd('sawtooth')
|
||||
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
||||
.resonance(0.9).freq([100,150].pick())
|
||||
.out()
|
||||
@ -30,10 +30,9 @@ mod(.5) && snd('sawtooth')
|
||||
${makeExample(
|
||||
"Listening to the different waveforms from the sweetest to the harshest",
|
||||
`
|
||||
mod(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out()
|
||||
beat(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out()
|
||||
.freq(50)
|
||||
.out()
|
||||
`,
|
||||
.out()`,
|
||||
false
|
||||
)}
|
||||
|
||||
@ -41,11 +40,11 @@ mod(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out(
|
||||
${makeExample(
|
||||
"Blessed by the square wave",
|
||||
`
|
||||
mod(4) :: [100,101].forEach((freq) => sound('square').freq(freq).sustain(0.1).out())
|
||||
mod(.5) :: [100,101].forEach((freq) => sound('square').freq(freq*2).sustain(0.01).out())
|
||||
mod([.5, .75, 2].beat()) :: [100,101].forEach((freq) => sound('square')
|
||||
beat(4) :: [100,101].forEach((freq) => sound('square').freq(freq).sustain(0.1).out())
|
||||
beat(.5) :: [100,101].forEach((freq) => sound('square').freq(freq*2).sustain(0.01).out())
|
||||
beat([.5, .75, 2].beat()) :: [100,101].forEach((freq) => sound('square')
|
||||
.freq(freq*4 + usquare(2) * 200).sustain(0.125).out())
|
||||
mod(.25) :: sound('square').freq(100*[1,2,4,8].beat()).sustain(0.1).out()`,
|
||||
beat(.25) :: sound('square').freq(100*[1,2,4,8].beat()).sustain(0.1).out()`,
|
||||
false
|
||||
)}
|
||||
|
||||
@ -53,7 +52,7 @@ mod(.25) :: sound('square').freq(100*[1,2,4,8].beat()).sustain(0.1).out()`,
|
||||
${makeExample(
|
||||
"Ghost carillon",
|
||||
`
|
||||
mod(1/8)::sound('sine')
|
||||
beat(1/8)::sound('sine')
|
||||
.velocity(rand(0.0, 1.0))
|
||||
.delay(0.75).delayt(.5)
|
||||
.sustain(0.4)
|
||||
@ -76,9 +75,9 @@ The same basic waveforms can take additional methods to switch to a basic two op
|
||||
${makeExample(
|
||||
"80s nostalgia",
|
||||
`
|
||||
mod(.25) && snd('sine')
|
||||
beat(.25) && snd('sine')
|
||||
.fmi([1,2,4,8].pick())
|
||||
.fmh([1,2,4,8].div(8))
|
||||
.fmh([1,2,4,8].beat(8))
|
||||
.freq([100,150].pick())
|
||||
.sustain(0.1)
|
||||
.out()
|
||||
@ -89,9 +88,9 @@ mod(.25) && snd('sine')
|
||||
${makeExample(
|
||||
"Giving some love to weird ratios",
|
||||
`
|
||||
mod([.5, .25].bar()) :: sound('sine').fm('2.2183:3.18293').sustain(0.05).out()
|
||||
mod([4].bar()) :: sound('sine').fm('5.2183:4.5').sustain(0.05).out()
|
||||
mod(.5) :: sound('sine')
|
||||
beat([.5, .25].bar()) :: sound('sine').fm('2.2183:3.18293').sustain(0.05).out()
|
||||
beat([4].bar()) :: sound('sine').fm('5.2183:4.5').sustain(0.05).out()
|
||||
beat(.5) :: sound('sine')
|
||||
.fmh([1, 1.75].beat())
|
||||
.fmi($(1) % 30).orbit(2).room(0.5).out()`,
|
||||
false
|
||||
@ -101,7 +100,7 @@ mod(.5) :: sound('sine')
|
||||
${makeExample(
|
||||
"Some peace and serenity",
|
||||
`
|
||||
mod(0.25) :: sound('sine')
|
||||
beat(0.25) :: sound('sine')
|
||||
.note([60, 67, 70, 72, 77].beat() - [0,12].bar())
|
||||
.attack(0.2).release(0.5).gain(0.25)
|
||||
.room(0.9).size(0.8).sustain(0.5)
|
||||
@ -123,10 +122,10 @@ There is also a more advanced set of parameters you can use to control the envel
|
||||
${makeExample(
|
||||
"FM Synthesis with envelope control",
|
||||
`
|
||||
mod(.5) :: sound('sine')
|
||||
.note([50,53,55,57].div(.5) - 12)
|
||||
beat(.5) :: sound('sine')
|
||||
.note([50,53,55,57].beat(.5) - 12)
|
||||
.fmi(0.5 + usine(.25) * 1.5)
|
||||
.fmh([2,4].div(.125))
|
||||
.fmh([2,4].beat(.125))
|
||||
.fmwave('triangle')
|
||||
.fmsus(0).fmdec(0.2).out()
|
||||
`,
|
||||
@ -142,16 +141,16 @@ ZZfX can be triggered by picking a default ZZfX waveform in the following list:
|
||||
${makeExample(
|
||||
"Picking a waveform",
|
||||
`
|
||||
mod(.5) :: sound(['z_sine', 'z_triangle', 'z_sawtooth', 'z_tan', 'z_noise'].beat()).out()
|
||||
beat(.5) :: sound(['z_sine', 'z_triangle', 'z_sawtooth', 'z_tan', 'z_noise'].beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
${makeExample(
|
||||
"Minimalist chiptune",
|
||||
`
|
||||
mod(.5) :: sound('z_triangle')
|
||||
.note([60, 67, 72, 63, 65, 70].div(.5))
|
||||
.zrand(0).curve([1,2,3,4].div(1))
|
||||
beat(.5) :: sound('z_triangle')
|
||||
.note([60, 67, 72, 63, 65, 70].beat(.5))
|
||||
.zrand(0).curve([1,2,3,4].beat(1))
|
||||
.slide(0.01).tremolo(12)
|
||||
.noise([0,0.5].beat())
|
||||
.decay(0.3).sustain(0)
|
||||
@ -187,7 +186,7 @@ It comes with a set of parameters that can be used to tweak the sound. Don't und
|
||||
${makeExample(
|
||||
"Chaotic Noise source",
|
||||
`
|
||||
mod(.25) :: sound('z_tan')
|
||||
beat(.25) :: sound('z_tan')
|
||||
.note(40).noise(rand(0.0, 1.0))
|
||||
.pitchJump(84).pitchJumpTime(rand(0.0, 1.0))
|
||||
.zcrush([0,1,2,3,4].beat())
|
||||
@ -201,7 +200,7 @@ mod(.25) :: sound('z_tan')
|
||||
${makeExample(
|
||||
"What is happening to me?",
|
||||
`
|
||||
mod(1) :: snd('zzfx').zzfx([
|
||||
beat(1) :: snd('zzfx').zzfx([
|
||||
[4.77,,25,,.15,.2,3,.21,,2.4,,,,,,,.23,.35],
|
||||
[1.12,,97,.11,.16,.01,4,.77,,,30,.17,,,-1.9,,.01,.67,.2]
|
||||
].beat()).out()
|
||||
@ -211,9 +210,9 @@ mod(1) :: snd('zzfx').zzfx([
|
||||
${makeExample(
|
||||
"Les voitures dans le futur",
|
||||
`
|
||||
mod(1) :: sound(['z_triangle', 'z_sine'].pick())
|
||||
beat(1) :: sound(['z_triangle', 'z_sine'].pick())
|
||||
.note([60,63,72,75].pick()).tremolo(16)
|
||||
.zmod([0, 1/2, 1/8].division(2).pick())
|
||||
.zmod([0, 1/2, 1/8].div(2).pick())
|
||||
.attack(0.5).release(0.5).sustain(2).delay(0.8)
|
||||
.room(0.9).size(0.9)
|
||||
.delayt(0.75).delayfb(0.5).out()
|
||||
@ -226,7 +225,7 @@ ${makeExample(
|
||||
"Designing a sound on the ZzFX website",
|
||||
`
|
||||
|
||||
mod(2) :: sound('zzfx').zzfx([3.62,,452,.16,.1,.21,,2.5,,,403,.05,.29,,,,.17,.34,.22,.68]).out()
|
||||
beat(2) :: sound('zzfx').zzfx([3.62,,452,.16,.1,.21,,2.5,,,403,.05,.29,,,,.17,.34,.22,.68]).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -246,7 +245,7 @@ Topos can also speak using the [Web Speech API](https://developer.mozilla.org/en
|
||||
${makeExample(
|
||||
"Hello world!",
|
||||
`
|
||||
mod(4) :: speak("Hello world!")
|
||||
beat(4) :: speak("Hello world!")
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -254,7 +253,7 @@ mod(4) :: speak("Hello world!")
|
||||
${makeExample(
|
||||
"Different voices",
|
||||
`
|
||||
mod(2) :: speak("Topos!","fr",irand(0,5))
|
||||
beat(2) :: speak("Topos!","fr",irand(0,5))
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -278,7 +277,7 @@ ${makeExample(
|
||||
const object = ["happy","sad","tired"].pick()
|
||||
const sentence = subject+" "+verb+" "+" "+object
|
||||
|
||||
mod(6) :: sentence.pitch(0).rate(0).voice([0,2].pick()).speak()
|
||||
beat(6) :: sentence.pitch(0).rate(0).voice([0,2].pick()).speak()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -20,13 +20,13 @@ To change the tempo, use the <ic>bpm(number)</ic> function. The transport is con
|
||||
|
||||
Let's study two very simple rhythmic functions, <ic>mod(n: ...number[])</ic> and <ic>onbeat(...n:number[])</ic>. They are both easy to understand and powerful enough to get you to play your first rhythms.
|
||||
|
||||
- <ic>mod(...n: number[])</ic>: this function will return true every _n_ pulsations. The value <ic>1</ic> will return <ic>true</ic> at the beginning of each beat. Floating point numbers like <ic>0.5</ic> or <ic>0.25</ic> are also accepted. Multiple values can be passed to <ic>mod</ic> to generate more complex rhythms.
|
||||
- <ic>beat(...n: number[])</ic>: this function will return true every _n_ pulsations. The value <ic>1</ic> will return <ic>true</ic> at the beginning of each beat. Floating point numbers like <ic>0.5</ic> or <ic>0.25</ic> are also accepted. Multiple values can be passed to <ic>beat</ic> to generate more complex rhythms.
|
||||
|
||||
${makeExample(
|
||||
"Using different mod values",
|
||||
`
|
||||
// This code is alternating between different mod values
|
||||
mod([1,1/2,1/4,1/8].div(2)) :: sound('bd').n(0).out()
|
||||
beat([1,1/2,1/4,1/8].beat(2)) :: sound('bd').n(0).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -35,32 +35,32 @@ ${makeExample(
|
||||
"Some sort of ringtone",
|
||||
`
|
||||
let blip = (freq) => {return sound('sine').sustain(0.1).freq(freq)};
|
||||
mod(1) :: blip(200).out();
|
||||
mod(1/3) :: blip(400).out();
|
||||
div(3) :: mod(1/6) :: blip(800).out();
|
||||
mod([1,0.75].div(2)) :: blip([50, 100].div(2)).out();
|
||||
beat(1) :: blip(200).out();
|
||||
beat(1/3) :: blip(400).out();
|
||||
flip(3) :: beat(1/6) :: blip(800).out();
|
||||
beat([1,0.75].beat(2)) :: blip([50, 100].beat(2)).out();
|
||||
`,
|
||||
false
|
||||
)}
|
||||
|
||||
|
||||
- <ic>modp(...n: number[])</ic>: extreme version of the <ic>mod</ic> function. Instead of being normalised, this function is returning a modulo of real pulses! It can be used to break out of ratios and play with real clock pulses for unexpected results.
|
||||
- <ic>pulse(...n: number[])</ic>: extreme version of the <ic>beat</ic> function. Instead of returning true for every beat, this function is returning true every _n_ clock ticks! It can be used to generate very unexpected results or to sequence by using your arithmetic ninja skills.
|
||||
|
||||
${makeExample(
|
||||
"Intriguing rhythms",
|
||||
`
|
||||
modp(36) :: snd('east')
|
||||
.n([2,4].div(1)).out()
|
||||
modp([12, 36].div(4)) :: snd('east')
|
||||
.n([2,4].add(5).div(1)).out()
|
||||
pulse(36) :: snd('east')
|
||||
.n([2,4].beat(1)).out()
|
||||
pulse([12, 36].beat(4)) :: snd('east')
|
||||
.n([2,4].add(5).beat(1)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
${makeExample(
|
||||
"modp is the OG rhythmic function in Topos",
|
||||
"pulse is the OG rhythmic function in Topos",
|
||||
`
|
||||
modp([48, 24, 16].div(4)) :: sound('linnhats').out()
|
||||
mod(1)::snd('bd').out()
|
||||
pulse([48, 24, 16].beat(4)) :: sound('linnhats').out()
|
||||
pulse(1)::snd('bd').out()
|
||||
`,
|
||||
false
|
||||
)};
|
||||
@ -82,7 +82,7 @@ ${makeExample(
|
||||
`
|
||||
onbeat(0.5, 1.5, 2, 3, 3.75)::snd('kick').n(2).out()
|
||||
onbeat(2, [1.5, 3].pick(), 4)::snd('snare').n(7).out()
|
||||
mod([.25, 1/8].div(1.5))::snd('hat').n(2)
|
||||
beat([.25, 1/8].beat(1.5))::snd('hat').n(2)
|
||||
.gain(rand(0.4, 0.7))
|
||||
.pan(usine()).out()
|
||||
`,
|
||||
@ -106,10 +106,10 @@ ${makeExample(
|
||||
"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) ::
|
||||
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()
|
||||
`,
|
||||
true
|
||||
@ -124,8 +124,8 @@ We included a bunch of popular rhythm generators in Topos such as the euclidian
|
||||
${makeExample(
|
||||
"Classic euclidian club music patterns",
|
||||
`
|
||||
mod(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||
mod(.5) && euclid($(2), 2, 8) && snd('sd').out()
|
||||
beat(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||
beat(.5) && euclid($(2), 2, 8) && snd('sd').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -134,9 +134,9 @@ ${makeExample(
|
||||
"And now for more interesting rhythmic constructions",
|
||||
`
|
||||
bpm(145); // Setting a faster BPM
|
||||
mod(.5) && euclid($(1), 5, 8) :: sound('bd').out()
|
||||
mod(.5) && euclid($(2), [1,0].div(8), 8) :: sound('sd').out()
|
||||
mod(.5) && euclid($(6), [6,7].div(8), 8) :: sound('hh').out()
|
||||
beat(.5) && euclid($(1), 5, 8) :: sound('bd').out()
|
||||
beat(.5) && euclid($(2), [1,0].beat(8), 8) :: sound('sd').out()
|
||||
beat(.5) && euclid($(6), [6,7].beat(8), 8) :: sound('hh').out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -144,10 +144,10 @@ mod(.5) && euclid($(6), [6,7].div(8), 8) :: sound('hh').out()
|
||||
${makeExample(
|
||||
"Adding more rhythmic density",
|
||||
`
|
||||
mod(.5) && euclid($(1), 5, 9) && snd('kick').out()
|
||||
mod(.5) && euclid($(2), 2, 3, 1) && snd('east').end(0.5).n(5).out()
|
||||
mod(.5) && euclid($(3), 6, 9, 1) && snd('east').end(0.5).n(5).freq(200).out()
|
||||
mod(.25) && euclid($(4), 7, 9, 1) && snd('hh').out()
|
||||
beat(.5) && euclid($(1), 5, 9) && snd('kick').out()
|
||||
beat(.5) && euclid($(2), 2, 3, 1) && snd('east').end(0.5).n(5).out()
|
||||
beat(.5) && euclid($(3), 6, 9, 1) && snd('east').end(0.5).n(5).freq(200).out()
|
||||
beat(.25) && euclid($(4), 7, 9, 1) && snd('hh').out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -179,16 +179,14 @@ rhythm(speed, 7, 12) :: snd('east').n(9).out()
|
||||
true
|
||||
)}
|
||||
|
||||
|
||||
|
||||
- <ic>bin(iterator: number, n: number): boolean</ic>: a binary rhythm generator. It transforms the given number into its binary representation (_e.g_ <ic>34</ic> becomes <ic>100010</ic>). It then returns a boolean value based on the iterator in order to generate a rhythm.
|
||||
- <ic>binrhythm(divisor: number, n: number): boolean: boolean</ic>: iterator-less version of the binary rhythm generator.
|
||||
|
||||
${makeExample(
|
||||
"Change the integers for a surprise rhythm!",
|
||||
`
|
||||
mod(.5) && bin($(1), 34) && snd('kick').out()
|
||||
mod(.5) && bin($(2), 48) && snd('sd').out()
|
||||
beat(.5) && bin($(1), 34) && snd('kick').out()
|
||||
beat(.5) && bin($(2), 48) && snd('sd').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -205,8 +203,8 @@ binrhythm(.5, 18) && snd('sd').out()
|
||||
${makeExample(
|
||||
"Calling 911",
|
||||
`
|
||||
mod(.5) && bin($(1), 911) && snd('subroc3d').n($(2)).delay(0.5).delayt(0.25).end(0.5).out()
|
||||
mod(.5) && sound('less').n(irand(1, 10)).out()
|
||||
beat(.5) && bin($(1), 911) && snd('subroc3d').n($(2)).delay(0.5).delayt(0.25).end(0.5).out()
|
||||
beat(.5) && sound('less').n(irand(1, 10)).out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -214,9 +212,9 @@ mod(.5) && sound('less').n(irand(1, 10)).out()
|
||||
${makeExample(
|
||||
"Playing around with simple numbers",
|
||||
`
|
||||
mod(.5) && bin($(1), [123, 456, 789].div(4))
|
||||
beat(.5) && bin($(1), [123, 456, 789].beat(4))
|
||||
&& snd('tabla').n($(2)).delay(0.5).delayt(0.25).out()
|
||||
mod(1) && sound('kick').shape(0.5).out()
|
||||
beat(1) && sound('kick').shape(0.5).out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -226,9 +224,9 @@ If you don't find it spicy enough, you can add some more probabilities to your r
|
||||
${makeExample(
|
||||
"Probablistic drums in one line!",
|
||||
`
|
||||
prob(60)::mod(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||
prob(60)::mod(.5) && euclid($(2), 3, 8) && snd('sd').out()
|
||||
prob(80)::mod(.5) && sound('hh').out()
|
||||
prob(60)::beat(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||
prob(60)::beat(.5) && euclid($(2), 3, 8) && snd('sd').out()
|
||||
prob(80)::beat(.5) && sound('hh').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -244,16 +242,16 @@ ${makeExample(
|
||||
"Jumping back and forth in time",
|
||||
`
|
||||
// Obscure Shenanigans - Bubobubobubo
|
||||
mod([1/4,1/8,1/16].div(8)):: sound('sine')
|
||||
.freq([100,50].div(16) + 50 * ($(1)%10))
|
||||
beat([1/4,1/8,1/16].beat(8)):: sound('sine')
|
||||
.freq([100,50].beat(16) + 50 * ($(1)%10))
|
||||
.gain(0.5).room(0.9).size(0.9)
|
||||
.sustain(0.1).out()
|
||||
mod(1) :: sound('kick').out()
|
||||
mod(2) :: sound('dr').n(5).out()
|
||||
div(3) :: mod([.25,.5].div(.5)) :: sound('dr')
|
||||
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].div(.25)).out()
|
||||
beat(1) :: sound('kick').out()
|
||||
beat(2) :: sound('dr').n(5).out()
|
||||
div(3) :: beat([.25,.5].beat(.5)) :: sound('dr')
|
||||
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].beat(.25)).out()
|
||||
// Time is elastic now!
|
||||
mod(.25) :: warp([12, 48, 24, 1, 120, 30].pick())
|
||||
beat(.25) :: warp([12, 48, 24, 1, 120, 30].pick())
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -264,18 +262,18 @@ ${makeExample(
|
||||
"Jumping back and forth with beats",
|
||||
`
|
||||
// Resonance bliss - Bubobubobubo
|
||||
mod(.25)::snd('arpy')
|
||||
beat(.25)::snd('arpy')
|
||||
.note(30 + [0,3,7,10].beat())
|
||||
.cutoff(usine(.5) * 5000).resonance(10).gain(0.3)
|
||||
.end(0.8).room(0.9).size(0.9).n(0).out();
|
||||
mod([.25,.125].div(2))::snd('arpy')
|
||||
beat([.25,.125].beat(2))::snd('arpy')
|
||||
.note(30 + [0,3,7,10].beat())
|
||||
.cutoff(usine(.5) * 5000).resonance(20).gain(0.3)
|
||||
.end(0.8).room(0.9).size(0.9).n(3).out();
|
||||
mod(.5) :: snd('arpy').note(
|
||||
[30, 33, 35].repeatAll(4).div(1) - [12,0].div(0.5)).out()
|
||||
beat(.5) :: snd('arpy').note(
|
||||
[30, 33, 35].repeatAll(4).beat(1) - [12,0].beat(0.5)).out()
|
||||
// Comment me to stop warping!
|
||||
mod(1) :: beat_warp([2,4,5,10,11].pick())
|
||||
beat(1) :: beat_warp([2,4,5,10,11].pick())
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -284,13 +282,13 @@ mod(1) :: beat_warp([2,4,5,10,11].pick())
|
||||
|
||||
Now you know how to play some basic rhythmic music but you are a bit stuck in a one-bar long loop. Let's see how we can think about time flowing on longer periods. The functions you are going to learn now are _very fundamental_ and all the fun comes from mastering them. **Read and experiment a lot with the following examples**.
|
||||
|
||||
- <ic>div(n: number, ratio: number = 50)</ic>: the <ic>div</ic> method is a temporal switch. If the value <ic>2</ic> is given, the function will return <ic>true</ic> for two beats and <ic>false</ic> for two beats. There are multiple ways to use it effectively. You can pass an integer or a floating point number.
|
||||
- <ic>flip(n: number, ratio: number = 50)</ic>: the <ic>flip</ic> method is a temporal switch. If the value <ic>2</ic> is given, the function will return <ic>true</ic> for two beats and <ic>false</ic> for two beats. There are multiple ways to use it effectively. You can pass an integer or a floating point number.
|
||||
- <ic>ratio: number = 50</ic>: this argument is ratio expressed in %. It determines how much of the period should be true or false. A ratio of <ic>75</ic> means that 75% of the period will be true. A ratio of <ic>25</ic> means that 25% of the period will be true.
|
||||
|
||||
${makeExample(
|
||||
"Two beats of silence, two beats of playing",
|
||||
`
|
||||
div(4) :: mod(1) :: snd('kick').out()
|
||||
flip(4) :: beat(1) :: snd('kick').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -298,9 +296,9 @@ div(4) :: mod(1) :: snd('kick').out()
|
||||
${makeExample(
|
||||
"Clapping on the edge",
|
||||
`
|
||||
div(2.5, 10) :: mod(.25) :: snd('cp').out()
|
||||
div(2.5, 75) :: mod(.25) :: snd('click').speed(2).end(0.2).out()
|
||||
div(2.5) :: mod(.5) :: snd('bd').out()
|
||||
flip(2.5, 10) :: beat(.25) :: snd('cp').out()
|
||||
flip(2.5, 75) :: beat(.25) :: snd('click').speed(2).end(0.2).out()
|
||||
flip(2.5) :: mod(.5) :: snd('bd').out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -308,35 +306,35 @@ div(2.5) :: mod(.5) :: snd('bd').out()
|
||||
${makeExample(
|
||||
"Good old true and false",
|
||||
`
|
||||
if (div(4, 75)) {
|
||||
mod(1) :: snd('kick').out()
|
||||
if (flip(4, 75)) {
|
||||
beat(1) :: snd('kick').out()
|
||||
} else {
|
||||
mod(.5) :: snd('snare').out()
|
||||
beat(.5) :: snd('snare').out()
|
||||
}
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
<ic>div</ic> is extremely powerful and is used internally for a lot of other Topos functions. You can also use it to think about **longer durations** spanning over multiple bars.
|
||||
<ic>flip</ic> is extremely powerful and is used internally for a lot of other Topos functions. You can also use it to think about **longer durations** spanning over multiple bars.
|
||||
|
||||
${makeExample(
|
||||
"Clunky algorithmic rap music",
|
||||
`
|
||||
// Rap God VS Lil Wild -- Adel Faure
|
||||
if (div(16)) {
|
||||
if (flip(16)) {
|
||||
// Playing this part for two bars
|
||||
mod(1.5)::snd('kick').out()
|
||||
mod(2)::snd('snare').out()
|
||||
mod(.5)::snd('hh').out()
|
||||
beat(1.5)::snd('kick').out()
|
||||
beat(2)::snd('snare').out()
|
||||
beat(.5)::snd('hh').out()
|
||||
} else {
|
||||
// Now adding some birds and tablas
|
||||
mod(1.5)::snd('kick').out()
|
||||
mod(2)::snd('snare').out()
|
||||
mod(.5)::snd('hh').out()
|
||||
mod(.5)::snd('tabla').speed([1,2].pick()).end(0.5).out()
|
||||
mod(2.34)::snd('birds').n(irand(1,10))
|
||||
beat(1.5)::snd('kick').out()
|
||||
beat(2)::snd('snare').out()
|
||||
beat(.5)::snd('hh').out()
|
||||
beat(.5)::snd('tabla').speed([1,2].pick()).end(0.5).out()
|
||||
beat(2.34)::snd('birds').n(irand(1,10))
|
||||
.delay(0.5).delaytime(0.5).delayfb(0.25).out()
|
||||
mod(.5)::snd('diphone').end(0.5).n([1,2,3,4].pick()).out()
|
||||
beat(.5)::snd('diphone').end(0.5).n([1,2,3,4].pick()).out()
|
||||
}
|
||||
`,
|
||||
true
|
||||
@ -347,7 +345,7 @@ You can use it everywhere to spice things up, including as a method parameter pi
|
||||
${makeExample(
|
||||
"div is great for parameter variation",
|
||||
`
|
||||
mod(.5)::snd(div(4) ? 'kick' : 'hat').out()
|
||||
beat(.5)::snd(flip(4) ? 'kick' : 'hat').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -357,8 +355,8 @@ mod(.5)::snd(div(4) ? 'kick' : 'hat').out()
|
||||
${makeExample(
|
||||
"Thinking music over bars",
|
||||
`
|
||||
divbar(2)::mod(1)::snd('kick').out()
|
||||
divbar(3)::mod(.5)::snd('hat').out()
|
||||
divbar(2)::beat(1)::snd('kick').out()
|
||||
divbar(3)::beat(.5)::snd('hat').out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -366,8 +364,8 @@ ${makeExample(
|
||||
"Alternating over four bars",
|
||||
`
|
||||
divbar(2)
|
||||
? mod(.5) && snd(['kick', 'hh'].div(1)).out()
|
||||
: mod(.5) && snd(['east', 'snare'].div(1)).out()
|
||||
? beat(.5) && snd(['kick', 'hh'].beat(1)).out()
|
||||
: beat(.5) && snd(['east', 'snare'].beat(1)).out()
|
||||
`,
|
||||
false
|
||||
)};
|
||||
@ -379,13 +377,13 @@ ${makeExample(
|
||||
"Using onbar for filler drums",
|
||||
`
|
||||
// Only play on the fourth bar of a four bar cycle.
|
||||
onbar(4, 4)::mod(.5)::snd('hh').out();
|
||||
onbar(4, 4)::beat(.5)::snd('hh').out();
|
||||
|
||||
// Here comes a longer version using JavaScript normal control flow
|
||||
if (onbar([4, 1], 3)) {
|
||||
mod(1)::snd('kick').out();
|
||||
beat(1)::snd('kick').out();
|
||||
} else {
|
||||
mod(.5)::snd('sd').out();
|
||||
beat(.5)::snd('sd').out();
|
||||
}
|
||||
`,
|
||||
true
|
||||
@ -401,13 +399,13 @@ To make a beat, you need a certain number of time grains or **pulses**. The **pu
|
||||
|
||||
Every script can access the current time by using the following functions:
|
||||
|
||||
- <ic>bar(n: number)</ic>: returns the current bar since the origin of time.
|
||||
- <ic>cbar(n: number)</ic>: returns the current bar since the origin of time.
|
||||
|
||||
- <ic>beat(n: number)</ic>: returns the current beat since the beginning of the bar.
|
||||
- <ic>cbeat(n: number)</ic>: returns the current beat since the beginning of the bar.
|
||||
|
||||
- <ic>ebeat()</ic>: returns the current beat since the origin of time (counting from 1).
|
||||
|
||||
- <ic>pulse()</ic>: returns the current bar since the origin of the beat.
|
||||
- <ic>cpulse()</ic>: returns the current bar since the origin of the beat.
|
||||
|
||||
- <ic>ppqn()</ic>: returns the current **PPQN** (see above).
|
||||
|
||||
@ -420,14 +418,14 @@ These values are **extremely useful** to craft more complex syntax or to write m
|
||||
${makeExample(
|
||||
"Manual mode: using time primitives!",
|
||||
`
|
||||
if((bar() % 4) > 1) {
|
||||
mod(1) && sound('kick').out()
|
||||
rarely() && mod(.5) && sound('sd').out()
|
||||
mod(.5) && sound('jvbass').freq(500).out()
|
||||
if((cbar() % 4) > 1) {
|
||||
beat(1) && sound('kick').out()
|
||||
rarely() && beat(.5) && sound('sd').out()
|
||||
beat(.5) && sound('jvbass').freq(500).out()
|
||||
} else {
|
||||
mod(.5) && sound('hh').out()
|
||||
mod(.75) && sound('cp').out()
|
||||
mod(.5) && sound('jvbass').freq(250).out()
|
||||
beat(.5) && sound('hh').out()
|
||||
beat(.75) && sound('cp').out()
|
||||
beat(.5) && sound('jvbass').freq(250).out()
|
||||
}
|
||||
`,
|
||||
true
|
||||
|
||||
@ -42,7 +42,7 @@ z1('s 0 1 2 3 4 5 6 7 8 9').sound('pluck').release(0.1).sustain(0.25).out()
|
||||
${makeExample(
|
||||
"Escaped pitches using curly brackets",
|
||||
`
|
||||
let pattern = div(4) ? z1('s _ _ 0 0 {9 11}') : z1('s _ 0 0 {10 12}');
|
||||
let pattern = flip(4) ? z1('s _ _ 0 0 {9 11}') : z1('s _ 0 0 {10 12}');
|
||||
pattern.sound('pluck').sustain(0.1).room(0.9).out();
|
||||
`,
|
||||
false
|
||||
@ -51,7 +51,7 @@ pattern.sound('pluck').sustain(0.1).room(0.9).out();
|
||||
${makeExample(
|
||||
"Durations using letters and floating point numbers",
|
||||
`
|
||||
div(8) ? z1('s 0 e 1 q 2 h 3 w 4').sound('sine').scale("locrian").out()
|
||||
flip(8) ? z1('s 0 e 1 q 2 h 3 w 4').sound('sine').scale("locrian").out()
|
||||
: z1('0.125 0 0.25 2').sound('sine').scale("locrian").out()
|
||||
`,
|
||||
false
|
||||
@ -61,8 +61,8 @@ ${makeExample(
|
||||
"Disco was invented thanks to Ziffers",
|
||||
`
|
||||
z1('e _ _ 0 ^ 0 _ 0 ^ 0').sound('jvbass').out()
|
||||
mod(1)::snd('bd').out(); mod(2)::snd('sd').out()
|
||||
mod(3) :: snd('cp').room(0.5).size(0.5).orbit(2).out()
|
||||
beat(1)::snd('bd').out(); beat(2)::snd('sd').out()
|
||||
beat(3) :: snd('cp').room(0.5).size(0.5).orbit(2).out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
@ -131,7 +131,7 @@ ${makeExample(
|
||||
"Transposing chords",
|
||||
`
|
||||
z1('q Fmaj Amin Dmin Cmaj Cdim')
|
||||
.key(["F3","E3","D3","E3"].div(3))
|
||||
.key(["F3","E3","D3","E3"].beat(3))
|
||||
.sound('sawtooth').out()
|
||||
`
|
||||
)}
|
||||
@ -161,7 +161,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
||||
.scale('minor').fmi(2).fmh(2).room(0.5)
|
||||
.size(0.5).sustain(0.1) .delay(0.5)
|
||||
.delay(0.125).delayfb(0.25).out();
|
||||
mod(.5) :: snd(['kick', 'hat'].div(.5)).out()
|
||||
beat(.5) :: snd(['kick', 'hat'].beat(.5)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -172,17 +172,17 @@ Ziffers supports all the keys and scales. Keys can be defined by using [scientif
|
||||
|
||||
| Scale name | Intervals |
|
||||
|------------|------------------------|
|
||||
| Lydian | <ic>2221221</ic> |
|
||||
| Mixolydian | <ic>2212212</ic> |
|
||||
| Aeolian | <ic>2122122</ic> |
|
||||
| Locrian | <ic>1221222</ic> |
|
||||
| Ionian | <ic>2212221</ic> |
|
||||
| Dorian | <ic>2122212</ic> |
|
||||
| Phrygian | <ic>1222122</ic> |
|
||||
| Soryllic | <ic>11122122</ic>|
|
||||
| Modimic | <ic>412122</ic> |
|
||||
| Ionalian | <ic>1312122</ic> |
|
||||
| ... | And it goes on for **1490** scales |
|
||||
| Lydian | <ic>2221221</ic> |
|
||||
| Mixolydian | <ic>2212212</ic> |
|
||||
| Aeolian | <ic>2122122</ic> |
|
||||
| Locrian | <ic>1221222</ic> |
|
||||
| Ionian | <ic>2212221</ic> |
|
||||
| Dorian | <ic>2122212</ic> |
|
||||
| Phrygian | <ic>1222122</ic> |
|
||||
| Soryllic | <ic>11122122</ic>|
|
||||
| Modimic | <ic>412122</ic> |
|
||||
| Ionalian | <ic>1312122</ic> |
|
||||
| ... | And it goes on for **1490** scales |
|
||||
|
||||
${makeExample(
|
||||
"What the hell is the Modimic scale?",
|
||||
@ -191,7 +191,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
||||
.scale('modimic').fmi(2).fmh(2).room(0.5)
|
||||
.size(0.5).sustain(0.1) .delay(0.5)
|
||||
.delay(0.125).delayfb(0.25).out();
|
||||
mod(.5) :: snd(['kick', 'hat'].div(.5)).out()
|
||||
beat(.5) :: snd(['kick', 'hat'].beat(.5)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -205,16 +205,16 @@ You can also use more traditional <a href="https://ianring.com/musictheory/scale
|
||||
|
||||
| Scale name | Intervals |
|
||||
|------------|------------------------|
|
||||
| Major | <ic>2212221</ic> |
|
||||
| Minor | <ic>2122122</ic> |
|
||||
| Minor pentatonic | <ic>32232</ic> |
|
||||
| Harmonic minor | <ic>2122131</ic>|
|
||||
| Harmonic major | <ic>2212131</ic>|
|
||||
| Melodic minor | <ic>2122221</ic>|
|
||||
| Melodic major | <ic>2212122</ic>|
|
||||
| Whole | <ic>222222</ic> |
|
||||
| Blues minor | <ic>321132</ic> |
|
||||
| Blues major | <ic>211323</ic> |
|
||||
| Major | <ic>2212221</ic> |
|
||||
| Minor | <ic>2122122</ic> |
|
||||
| Minor pentatonic | <ic>32232</ic> |
|
||||
| Harmonic minor | <ic>2122131</ic>|
|
||||
| Harmonic major | <ic>2212131</ic>|
|
||||
| Melodic minor | <ic>2122221</ic>|
|
||||
| Melodic major | <ic>2212122</ic>|
|
||||
| Whole | <ic>222222</ic> |
|
||||
| Blues minor | <ic>321132</ic> |
|
||||
| Blues major | <ic>211323</ic> |
|
||||
|
||||
|
||||
${makeExample(
|
||||
@ -224,7 +224,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
||||
.scale('blues minor').fmi(2).fmh(2).room(0.5)
|
||||
.size(0.5).sustain(0.25).delay(0.25)
|
||||
.delay(0.25).delayfb(0.5).out();
|
||||
mod(1, 1.75) :: snd(['kick', 'hat'].div(1)).out()
|
||||
beat(1, 1.75) :: snd(['kick', 'hat'].beat(1)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -242,7 +242,7 @@ z1("s ^ (0,8) 0 0 _ (0,5) 0 0").sound('sine')
|
||||
.scale('17/16 9/8 6/5 5/4 4/3 11/8 3/2 13/8 5/3 7/4 15/8 2/1').fmi(2).fmh(2).room(0.5)
|
||||
.size(0.5).sustain(0.15).delay(0.1)
|
||||
.delay(0.25).delayfb(0.5).out();
|
||||
mod(1, 1.75) :: snd(['kick', 'hat'].div(1)).out()
|
||||
beat(1, 1.75) :: snd(['kick', 'hat'].beat(1)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
@ -258,7 +258,7 @@ ${makeExample(
|
||||
`
|
||||
z0('w 0 8').sound('peri').out()
|
||||
z1('e 0 4 5 9').sound('bell').out()
|
||||
`,
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -267,7 +267,7 @@ ${makeExample(
|
||||
`
|
||||
z1('w 0 5').sound('pluck').release(0.1).sustain(0.25).out()
|
||||
z2('q 6 3').wait(z1).sound('sine').release(0.16).sustain(0.55).out()
|
||||
`,
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
@ -276,13 +276,10 @@ ${makeExample(
|
||||
`
|
||||
z1('w __ 0 5 9 3').sound('bin').out()
|
||||
z2('q __ 4 2 e 6 3 q 6').sync(z1).sound('east').out()
|
||||
`,
|
||||
`,
|
||||
true
|
||||
)}
|
||||
|
||||
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
- Basic notation
|
||||
|
||||
Reference in New Issue
Block a user