Merge branch 'main' of https://github.com/Bubobubobubobubo/Topos
This commit is contained in:
49
src/API.ts
49
src/API.ts
@ -938,7 +938,7 @@ export class UserAPI {
|
|||||||
// Time markers
|
// Time markers
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
bar = (): number => {
|
cbar = (): number => {
|
||||||
/**
|
/**
|
||||||
* Returns the current bar number
|
* Returns the current bar number
|
||||||
*
|
*
|
||||||
@ -947,7 +947,7 @@ export class UserAPI {
|
|||||||
return this.app.clock.time_position.bar + 1;
|
return this.app.clock.time_position.bar + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
tick = (): number => {
|
ctick = (): number => {
|
||||||
/**
|
/**
|
||||||
* Returns the current tick number
|
* Returns the current tick number
|
||||||
*
|
*
|
||||||
@ -956,7 +956,7 @@ export class UserAPI {
|
|||||||
return this.app.clock.tick + 1;
|
return this.app.clock.tick + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
pulse = (): number => {
|
cpulse = (): number => {
|
||||||
/**
|
/**
|
||||||
* Returns the current pulse number
|
* Returns the current pulse number
|
||||||
*
|
*
|
||||||
@ -965,7 +965,7 @@ export class UserAPI {
|
|||||||
return this.app.clock.time_position.pulse + 1;
|
return this.app.clock.time_position.pulse + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
beat = (): number => {
|
cbeat = (): number => {
|
||||||
/**
|
/**
|
||||||
* Returns the current beat number
|
* Returns the current beat number
|
||||||
*
|
*
|
||||||
@ -1008,7 +1008,7 @@ export class UserAPI {
|
|||||||
// Time Filters
|
// Time Filters
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
public mod = (...n: number[]): boolean => {
|
public beat = (...n: number[]): boolean => {
|
||||||
const results: boolean[] = n.map(
|
const results: boolean[] = n.map(
|
||||||
(value) =>
|
(value) =>
|
||||||
this.app.clock.pulses_since_origin % Math.floor(value * this.ppqn()) ===
|
this.app.clock.pulses_since_origin % Math.floor(value * this.ppqn()) ===
|
||||||
@ -1017,33 +1017,22 @@ export class UserAPI {
|
|||||||
return results.some((value) => value === true);
|
return results.some((value) => value === true);
|
||||||
};
|
};
|
||||||
|
|
||||||
public modpulse = (...n: number[]): boolean => {
|
public pulse = (...n: number[]): boolean => {
|
||||||
const results: boolean[] = n.map(
|
const results: boolean[] = n.map(
|
||||||
(value) => this.app.clock.pulses_since_origin % value === 0
|
(value) => this.app.clock.pulses_since_origin % value === 0
|
||||||
);
|
);
|
||||||
return results.some((value) => value === true);
|
return results.some((value) => value === true);
|
||||||
};
|
};
|
||||||
modp = this.modpulse;
|
|
||||||
|
|
||||||
public modbar = (...n: number[]): boolean => {
|
// =============================================================
|
||||||
const results: boolean[] = n.map(
|
// Modulo based time filters
|
||||||
(value) =>
|
// =============================================================
|
||||||
this.app.clock.time_position.bar % Math.floor(value * this.ppqn()) === 0
|
|
||||||
);
|
|
||||||
return results.some((value) => value === true);
|
|
||||||
};
|
|
||||||
modb = this.modbar;
|
|
||||||
|
|
||||||
// Original implementation
|
// =============================================================
|
||||||
// public div = (chunk: number): boolean => {
|
// Other core temporal functions
|
||||||
// const time_pos = this.app.clock.pulses_since_origin;
|
// =============================================================
|
||||||
// const current_chunk = Math.floor(
|
|
||||||
// time_pos / Math.floor(chunk * this.ppqn())
|
|
||||||
// );
|
|
||||||
// return current_chunk % 2 === 0;
|
|
||||||
// };
|
|
||||||
|
|
||||||
public div = (chunk: number, ratio: number = 50): boolean => {
|
public flip = (chunk: number, ratio: number = 50): boolean => {
|
||||||
/**
|
/**
|
||||||
* Determines if the current time position is in the first
|
* Determines if the current time position is in the first
|
||||||
* or second half of a given time chunk.
|
* or second half of a given time chunk.
|
||||||
@ -1059,12 +1048,16 @@ export class UserAPI {
|
|||||||
return pos_within_chunk < threshold;
|
return pos_within_chunk < threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
public divbar = (chunk: number): boolean => {
|
public flipbar = (chunk: number = 1): boolean => {
|
||||||
const time_pos = this.app.clock.time_position.bar;
|
const time_pos = this.app.clock.time_position.bar;
|
||||||
const current_chunk = Math.floor(time_pos / chunk);
|
const current_chunk = Math.floor(time_pos / chunk);
|
||||||
return current_chunk % 2 === 0;
|
return current_chunk % 2 === 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// =============================================================
|
||||||
|
// "On" Filters
|
||||||
|
// =============================================================
|
||||||
|
|
||||||
public onbar = (
|
public onbar = (
|
||||||
bars: number[] | number,
|
bars: number[] | number,
|
||||||
n: number = this.app.clock.time_signature[0]
|
n: number = this.app.clock.time_signature[0]
|
||||||
@ -1095,7 +1088,7 @@ export class UserAPI {
|
|||||||
if (decimal_part <= 0)
|
if (decimal_part <= 0)
|
||||||
decimal_part = decimal_part + this.ppqn() * this.nominator();
|
decimal_part = decimal_part + this.ppqn() * this.nominator();
|
||||||
final_pulses.push(
|
final_pulses.push(
|
||||||
integral_part === this.beat() && this.pulse() === decimal_part
|
integral_part === this.cbeat() && this.cpulse() === decimal_part
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return final_pulses.some((p) => p == true);
|
return final_pulses.some((p) => p == true);
|
||||||
@ -1199,7 +1192,7 @@ export class UserAPI {
|
|||||||
rotate: number = 0
|
rotate: number = 0
|
||||||
): boolean => {
|
): boolean => {
|
||||||
return (
|
return (
|
||||||
this.mod(div) && this._euclidean_cycle(pulses, length, rotate).div(div)
|
this.beat(div) && this._euclidean_cycle(pulses, length, rotate).beat(div)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1249,7 +1242,7 @@ export class UserAPI {
|
|||||||
*/
|
*/
|
||||||
let convert: string = n.toString(2);
|
let convert: string = n.toString(2);
|
||||||
let tobin: boolean[] = convert.split("").map((x: string) => x === "1");
|
let tobin: boolean[] = convert.split("").map((x: string) => x === "1");
|
||||||
return this.mod(div) && tobin.div(div);
|
return this.beat(div) && tobin.beat(div);
|
||||||
};
|
};
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|||||||
@ -6,7 +6,7 @@ declare global {
|
|||||||
add(amount: number): number[];
|
add(amount: number): number[];
|
||||||
sub(amount: number): number[];
|
sub(amount: number): number[];
|
||||||
mult(amount: number): number[];
|
mult(amount: number): number[];
|
||||||
division(amount: number): number[];
|
div(amount: number): number[];
|
||||||
palindrome(): T[];
|
palindrome(): T[];
|
||||||
random(index: number): T;
|
random(index: number): T;
|
||||||
rand(index: number): T;
|
rand(index: number): T;
|
||||||
@ -14,12 +14,11 @@ declare global {
|
|||||||
repeatAll(amount: number): T;
|
repeatAll(amount: number): T;
|
||||||
repeatPair(amount: number): T;
|
repeatPair(amount: number): T;
|
||||||
repeatOdd(amount: number): T;
|
repeatOdd(amount: number): T;
|
||||||
beat(): T;
|
beat(division: number): T;
|
||||||
bar(): T;
|
bar(): T;
|
||||||
pulse(): T;
|
pulse(): T;
|
||||||
pick(): T;
|
pick(): T;
|
||||||
loop(index: number): T;
|
loop(index: number): T;
|
||||||
div(division: number): T;
|
|
||||||
shuffle(): this;
|
shuffle(): this;
|
||||||
rotate(steps: number): this;
|
rotate(steps: number): this;
|
||||||
unique(): this;
|
unique(): this;
|
||||||
@ -75,7 +74,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
|||||||
return this.map((x: number) => x * amount);
|
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.
|
* @param amount - The value to divide each element in the array by.
|
||||||
* @returns New array with divided values. Throws if division by zero.
|
* @returns New array with divided values. Throws if division by zero.
|
||||||
@ -93,15 +92,6 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
|||||||
return this[Math.floor(api.randomGen() * this.length)];
|
return this[Math.floor(api.randomGen() * this.length)];
|
||||||
};
|
};
|
||||||
|
|
||||||
Array.prototype.beat = function (beat: number = 1) {
|
|
||||||
/**
|
|
||||||
* Returns the element corresponding to the current beat
|
|
||||||
*
|
|
||||||
* @returns The element corresponding to the current beat
|
|
||||||
*/
|
|
||||||
return this[(api.app.clock.beats_since_origin / beat) % this.length];
|
|
||||||
};
|
|
||||||
|
|
||||||
Array.prototype.gen = function (min: number, max: number, times: number) {
|
Array.prototype.gen = function (min: number, max: number, times: number) {
|
||||||
/**
|
/**
|
||||||
* Returns an array of random numbers.
|
* Returns an array of random numbers.
|
||||||
@ -110,10 +100,13 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
|||||||
* @param times - The number of random numbers to generate
|
* @param times - The number of random numbers to generate
|
||||||
* @returns An array of random numbers
|
* @returns An array of random numbers
|
||||||
*/
|
*/
|
||||||
if(times < 1) {
|
if (times < 1) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Array.from({ length: times }, () => Math.floor(api.randomGen() * (max - min + 1)) + min);
|
return Array.from(
|
||||||
|
{ length: times },
|
||||||
|
() => Math.floor(api.randomGen() * (max - min + 1)) + min
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Array.prototype.bar = function () {
|
Array.prototype.bar = function () {
|
||||||
@ -134,7 +127,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
|||||||
return this[api.app.clock.time_position.pulse % this.length];
|
return this[api.app.clock.time_position.pulse % this.length];
|
||||||
};
|
};
|
||||||
|
|
||||||
Array.prototype.div = function (divisor: number) {
|
Array.prototype.beat = function (divisor: number = 1) {
|
||||||
const chunk_size = divisor; // Get the first argument (chunk size)
|
const chunk_size = divisor; // Get the first argument (chunk size)
|
||||||
const timepos = api.app.clock.pulses_since_origin;
|
const timepos = api.app.clock.pulses_since_origin;
|
||||||
const slice_count = Math.floor(
|
const slice_count = Math.floor(
|
||||||
|
|||||||
@ -10,8 +10,19 @@ import {
|
|||||||
export class SoundEvent extends AudibleEvent {
|
export class SoundEvent extends AudibleEvent {
|
||||||
constructor(sound: string | object, public app: Editor) {
|
constructor(sound: string | object, public app: Editor) {
|
||||||
super(app);
|
super(app);
|
||||||
if (typeof sound === "string") this.values = { s: sound, dur: 0.5 };
|
if (typeof sound === "string") {
|
||||||
else this.values = sound;
|
if (sound.includes(":")) {
|
||||||
|
this.values = {
|
||||||
|
s: sound.split(":")[0],
|
||||||
|
n: sound.split(":")[1],
|
||||||
|
dur: 0.5,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.values = { s: sound, dur: 0.5 };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.values = sound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateValue<T>(key: string, value: T): this {
|
private updateValue<T>(key: string, value: T): this {
|
||||||
@ -103,11 +114,13 @@ export class SoundEvent extends AudibleEvent {
|
|||||||
public begin = (value: number) => this.updateValue("begin", value);
|
public begin = (value: number) => this.updateValue("begin", value);
|
||||||
public end = (value: number) => this.updateValue("end", value);
|
public end = (value: number) => this.updateValue("end", value);
|
||||||
public gain = (value: number) => this.updateValue("gain", value);
|
public gain = (value: number) => this.updateValue("gain", value);
|
||||||
public dbgain = (value: number) => this.updateValue("gain", Math.min(Math.pow(10, value / 20), 10));
|
public dbgain = (value: number) =>
|
||||||
|
this.updateValue("gain", Math.min(Math.pow(10, value / 20), 10));
|
||||||
public db = this.dbgain;
|
public db = this.dbgain;
|
||||||
public cutoff = (value: number) => this.updateValue("cutoff", value);
|
public cutoff = (value: number) => this.updateValue("cutoff", value);
|
||||||
public lpf = this.cutoff;
|
public lpf = this.cutoff;
|
||||||
public resonance = (value: number) => this.updateValue("resonance", Math.min(Math.max(value, 0), 50));
|
public resonance = (value: number) =>
|
||||||
|
this.updateValue("resonance", Math.min(Math.max(value, 0), 50));
|
||||||
public lpq = this.resonance;
|
public lpq = this.resonance;
|
||||||
public hcutoff = (value: number) => this.updateValue("hcutoff", value);
|
public hcutoff = (value: number) => this.updateValue("hcutoff", value);
|
||||||
public hpf = this.hcutoff;
|
public hpf = this.hcutoff;
|
||||||
@ -164,9 +177,9 @@ export class SoundEvent extends AudibleEvent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
out = (): void => {
|
out = (): void => {
|
||||||
if(this.values.chord) {
|
if (this.values.chord) {
|
||||||
this.values.chord.forEach((freq: number) => {
|
this.values.chord.forEach((freq: number) => {
|
||||||
const copy = {...this.values};
|
const copy = { ...this.values };
|
||||||
copy.freq = freq;
|
copy.freq = freq;
|
||||||
superdough(copy, 1 / 4, this.values.dur || 0.5);
|
superdough(copy, 1 / 4, this.values.dur || 0.5);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -19,7 +19,7 @@ Some features are not part of the core of Topos but are still very useful. They
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Hydra integration",
|
"Hydra integration",
|
||||||
`mod(4) :: app.hydra.osc(3, 0.5, 2).out()`,
|
`beat(4) :: app.hydra.osc(3, 0.5, 2).out()`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ Stopping **Hydra** is simple:
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Stopping Hydra",
|
"Stopping Hydra",
|
||||||
`
|
`
|
||||||
mod(4) :: stop_hydra() // this one
|
beat(4) :: stop_hydra() // this one
|
||||||
mod(4) :: app.hydra.hush() // or this one
|
beat(4) :: app.hydra.hush() // or this one
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ All functions from the sound object can be used to modify the event, for example
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Modifying sound events with probabilities",
|
"Modifying sound events with probabilities",
|
||||||
`
|
`
|
||||||
mod(.5) && sound('numbers')
|
beat(.5) && sound('numbers')
|
||||||
.odds(1/4, s => s.speed(irand(1,4)))
|
.odds(1/4, s => s.speed(irand(1,4)))
|
||||||
.rarely(s => s.crush(3))
|
.rarely(s => s.crush(3))
|
||||||
.out()
|
.out()
|
||||||
@ -27,7 +27,7 @@ ${makeExample(
|
|||||||
"Chance to change to a different note",
|
"Chance to change to a different note",
|
||||||
`
|
`
|
||||||
rhythm(.5, 3, 8) && sound('pluck').note(38).out()
|
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))
|
.often(s => s.note(57))
|
||||||
.sometimes(s => s.note(64).n(irand(1,4)))
|
.sometimes(s => s.note(64).n(irand(1,4)))
|
||||||
.note(62)
|
.note(62)
|
||||||
@ -41,7 +41,7 @@ All the functions from the MIDI object can be used to modify the event with prob
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modifying midi events with probabilities",
|
"Modifying midi events with probabilities",
|
||||||
`mod(.5) && midi(60).channel(1)
|
`beat(.5) && midi(60).channel(1)
|
||||||
.odds(1/4, n => n.channel(2))
|
.odds(1/4, n => n.channel(2))
|
||||||
.often(n => n.note+=4)
|
.often(n => n.note+=4)
|
||||||
.sometimes(s => s.velocity(irand(50,100)))
|
.sometimes(s => s.velocity(irand(50,100)))
|
||||||
@ -63,7 +63,7 @@ ${makeExample(
|
|||||||
"Ziffer player using a sound chain and probabilities!",
|
"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')
|
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')
|
.scale('pentatonic').sound('pluck')
|
||||||
.odds(1/4, n => n.delay(0.5).delayt(0.25))
|
.odds(1/4, n => n.delay(0.5).delayt(0.25))
|
||||||
.odds(1/2, n => n.speed(0.5))
|
.odds(1/2, n => n.speed(0.5))
|
||||||
|
|||||||
@ -34,12 +34,12 @@ ${makeExample(
|
|||||||
"Shortening your if conditions",
|
"Shortening your if conditions",
|
||||||
`
|
`
|
||||||
// The && symbol (overriden by :: in Topos) is very often used for conditions!
|
// The && symbol (overriden by :: in Topos) is very often used for conditions!
|
||||||
mod(.75) :: snd('linnhats').n([1,4,5].beat()).out()
|
beat(.75) :: snd('linnhats').n([1,4,5].beat()).out()
|
||||||
mod(1) :: snd('bd').out()
|
beat(1) :: snd('bd').out()
|
||||||
//if (true) && log('very true')
|
//if (true) && log('very true')
|
||||||
// These two lines are the same:
|
// These two lines are the same:
|
||||||
// mod(1) && snd('bd').out()
|
// beat(1) && snd('bd').out()
|
||||||
//// mod(1) :: snd('bd').out()
|
//// beat(1) :: snd('bd').out()
|
||||||
|
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
@ -49,7 +49,7 @@ ${makeExample(
|
|||||||
"More complex conditions using ?",
|
"More complex conditions using ?",
|
||||||
`
|
`
|
||||||
// The ? symbol can be used to write a if/true/false condition
|
// 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')
|
// (true) ? log('very true') : log('very false')
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
@ -60,14 +60,12 @@ ${makeExample(
|
|||||||
"Using not and other short symbols",
|
"Using not and other short symbols",
|
||||||
`
|
`
|
||||||
// The ! symbol can be used to reverse a condition
|
// The ! symbol can be used to reverse a condition
|
||||||
mod(4) ? snd('kick').out() : mod(2)::snd('snare').out()
|
beat(4) ? snd('kick').out() : beat(2) :: snd('snare').out()
|
||||||
!mod(2) :: mod(0.5)::snd('clap').out()
|
!beat(2) :: beat(0.5) :: snd('clap').out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## About crashes and bugs
|
## 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.
|
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(
|
${makeExample(
|
||||||
"Playing sounds is easy",
|
"Playing sounds is easy",
|
||||||
`
|
`
|
||||||
mod(1) && sound('bd').out()
|
beat(1) && sound('bd').out()
|
||||||
mod(0.5) && sound('hh').out()
|
beat(0.5) && sound('hh').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -31,8 +31,8 @@ Let's make it slightly more complex:
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Adding some effects",
|
"Adding some effects",
|
||||||
`
|
`
|
||||||
mod(1) && sound('bd').coarse(0.25).room(0.5).orbit(2).out();
|
beat(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(0.5) && sound('hh').delay(0.25).delaytime(0.125).out();
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -51,7 +51,7 @@ Let's pause for a moment to explain what we just wrote. There are many things to
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
'"Composing" a sound or making a sound chain',
|
'"Composing" a sound or making a sound chain',
|
||||||
`
|
`
|
||||||
mod(1) :: sound('pad')
|
beat(1) :: sound('pad')
|
||||||
.begin(rand(0, 0.4))
|
.begin(rand(0, 0.4))
|
||||||
.freq([50,52].beat())
|
.freq([50,52].beat())
|
||||||
.size(0.9)
|
.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(
|
${makeExample(
|
||||||
"Picking a sample",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
@ -96,7 +96,7 @@ ${makeExample(
|
|||||||
"Picking a sample... with your mouse!",
|
"Picking a sample... with your mouse!",
|
||||||
`
|
`
|
||||||
// Move your mouse to change the sample being used!
|
// 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
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ As we said earlier, the <ic>sound('sample_name')</ic> function can be chained to
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Learning through repetition",
|
"Learning through repetition",
|
||||||
`
|
`
|
||||||
mod(0.5) && sound('hh')
|
beat(0.5) && sound('hh')
|
||||||
.sometimes(s=>s.speed([1,5,10].pick()))
|
.sometimes(s=>s.speed([1,5,10].pick()))
|
||||||
.room(0.5)
|
.room(0.5)
|
||||||
.cutoff(usine(2) * 5000)
|
.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 |
|
| Method | Alias | Description |
|
||||||
|----------|-------|------------------------------------------------------------|
|
|----------|-------|------------------------------------------------------------|
|
||||||
| orbit | | Orbit number |
|
| orbit | | Orbit number |
|
||||||
|
|
||||||
|
|
||||||
## Amplitude
|
## Amplitude
|
||||||
@ -145,7 +145,7 @@ Simple controls over the amplitude (volume) of a given sound.
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Velocity manipulated by a counter",
|
"Velocity manipulated by a counter",
|
||||||
`
|
`
|
||||||
mod(.5)::snd('cp').vel($(1)%10 / 10).out()`,
|
beat(.5)::snd('cp').vel($(1)%10 / 10).out()`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -165,10 +165,10 @@ Note that the **sustain** value is not a duration but an amplitude value (how lo
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Simple synthesizer",
|
"Simple synthesizer",
|
||||||
`
|
`
|
||||||
mod(4)::sound('sawtooth').note(50).decay(0.5).sustain(0.5).release(2).gain(0.25).out();
|
beat(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();
|
beat(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();
|
beat(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(.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()
|
.cutoff(5000).sustain(0.5).release(0.1).gain(0.25).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
@ -192,9 +192,9 @@ ${makeExample(
|
|||||||
"Complex sampling duties",
|
"Complex sampling duties",
|
||||||
`
|
`
|
||||||
// Using some of the modifiers described above :)
|
// Using some of the modifiers described above :)
|
||||||
mod(.5)::snd('pad').begin(0.2)
|
beat(.5)::snd('pad').begin(0.2)
|
||||||
.speed([1, 0.9, 0.8].div(4))
|
.speed([1, 0.9, 0.8].beat(4))
|
||||||
.n([0, 0, 2, 4].div(4)).pan(usine(.5))
|
.n([0, 0, 2, 4].beat(4)).pan(usine(.5))
|
||||||
.end(rand(0.3,0.8))
|
.end(rand(0.3,0.8))
|
||||||
.room(0.8).size(0.5)
|
.room(0.8).size(0.5)
|
||||||
.clip(1).out()
|
.clip(1).out()
|
||||||
@ -220,7 +220,7 @@ There are three basic filters: a _lowpass_, _highpass_ and _bandpass_ filters wi
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Filter sweep using a low frequency oscillator",
|
"Filter sweep using a low frequency oscillator",
|
||||||
`
|
`
|
||||||
mod(.5) && snd('sawtooth')
|
beat(.5) && snd('sawtooth')
|
||||||
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
||||||
.resonance(0.9).freq([100,150].pick())
|
.resonance(0.9).freq([100,150].pick())
|
||||||
.out()
|
.out()
|
||||||
@ -240,7 +240,7 @@ A basic reverberator that you can use to give some depth to your sounds. This si
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Clapping in the cavern",
|
"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
|
true
|
||||||
)};
|
)};
|
||||||
@ -259,9 +259,9 @@ A good sounding delay unit that can go into feedback territory. Use it without m
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Who doesn't like delay?",
|
"Who doesn't like delay?",
|
||||||
`
|
`
|
||||||
mod(2)::snd('cp').delay(0.5).delaytime(0.75).delayfb(0.8).out()
|
beat(2)::snd('cp').delay(0.5).delaytime(0.75).delayfb(0.8).out()
|
||||||
mod(4)::snd('snare').out()
|
beat(4)::snd('snare').out()
|
||||||
mod(1)::snd('kick').out()
|
beat(1)::snd('kick').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)};
|
)};
|
||||||
@ -278,8 +278,8 @@ mod(1)::snd('kick').out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Crunch... crunch... crunch!",
|
"Crunch... crunch... crunch!",
|
||||||
`
|
`
|
||||||
mod(.5)::snd('pad').coarse($(1) % 16).clip(.5).out(); // Comment me
|
beat(.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').crush([16, 8, 4].beat(2)).clip(.5).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)};
|
)};
|
||||||
|
|||||||
@ -86,7 +86,7 @@ You can control scripts programatically. This is the core concept of Topos after
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Calling a script! The most important feature!",
|
"Calling a script! The most important feature!",
|
||||||
`
|
`
|
||||||
mod(1) :: script(1)
|
beat(1) :: script(1)
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -94,7 +94,7 @@ mod(1) :: script(1)
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Calling mutliple scripts at the same time.",
|
"Calling mutliple scripts at the same time.",
|
||||||
`
|
`
|
||||||
mod(1) :: script(1, 3, 5)
|
beat(1) :: script(1, 3, 5)
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
@ -111,7 +111,7 @@ You can get the current position of the mouse on the screen by using the followi
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"FM Synthesizer controlled using the mouse",
|
"FM Synthesizer controlled using the mouse",
|
||||||
`
|
`
|
||||||
mod(.25) :: sound('sine')
|
beat(.25) :: sound('sine')
|
||||||
.fmi(mouseX() / 100)
|
.fmi(mouseX() / 100)
|
||||||
.fmh(mouseY() / 100)
|
.fmh(mouseY() / 100)
|
||||||
.vel(0.2)
|
.vel(0.2)
|
||||||
@ -129,7 +129,7 @@ Current mouse position can also be used to generate notes:
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"The same synthesizer, with note control!",
|
"The same synthesizer, with note control!",
|
||||||
`
|
`
|
||||||
mod(.25) :: sound('sine')
|
beat(.25) :: sound('sine')
|
||||||
.fmi(mouseX() / 100)
|
.fmi(mouseX() / 100)
|
||||||
.note(noteX())
|
.note(noteX())
|
||||||
.fmh(mouseY() / 100)
|
.fmh(mouseY() / 100)
|
||||||
@ -148,7 +148,7 @@ Low Frequency Oscillators (_LFOs_) are an important piece in any digital audio w
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modulating the speed of a sample player using a sine LFO",
|
"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
|
true
|
||||||
)};
|
)};
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ ${makeExample(
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modulating the speed of a sample player using a triangle LFO",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ ${makeExample(
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modulating the speed of a sample player using a saw LFO",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ ${makeExample(
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modulating the speed of a sample player using a square LFO",
|
"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
|
true
|
||||||
)};
|
)};
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ ${makeExample(
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Modulating the speed of a sample player using noise",
|
"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
|
true
|
||||||
)};
|
)};
|
||||||
|
|
||||||
@ -254,8 +254,8 @@ ${makeExample(
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Using chance with other operators",
|
"Using chance with other operators",
|
||||||
`
|
`
|
||||||
frequently() :: mod(1) :: sound('kick').out();
|
frequently() :: beat(1) :: sound('kick').out();
|
||||||
often() :: mod(0.5) :: sound('hh').out();
|
often() :: beat(0.5) :: sound('hh').out();
|
||||||
sometimes() :: onbeat(1,3) :: sound('snare').out();
|
sometimes() :: onbeat(1,3) :: sound('snare').out();
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
@ -264,12 +264,12 @@ ${makeExample(
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Using chance with chaining",
|
"Using chance with chaining",
|
||||||
`
|
`
|
||||||
mod(0.5) && sound("bd")
|
beat(0.5) && sound("bd")
|
||||||
.freq(100)
|
.freq(100)
|
||||||
.sometimes(s=>s.crush(2.5))
|
.sometimes(s=>s.crush(2.5))
|
||||||
.out()
|
.out()
|
||||||
|
|
||||||
mod(0.5) && sound('arp').freq(100)
|
beat(0.5) && sound('arp').freq(100)
|
||||||
.sometimes(n=>n.freq(200).delay(0.5))
|
.sometimes(n=>n.freq(200).delay(0.5))
|
||||||
.rarely(n=>n.freq(300).delay(2.5))
|
.rarely(n=>n.freq(300).delay(2.5))
|
||||||
.almostNever(n=>n.freq(400))
|
.almostNever(n=>n.freq(400))
|
||||||
@ -293,8 +293,8 @@ ${makeExample(
|
|||||||
"Phased woodblocks",
|
"Phased woodblocks",
|
||||||
`
|
`
|
||||||
// Some very low-budget version of phase music
|
// Some very low-budget version of phase music
|
||||||
mod(.5) :: delay(usine(.125) * 80, () => sound('east').out())
|
beat(.5) :: delay(usine(.125) * 80, () => sound('east').out())
|
||||||
mod(.5) :: delay(50, () => sound('east').out())
|
beat(.5) :: delay(50, () => sound('east').out())
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -304,8 +304,8 @@ mod(.5) :: delay(50, () => sound('east').out())
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Another woodblock texture",
|
"Another woodblock texture",
|
||||||
`
|
`
|
||||||
mod(1) :: delayr(50, 4, () => sound('east').speed([0.5,.25].beat()).out())
|
beat(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())
|
flip(2) :: beat(2) :: delayr(150, 4, () => sound('east').speed([0.5,.25].beat() * 4).out())
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)};
|
)};
|
||||||
|
|||||||
@ -23,7 +23,7 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
name: "delayr",
|
name: "delayr",
|
||||||
category: "time",
|
category: "time",
|
||||||
description: "Delay a function <i>n</i> times by <i>t</i> ms",
|
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: {
|
toss: {
|
||||||
name: "toss",
|
name: "toss",
|
||||||
@ -115,12 +115,12 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
description: "Log a value in the console",
|
description: "Log a value in the console",
|
||||||
example: "log('Hello, world')",
|
example: "log('Hello, world')",
|
||||||
},
|
},
|
||||||
div: {
|
flip: {
|
||||||
name: "div",
|
name: "flip",
|
||||||
category: "patterns",
|
category: "patterns",
|
||||||
description:
|
description:
|
||||||
"Returns next value every <i>n</i> beats or true and false alternatively",
|
"Returns true and false alternatively or next value every <i>n</i> beats (arrays)",
|
||||||
example: "div(4, 50) // 2 beats of true, 2 beats of false, 50/50.",
|
example: "flip(4, 50) // 2 beats of true, 2 beats of false, 50/50.",
|
||||||
},
|
},
|
||||||
n: {
|
n: {
|
||||||
name: "n",
|
name: "n",
|
||||||
@ -192,7 +192,7 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
name: "coarse",
|
name: "coarse",
|
||||||
category: "synthesis",
|
category: "synthesis",
|
||||||
description: "Artificial sample-rate lowering",
|
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: {
|
crush: {
|
||||||
name: "crush",
|
name: "crush",
|
||||||
@ -243,12 +243,6 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
description: "Returns list index for the current bar (with wrapping)",
|
description: "Returns list index for the current bar (with wrapping)",
|
||||||
example: "[0,1,2,3].bar()",
|
example: "[0,1,2,3].bar()",
|
||||||
},
|
},
|
||||||
beat: {
|
|
||||||
name: "beat",
|
|
||||||
category: "patterns",
|
|
||||||
description: "Returns list index for the current beat (with wrapping)",
|
|
||||||
example: "[0,1,2,3].beat()",
|
|
||||||
},
|
|
||||||
room: {
|
room: {
|
||||||
name: "room",
|
name: "room",
|
||||||
category: "effect",
|
category: "effect",
|
||||||
@ -335,17 +329,17 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
example:
|
example:
|
||||||
"oncount([1,2,3], 4) // true on beats 1, 2 and 3 in a 4 beats period",
|
"oncount([1,2,3], 4) // true on beats 1, 2 and 3 in a 4 beats period",
|
||||||
},
|
},
|
||||||
mod: {
|
beat: {
|
||||||
name: "mod",
|
name: "beat",
|
||||||
category: "rhythm",
|
category: "rhythm",
|
||||||
description: "return true every <i>n</i> pulsations.",
|
description: "return true every <i>n</i> beats.",
|
||||||
example: "mod(1) :: log(rand(1,5))",
|
example: "beat(1) :: log(rand(1,5))",
|
||||||
},
|
},
|
||||||
modp: {
|
pulse: {
|
||||||
name: "modp",
|
name: "pulse",
|
||||||
category: "rhythm",
|
category: "rhythm",
|
||||||
description: "return true every <i>n</i> ticks.",
|
description: "return true every <i>n</i> pulses.",
|
||||||
example: "modp(8) :: log(rand(1,5))",
|
example: "pulse(8) :: log(rand(1,5))",
|
||||||
},
|
},
|
||||||
euclid: {
|
euclid: {
|
||||||
name: "euclid",
|
name: "euclid",
|
||||||
@ -368,7 +362,7 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
binrhythm: {
|
binrhythm: {
|
||||||
name: "binrhythm",
|
name: "binrhythm",
|
||||||
category: "rhythm",
|
category: "rhythm",
|
||||||
description: "Binary rhythm generator",
|
description: "Binary rhythm generator (time, number)",
|
||||||
example: "binrhythm(.5, 9223) :: sound('cp').out()",
|
example: "binrhythm(.5, 9223) :: sound('cp').out()",
|
||||||
},
|
},
|
||||||
prob: {
|
prob: {
|
||||||
@ -399,61 +393,61 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
name: "odds",
|
name: "odds",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of <i>n</i> %",
|
description: "Return true with a probability of <i>n</i> %",
|
||||||
example: "odds(1/2) // 50% probability"
|
example: "odds(1/2) // 50% probability",
|
||||||
},
|
},
|
||||||
never: {
|
never: {
|
||||||
name: "never",
|
name: "never",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return false",
|
description: "Return false",
|
||||||
example: "never() // false"
|
example: "never() // false",
|
||||||
},
|
},
|
||||||
almostNever: {
|
almostNever: {
|
||||||
name: "almostNever",
|
name: "almostNever",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 2.5%",
|
description: "Return true with a probability of 2.5%",
|
||||||
example: "almostNever() // 2.5% chance"
|
example: "almostNever() // 2.5% chance",
|
||||||
},
|
},
|
||||||
rarely: {
|
rarely: {
|
||||||
name: "rarely",
|
name: "rarely",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 10%",
|
description: "Return true with a probability of 10%",
|
||||||
example: "rarely() // 10% chance"
|
example: "rarely() // 10% chance",
|
||||||
},
|
},
|
||||||
scarcely: {
|
scarcely: {
|
||||||
name: "scarcely",
|
name: "scarcely",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 25%",
|
description: "Return true with a probability of 25%",
|
||||||
example: "scarcely() // 25% chance"
|
example: "scarcely() // 25% chance",
|
||||||
},
|
},
|
||||||
sometimes: {
|
sometimes: {
|
||||||
name: "sometimes",
|
name: "sometimes",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 50%",
|
description: "Return true with a probability of 50%",
|
||||||
example: "sometimes() // 50% chance"
|
example: "sometimes() // 50% chance",
|
||||||
},
|
},
|
||||||
often: {
|
often: {
|
||||||
name: "often",
|
name: "often",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 75%",
|
description: "Return true with a probability of 75%",
|
||||||
example: "often() // 75% chance"
|
example: "often() // 75% chance",
|
||||||
},
|
},
|
||||||
frequently: {
|
frequently: {
|
||||||
name: "frequently",
|
name: "frequently",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 90%",
|
description: "Return true with a probability of 90%",
|
||||||
example: "frequently() // chance"
|
example: "frequently() // chance",
|
||||||
},
|
},
|
||||||
almostAlways: {
|
almostAlways: {
|
||||||
name: "almostAlways",
|
name: "almostAlways",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true with a probability of 98.5%",
|
description: "Return true with a probability of 98.5%",
|
||||||
example: "almostAlways() // 98.5% chance"
|
example: "almostAlways() // 98.5% chance",
|
||||||
},
|
},
|
||||||
always: {
|
always: {
|
||||||
name: "always",
|
name: "always",
|
||||||
category: "randomness",
|
category: "randomness",
|
||||||
description: "Return true",
|
description: "Return true",
|
||||||
example: "always() // true"
|
example: "always() // true",
|
||||||
},
|
},
|
||||||
sound: {
|
sound: {
|
||||||
name: "sound",
|
name: "sound",
|
||||||
@ -484,7 +478,7 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
name: "script",
|
name: "script",
|
||||||
category: "core",
|
category: "core",
|
||||||
description: "Execute one or more local scripts",
|
description: "Execute one or more local scripts",
|
||||||
example: "mod(1) :: script(1)",
|
example: "beat(1) :: script(1)",
|
||||||
},
|
},
|
||||||
clear_script: {
|
clear_script: {
|
||||||
name: "clear_script",
|
name: "clear_script",
|
||||||
@ -510,18 +504,18 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
description: "jumps to the <i>n</i> beat of the clock.",
|
description: "jumps to the <i>n</i> beat of the clock.",
|
||||||
example: "beat_warp(1) :: log('back to the first beat!')",
|
example: "beat_warp(1) :: log('back to the first beat!')",
|
||||||
},
|
},
|
||||||
divbar: {
|
flipbar: {
|
||||||
name: "divbar",
|
name: "flipbar",
|
||||||
category: "time",
|
category: "time",
|
||||||
description:
|
description:
|
||||||
"works just like <i>div</i> but at the level of bars instead of beats",
|
"works just like <i>flip</i> at the level of bars instead of beats",
|
||||||
example: "divbar(2)::mod(1)::snd('kick').out()",
|
example: "flipbar(2)::beat(1)::snd('kick').out()",
|
||||||
},
|
},
|
||||||
onbar: {
|
onbar: {
|
||||||
name: "onbar",
|
name: "onbar",
|
||||||
category: "time",
|
category: "time",
|
||||||
description: "return true when targetted bar(s) is/are reached in period",
|
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: {
|
begin: {
|
||||||
name: "begin",
|
name: "begin",
|
||||||
@ -629,7 +623,7 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
name: "speak",
|
name: "speak",
|
||||||
category: "synthesis",
|
category: "synthesis",
|
||||||
description: "Text to speech synthesizer",
|
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: {
|
midi_outputs: {
|
||||||
name: "midi_outputs",
|
name: "midi_outputs",
|
||||||
@ -775,11 +769,11 @@ const completionDatabase: CompletionDatabase = {
|
|||||||
description: "Multiply each element of the given array by a value",
|
description: "Multiply each element of the given array by a value",
|
||||||
example: "[0,1,2,3].mul(2)",
|
example: "[0,1,2,3].mul(2)",
|
||||||
},
|
},
|
||||||
division: {
|
div: {
|
||||||
name: "div",
|
name: "div",
|
||||||
category: "patterns",
|
category: "patterns",
|
||||||
description: "Divide each element of the given array by a value",
|
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: {
|
scale: {
|
||||||
name: "scale",
|
name: "scale",
|
||||||
|
|||||||
@ -35,8 +35,8 @@ Every Topos session is composed of several small scripts. A set of scripts is ca
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"To take the most out of Topos...",
|
"To take the most out of Topos...",
|
||||||
`// Write your code in multiple scripts. Use all the code buffers!
|
`// Write your code in multiple scripts. Use all the code buffers!
|
||||||
mod(1) :: script(1)
|
beat(1) :: script(1)
|
||||||
div(4) :: mod(.5) :: script(2)
|
flip(4) :: beat(.5) :: script(2)
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -44,8 +44,8 @@ div(4) :: mod(.5) :: script(2)
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Script execution can become musical too!",
|
"Script execution can become musical too!",
|
||||||
`// You can play your scripts... algorithmically.
|
`// You can play your scripts... algorithmically.
|
||||||
mod(1) :: script([1,3,5].pick())
|
beat(1) :: script([1,3,5].pick())
|
||||||
div(4) :: mod([.5, .25].div(16)) :: script([5,6,7,8].loop($(2)))
|
flip(4) :: beat([.5, .25].beat(16)) :: script([5,6,7,8].loop($(2)))
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -16,17 +16,16 @@ ${makeExample(
|
|||||||
|
|
||||||
|
|
||||||
bpm(110)
|
bpm(110)
|
||||||
mod(0.125) && sound('sawtooth')
|
beat(0.125) && sound('sawtooth')
|
||||||
.note([60, 62, 63, 67, 70].div(.125) +
|
.note([60, 62, 63, 67, 70].beat(.125) +
|
||||||
[-12,0,12].beat() + [0, 0, 5, 7].bar())
|
[-12,0,12].beat() + [0, 0, 5, 7].bar())
|
||||||
.sustain(0.1).fmi(0.25).fmh(2).room(0.9)
|
.sustain(0.1).fmi(0.25).fmh(2).room(0.9)
|
||||||
.gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar())
|
.gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar())
|
||||||
.delay(0.5).delayt(0.25).delayfb(0.25)
|
.delay(0.5).delayt(0.25).delayfb(0.25)
|
||||||
.out();
|
.out();
|
||||||
mod(1) && snd('kick').out();
|
beat(1) && snd('kick').out();
|
||||||
mod(2) && snd('snare').out();
|
beat(2) && snd('snare').out();
|
||||||
mod(.5) && snd('hat').out();
|
beat(.5) && snd('hat').out();
|
||||||
|
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -39,16 +38,16 @@ Topos is an _algorithmic_ sequencer. Topos uses small algorithms to represent mu
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Small algorithms for direct musical expression",
|
"Small algorithms for direct musical expression",
|
||||||
`
|
`
|
||||||
mod(1) :: sound(['kick', 'hat', 'snare', 'hat'].div(1)).out()
|
beat(1) :: sound(['kick', 'hat', 'snare', 'hat'].beat(1)).out()
|
||||||
mod(.5) :: sound('jvbass').note(35 + [0,12].beat()).out()
|
beat(.5) :: sound('jvbass').note(35 + [0,12].beat()).out()
|
||||||
mod([0.5, 0.25, 1, 2].div(1)) :: sound('east')
|
beat([0.5, 0.25, 1, 2].beat(1)) :: sound('east')
|
||||||
.room(.5).size(0.5).n(irand(1,5)).out()`,
|
.room(.5).size(0.5).n(irand(1,5)).out()`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Computer music should be immediate and intuitive",
|
"Computer music should be immediate and intuitive",
|
||||||
`mod(.5)::snd('sine')
|
`beat(.5)::snd('sine')
|
||||||
.delay(0.5).delayt(0.25).delayfb(0.7)
|
.delay(0.5).delayt(0.25).delayfb(0.7)
|
||||||
.room(0.8).size(0.8)
|
.room(0.8).size(0.8)
|
||||||
.freq(mouseX()).out()`,
|
.freq(mouseX()).out()`,
|
||||||
@ -58,9 +57,9 @@ ${makeExample(
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Making the web less dreadful, one beep at at time",
|
"Making the web less dreadful, one beep at at time",
|
||||||
`
|
`
|
||||||
mod(.5) :: sound('sid').n($(2)).out()
|
beat(.5) :: sound('sid').n($(2)).out()
|
||||||
mod(.25) :: sound('sid').note(
|
beat(.25) :: sound('sid').note(
|
||||||
[34, 36, 41].div(.25) + [[0,-24].pick(),12].beat())
|
[34, 36, 41].beat(.25) + [[0,-24].pick(),12].beat())
|
||||||
.room(0.9).size(0.9).n(4).out()`,
|
.room(0.9).size(0.9).n(4).out()`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -81,10 +81,10 @@ ${makeExample(
|
|||||||
"Playing some piano",
|
"Playing some piano",
|
||||||
`
|
`
|
||||||
bpm(80) // Setting a default BPM
|
bpm(80) // Setting a default BPM
|
||||||
mod(.5) && midi(36 + seqbeat(0,12)).sustain(0.02).out()
|
beat(.5) && midi(36 + [0,12].beat()).sustain(0.02).out()
|
||||||
mod(.25) && midi([64, 76].pick()).sustain(0.05).out()
|
beat(.25) && midi([64, 76].pick()).sustain(0.05).out()
|
||||||
mod(.75) && midi(seqbeat(64, 67, 69)).sustain(0.05).out()
|
beat(.75) && midi([64, 67, 69].beat()).sustain(0.05).out()
|
||||||
sometimes() && mod(.25) && midi(seqbeat(64, 67, 69) + 24).sustain(0.05).out()
|
beat(.25) && midi([64, 67, 69].beat() + 24).sustain(0.05).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -133,7 +133,7 @@ sysex(0x90, 0x40, 0x7f)
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Tic, tac, tic, tac...",
|
"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
|
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>.
|
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(
|
${makeExample(
|
||||||
"Light drumming",
|
"Light drumming",
|
||||||
`
|
`
|
||||||
// Every bar, use a different rhythm
|
// Every bar, use a different rhythm
|
||||||
mod([1, 0.75].div(4)) :: sound('cp').out()
|
beat([1, 0.75].beat(4)) :: sound('cp').out()
|
||||||
mod([0.5, 1].div(4)) :: sound('kick').out()
|
beat([0.5, 1].beat(4)) :: sound('kick').out()
|
||||||
mod(2)::snd('snare').shape(.5).out()
|
beat(2)::snd('snare').shape(.5).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Using div to create arpeggios",
|
"Using beat to create arpeggios",
|
||||||
`
|
`
|
||||||
// Arpeggio using pulse divisions
|
// Arpeggio using pulse divisions
|
||||||
mod([.5, .25].div(2)) :: sound('sine')
|
beat([.5, .25].beat(2)) :: sound('sine')
|
||||||
.hcutoff(400)
|
.hcutoff(400)
|
||||||
.fmi([1,2].div(8))
|
.fmi([1,2].beat(8))
|
||||||
.fmh([0.5,0.25,1].div(2))
|
.fmh([0.5,0.25,1].beat(2))
|
||||||
.note([50,53,57].div(.25) + [12,24].div(2))
|
.note([50,53,57].beat(.25) + [12,24].beat(2))
|
||||||
.sustain([0.25, 0.5].div(8))
|
.sustain([0.25, 0.5].beat(8))
|
||||||
.room(0.9).size(0.5)
|
.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)
|
.delayfb(0.5)
|
||||||
.out()
|
.out()
|
||||||
`,
|
`,
|
||||||
@ -44,48 +44,44 @@ mod([.5, .25].div(2)) :: sound('sine')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Cool ambiance",
|
"Cool ambiance",
|
||||||
`
|
`
|
||||||
mod(.5) :: snd(['kick', 'hat'].div(4)).out()
|
beat(.5) :: snd(['kick', 'hat'].beat(4)).out()
|
||||||
mod([2,4].div(2)) :: snd('shaker').delay(.5).delayfb(.75).delayt(0.125).out()
|
beat([2,4].beat(2)) :: snd('shaker').delay(.5).delayfb(.75).delayt(0.125).out()
|
||||||
div(2)::mod(1)::snd('clap').out()
|
flip(2)::beat(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()
|
flip(4)::beat(2)::snd('pad').n(2).shape(.5).orbit(2).room(0.9).size(0.9).release(0.5).out()
|
||||||
`,
|
`,
|
||||||
false
|
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>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.
|
- <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(
|
${makeExample(
|
||||||
"A simple drumbeat in no time!",
|
"A simple drumbeat in no time!",
|
||||||
`
|
`
|
||||||
mod(1)::sound(['kick', 'hat', 'snare', 'hat'].beat()).out()
|
beat(1)::sound(['kick', 'hat', 'snare', 'hat'].beat()).out()
|
||||||
mod(1.5)::sound(['jvbass', 'clap'].beat()).out()
|
beat(1.5)::sound(['jvbass', 'clap'].beat()).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Using beat, pulse and bar in the same code",
|
"Using beat, pulse and bar in the same code",
|
||||||
`mod(2)::snd('snare').out()
|
`beat(2)::snd('snare').out()
|
||||||
mod([1, 0.5].beat()) :: sound(['bass3'].bar())
|
beat([1, 0.5].beat()) :: sound(['bass3'].bar())
|
||||||
.freq(100).n([12, 14].bar())
|
.freq(100).n([12, 14].bar())
|
||||||
.speed([1,2,3].pulse())
|
.speed([1,2,3].pulse())
|
||||||
.out()
|
.out()
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
- <ic>palindrome()</ic>: Concatenates a list with the same list in reverse.
|
- <ic>palindrome()</ic>: Concatenates a list with the same list in reverse.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Palindrome filter sweep",
|
"Palindrome filter sweep",
|
||||||
`
|
`
|
||||||
mod([1,.5,.25].beat()) :: snd('sine')
|
beat([1,.5,.25].beat()) :: snd('sine')
|
||||||
.freq([100,200,300].div(0.25))
|
.freq([100,200,300].beat(0.25))
|
||||||
.fmi([1,2,3].palindrome().div(0.5))
|
.fmi([1,2,3].palindrome().beat(0.5))
|
||||||
.fmh([4, 8].palindrome().beat())
|
.fmh([4, 8].palindrome().beat())
|
||||||
.cutoff([500,1000,2000,4000].palindrome().beat())
|
.cutoff([500,1000,2000,4000].palindrome().beat())
|
||||||
.sustain(0.1)
|
.sustain(0.1)
|
||||||
@ -94,7 +90,6 @@ mod([1,.5,.25].beat()) :: snd('sine')
|
|||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
- <ic>random(index: number)</ic>: pick a random element in the given list.
|
- <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>rand(index: number)</ic>: shorter alias for the same method.
|
||||||
- <ic>pick()</ic>: pick a random element in the list.
|
- <ic>pick()</ic>: pick a random element in the list.
|
||||||
@ -103,8 +98,8 @@ mod([1,.5,.25].beat()) :: snd('sine')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Sipping some gasoline at the robot bar",
|
"Sipping some gasoline at the robot bar",
|
||||||
`
|
`
|
||||||
mod(1)::snd('kick').shape(0.5).out()
|
beat(1)::snd('kick').shape(0.5).out()
|
||||||
mod([.5, 1].random() / 2) :: snd(
|
beat([.5, 1].random() / 2) :: snd(
|
||||||
['amencutup', 'synth2'].random())
|
['amencutup', 'synth2'].random())
|
||||||
.n(irand(4,10))
|
.n(irand(4,10))
|
||||||
.cutoff(2000)
|
.cutoff(2000)
|
||||||
@ -116,9 +111,7 @@ mod([.5, 1].random() / 2) :: snd(
|
|||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Generate a list of random numbers",
|
"Generate a list of random numbers",
|
||||||
`
|
`beat(0.5) && sound('arp').freq([].gen(300,600,10).div(3)).out()`,
|
||||||
mod(0.5) && sound('arp').freq([].gen(300,600,10).div(3)).out()
|
|
||||||
`,
|
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -128,7 +121,7 @@ ${makeExample(
|
|||||||
"Amen break suffering from data loss",
|
"Amen break suffering from data loss",
|
||||||
`
|
`
|
||||||
// Tweak the value to degrade this amen break even more!
|
// 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
|
true
|
||||||
)}
|
)}
|
||||||
@ -141,7 +134,7 @@ ${makeExample(
|
|||||||
"Repeating samples a given number of times",
|
"Repeating samples a given number of times",
|
||||||
`
|
`
|
||||||
// Please take this repeat number down a bit!
|
// 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
|
true
|
||||||
)}
|
)}
|
||||||
@ -151,7 +144,7 @@ mod(.25)::sound('amencutup').n([1,2,3,4,5,6,7,8].repeatAll(4).beat()).out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Don't you know how to count up to 5?",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
@ -161,7 +154,7 @@ mod(1) :: sound('numbers').n([1,2,3,4,5].loop($(3, 10, 2))).out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Shuffling a list for extra randomness",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
@ -171,7 +164,7 @@ mod(1) :: sound('numbers').n([1,2,3,4,5].shuffle().loop($(1)).out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"To make things more complex... here you go",
|
"To make things more complex... here you go",
|
||||||
`
|
`
|
||||||
mod(.5) :: snd('sine')
|
beat(.5) :: snd('sine')
|
||||||
.freq([100, 150, 200, 250, ,300, 400]
|
.freq([100, 150, 200, 250, ,300, 400]
|
||||||
.rotate([1,2,3].bar()) // The list of frequencies is rotating
|
.rotate([1,2,3].bar()) // The list of frequencies is rotating
|
||||||
.beat()) // while being indexed over!
|
.beat()) // while being indexed over!
|
||||||
@ -187,7 +180,7 @@ ${makeExample(
|
|||||||
"Demonstrative filtering. Final list is [100, 200]",
|
"Demonstrative filtering. Final list is [100, 200]",
|
||||||
`
|
`
|
||||||
// Remove unique and 100 will repeat four times!
|
// 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
|
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)}
|
${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(
|
${makeExample(
|
||||||
"Simple synthesizer voice with filter",
|
"Simple synthesizer voice with filter",
|
||||||
`
|
`
|
||||||
mod(.5) && snd('sawtooth')
|
beat(.5) && snd('sawtooth')
|
||||||
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
.cutoff([2000,500].pick() + usine(.5) * 4000)
|
||||||
.resonance(0.9).freq([100,150].pick())
|
.resonance(0.9).freq([100,150].pick())
|
||||||
.out()
|
.out()
|
||||||
@ -30,10 +30,9 @@ mod(.5) && snd('sawtooth')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Listening to the different waveforms from the sweetest to the harshest",
|
"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)
|
.freq(50)
|
||||||
.out()
|
.out()`,
|
||||||
`,
|
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -41,11 +40,11 @@ mod(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out(
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Blessed by the square wave",
|
"Blessed by the square wave",
|
||||||
`
|
`
|
||||||
mod(4) :: [100,101].forEach((freq) => sound('square').freq(freq).sustain(0.1).out())
|
beat(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())
|
beat(.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([.5, .75, 2].beat()) :: [100,101].forEach((freq) => sound('square')
|
||||||
.freq(freq*4 + usquare(2) * 200).sustain(0.125).out())
|
.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
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ mod(.25) :: sound('square').freq(100*[1,2,4,8].beat()).sustain(0.1).out()`,
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Ghost carillon",
|
"Ghost carillon",
|
||||||
`
|
`
|
||||||
mod(1/8)::sound('sine')
|
beat(1/8)::sound('sine')
|
||||||
.velocity(rand(0.0, 1.0))
|
.velocity(rand(0.0, 1.0))
|
||||||
.delay(0.75).delayt(.5)
|
.delay(0.75).delayt(.5)
|
||||||
.sustain(0.4)
|
.sustain(0.4)
|
||||||
@ -76,9 +75,9 @@ The same basic waveforms can take additional methods to switch to a basic two op
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"80s nostalgia",
|
"80s nostalgia",
|
||||||
`
|
`
|
||||||
mod(.25) && snd('sine')
|
beat(.25) && snd('sine')
|
||||||
.fmi([1,2,4,8].pick())
|
.fmi([1,2,4,8].pick())
|
||||||
.fmh([1,2,4,8].div(8))
|
.fmh([1,2,4,8].beat(8))
|
||||||
.freq([100,150].pick())
|
.freq([100,150].pick())
|
||||||
.sustain(0.1)
|
.sustain(0.1)
|
||||||
.out()
|
.out()
|
||||||
@ -89,9 +88,9 @@ mod(.25) && snd('sine')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Giving some love to weird ratios",
|
"Giving some love to weird ratios",
|
||||||
`
|
`
|
||||||
mod([.5, .25].bar()) :: sound('sine').fm('2.2183:3.18293').sustain(0.05).out()
|
beat([.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()
|
beat([4].bar()) :: sound('sine').fm('5.2183:4.5').sustain(0.05).out()
|
||||||
mod(.5) :: sound('sine')
|
beat(.5) :: sound('sine')
|
||||||
.fmh([1, 1.75].beat())
|
.fmh([1, 1.75].beat())
|
||||||
.fmi($(1) % 30).orbit(2).room(0.5).out()`,
|
.fmi($(1) % 30).orbit(2).room(0.5).out()`,
|
||||||
false
|
false
|
||||||
@ -101,7 +100,7 @@ mod(.5) :: sound('sine')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Some peace and serenity",
|
"Some peace and serenity",
|
||||||
`
|
`
|
||||||
mod(0.25) :: sound('sine')
|
beat(0.25) :: sound('sine')
|
||||||
.note([60, 67, 70, 72, 77].beat() - [0,12].bar())
|
.note([60, 67, 70, 72, 77].beat() - [0,12].bar())
|
||||||
.attack(0.2).release(0.5).gain(0.25)
|
.attack(0.2).release(0.5).gain(0.25)
|
||||||
.room(0.9).size(0.8).sustain(0.5)
|
.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(
|
${makeExample(
|
||||||
"FM Synthesis with envelope control",
|
"FM Synthesis with envelope control",
|
||||||
`
|
`
|
||||||
mod(.5) :: sound('sine')
|
beat(.5) :: sound('sine')
|
||||||
.note([50,53,55,57].div(.5) - 12)
|
.note([50,53,55,57].beat(.5) - 12)
|
||||||
.fmi(0.5 + usine(.25) * 1.5)
|
.fmi(0.5 + usine(.25) * 1.5)
|
||||||
.fmh([2,4].div(.125))
|
.fmh([2,4].beat(.125))
|
||||||
.fmwave('triangle')
|
.fmwave('triangle')
|
||||||
.fmsus(0).fmdec(0.2).out()
|
.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(
|
${makeExample(
|
||||||
"Picking a waveform",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Minimalist chiptune",
|
"Minimalist chiptune",
|
||||||
`
|
`
|
||||||
mod(.5) :: sound('z_triangle')
|
beat(.5) :: sound('z_triangle')
|
||||||
.note([60, 67, 72, 63, 65, 70].div(.5))
|
.note([60, 67, 72, 63, 65, 70].beat(.5))
|
||||||
.zrand(0).curve([1,2,3,4].div(1))
|
.zrand(0).curve([1,2,3,4].beat(1))
|
||||||
.slide(0.01).tremolo(12)
|
.slide(0.01).tremolo(12)
|
||||||
.noise([0,0.5].beat())
|
.noise([0,0.5].beat())
|
||||||
.decay(0.3).sustain(0)
|
.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(
|
${makeExample(
|
||||||
"Chaotic Noise source",
|
"Chaotic Noise source",
|
||||||
`
|
`
|
||||||
mod(.25) :: sound('z_tan')
|
beat(.25) :: sound('z_tan')
|
||||||
.note(40).noise(rand(0.0, 1.0))
|
.note(40).noise(rand(0.0, 1.0))
|
||||||
.pitchJump(84).pitchJumpTime(rand(0.0, 1.0))
|
.pitchJump(84).pitchJumpTime(rand(0.0, 1.0))
|
||||||
.zcrush([0,1,2,3,4].beat())
|
.zcrush([0,1,2,3,4].beat())
|
||||||
@ -201,7 +200,7 @@ mod(.25) :: sound('z_tan')
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"What is happening to me?",
|
"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],
|
[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]
|
[1.12,,97,.11,.16,.01,4,.77,,,30,.17,,,-1.9,,.01,.67,.2]
|
||||||
].beat()).out()
|
].beat()).out()
|
||||||
@ -211,9 +210,9 @@ mod(1) :: snd('zzfx').zzfx([
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Les voitures dans le futur",
|
"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)
|
.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)
|
.attack(0.5).release(0.5).sustain(2).delay(0.8)
|
||||||
.room(0.9).size(0.9)
|
.room(0.9).size(0.9)
|
||||||
.delayt(0.75).delayfb(0.5).out()
|
.delayt(0.75).delayfb(0.5).out()
|
||||||
@ -226,7 +225,7 @@ ${makeExample(
|
|||||||
"Designing a sound on the ZzFX website",
|
"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
|
true
|
||||||
)}
|
)}
|
||||||
@ -246,7 +245,7 @@ Topos can also speak using the [Web Speech API](https://developer.mozilla.org/en
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Hello world!",
|
"Hello world!",
|
||||||
`
|
`
|
||||||
mod(4) :: speak("Hello world!")
|
beat(4) :: speak("Hello world!")
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -254,7 +253,7 @@ mod(4) :: speak("Hello world!")
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Different voices",
|
"Different voices",
|
||||||
`
|
`
|
||||||
mod(2) :: speak("Topos!","fr",irand(0,5))
|
beat(2) :: speak("Topos!","fr",irand(0,5))
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -278,7 +277,7 @@ ${makeExample(
|
|||||||
const object = ["happy","sad","tired"].pick()
|
const object = ["happy","sad","tired"].pick()
|
||||||
const sentence = subject+" "+verb+" "+" "+object
|
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
|
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.
|
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_ beats. 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(
|
${makeExample(
|
||||||
"Using different mod values",
|
"Using different mod values",
|
||||||
`
|
`
|
||||||
// This code is alternating between 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
|
true
|
||||||
)}
|
)}
|
||||||
@ -35,37 +35,37 @@ ${makeExample(
|
|||||||
"Some sort of ringtone",
|
"Some sort of ringtone",
|
||||||
`
|
`
|
||||||
let blip = (freq) => {return sound('sine').sustain(0.1).freq(freq)};
|
let blip = (freq) => {return sound('sine').sustain(0.1).freq(freq)};
|
||||||
mod(1) :: blip(200).out();
|
beat(1) :: blip(200).out();
|
||||||
mod(1/3) :: blip(400).out();
|
beat(1/3) :: blip(400).out();
|
||||||
div(3) :: mod(1/6) :: blip(800).out();
|
flip(3) :: beat(1/6) :: blip(800).out();
|
||||||
mod([1,0.75].div(2)) :: blip([50, 100].div(2)).out();
|
beat([1,0.75].beat(2)) :: blip([50, 100].beat(2)).out();
|
||||||
`,
|
`,
|
||||||
false
|
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>: faster 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(
|
${makeExample(
|
||||||
"Intriguing rhythms",
|
"Intriguing rhythms",
|
||||||
`
|
`
|
||||||
modp(36) :: snd('east')
|
pulse(36) :: snd('east')
|
||||||
.n([2,4].div(1)).out()
|
.n([2,4].beat(1)).out()
|
||||||
modp([12, 36].div(4)) :: snd('east')
|
pulse([12, 36].beat(4)) :: snd('east')
|
||||||
.n([2,4].add(5).div(1)).out()
|
.n([2,4].add(5).beat(1)).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
${makeExample(
|
${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()
|
pulse([48, 24, 16].beat(4)) :: sound('linnhats').out()
|
||||||
mod(1)::snd('bd').out()
|
beat(1)::snd('bd').out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)};
|
)};
|
||||||
|
|
||||||
- <ic>onbeat(...n: number[])</ic>: By default, the bar is set in <ic>4/4</ic> with four beats per bar. The <ic>onbeat</ic> function allows you to lock on to a specific beat to execute some code. It can accept multiple arguments. It's usage is very straightforward and not hard to understand. You can pass integers or floating point numbers.
|
- <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.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Some simple yet detailed rhythms",
|
"Some simple yet detailed rhythms",
|
||||||
@ -82,20 +82,21 @@ ${makeExample(
|
|||||||
`
|
`
|
||||||
onbeat(0.5, 1.5, 2, 3, 3.75)::snd('kick').n(2).out()
|
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()
|
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))
|
.gain(rand(0.4, 0.7))
|
||||||
.pan(usine()).out()
|
.pan(usine()).out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
- <ic>oncount(beats: number[], meter: number)</ic>: This function is similar to <ic>onbeat</ic> but it allows you to specify a custom meter (time signature denominator) for the beats.
|
- <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.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Using oncount to create more variation in the rhythm",
|
"Using oncount to create more variation in the rhythm",
|
||||||
`
|
`
|
||||||
bpm(120)
|
bpm(120)
|
||||||
z1('q (0 4 2 9)+(0 3 1 5)').sound('sine').cutoff(400).delay(0.5).out()
|
z1('q (0 4 2 9)+(0 3 1 5)').sound('sawtooth').cutoff([400,500,1000,2000].beat(1))
|
||||||
|
.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()
|
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()
|
oncount([1,3,5.5,7,7.5,8],8) :: sound('hh').gain(irand(1.0,4.0)).out()
|
||||||
`,
|
`,
|
||||||
@ -106,10 +107,10 @@ ${makeExample(
|
|||||||
"Using oncount to create rhythms with a custom meter",
|
"Using oncount to create rhythms with a custom meter",
|
||||||
`
|
`
|
||||||
bpm(200)
|
bpm(200)
|
||||||
oncount([1,5,9,13],16) :: sound('bd').gain(1.0).out()
|
oncount([1, 5, 9, 13],16) :: sound('bd').gain(1.0).out()
|
||||||
oncount([5,6,13],16) :: sound('cp').gain(0.9).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([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, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16],16) ::
|
||||||
sound('hh').out()
|
sound('hh').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
@ -124,8 +125,9 @@ We included a bunch of popular rhythm generators in Topos such as the euclidian
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Classic euclidian club music patterns",
|
"Classic euclidian club music patterns",
|
||||||
`
|
`
|
||||||
mod(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
beat(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||||
mod(.5) && euclid($(2), 2, 8) && snd('sd').out()
|
beat(.5) && euclid($(2), 2, 8) && snd('sd').out()
|
||||||
|
beat(4) :: sound('cp').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -134,9 +136,9 @@ ${makeExample(
|
|||||||
"And now for more interesting rhythmic constructions",
|
"And now for more interesting rhythmic constructions",
|
||||||
`
|
`
|
||||||
bpm(145); // Setting a faster BPM
|
bpm(145); // Setting a faster BPM
|
||||||
mod(.5) && euclid($(1), 5, 8) :: sound('bd').out()
|
beat(.5) && euclid($(1), 5, 8) :: sound('bd').out()
|
||||||
mod(.5) && euclid($(2), [1,0].div(8), 8) :: sound('sd').out()
|
beat(.5) && euclid($(2), [1,0].beat(8), 8) :: sound('sd').out()
|
||||||
mod(.5) && euclid($(6), [6,7].div(8), 8) :: sound('hh').out()
|
beat(.5) && euclid($(6), [6,7].beat(8), 8) :: sound('hh').out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
@ -144,10 +146,10 @@ mod(.5) && euclid($(6), [6,7].div(8), 8) :: sound('hh').out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Adding more rhythmic density",
|
"Adding more rhythmic density",
|
||||||
`
|
`
|
||||||
mod(.5) && euclid($(1), 5, 9) && snd('kick').out()
|
beat(.5) && euclid($(1), 5, 9) && snd('kick').out()
|
||||||
mod(.5) && euclid($(2), 2, 3, 1) && snd('east').end(0.5).n(5).out()
|
beat(.5) && euclid($(2), 2, 3, 1) && snd('east').end(0.5).n(5).speed([1,2].beat(2)).out()
|
||||||
mod(.5) && euclid($(3), 6, 9, 1) && snd('east').end(0.5).n(5).freq(200).out()
|
beat(.5) && euclid($(3), 6, 9, 1) && snd('east').end(0.5).n(5).freq(200).speed([2,1].beat(2)).out()
|
||||||
mod(.25) && euclid($(4), 7, 9, 1) && snd('hh').out()
|
beat(.25) && euclid($(4), 7, 9, 1) && snd('hh').out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
@ -159,7 +161,7 @@ ${makeExample(
|
|||||||
"Using oneuclid to create a rhythm without iterators",
|
"Using oneuclid to create a rhythm without iterators",
|
||||||
`
|
`
|
||||||
// Change speed using bpm
|
// Change speed using bpm
|
||||||
// bpm(250)
|
bpm(250)
|
||||||
oneuclid(5, 9) :: snd('kick').out()
|
oneuclid(5, 9) :: snd('kick').out()
|
||||||
oneuclid(7,16) :: snd('east').end(0.5).n(irand(3,5)).out()
|
oneuclid(7,16) :: snd('east').end(0.5).n(irand(3,5)).out()
|
||||||
`,
|
`,
|
||||||
@ -170,7 +172,7 @@ ${makeExample(
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"rhythm is a beginner friendly rhythmic function!",
|
"rhythm is a beginner friendly rhythmic function!",
|
||||||
`
|
`
|
||||||
let speed = [0.5, 0.25].div(8);
|
let speed = [0.5, 0.25].beat(8); bpm(140);
|
||||||
rhythm(speed, 5, 12) :: snd('east').n(2).out()
|
rhythm(speed, 5, 12) :: snd('east').n(2).out()
|
||||||
rhythm(speed, 2, 12) :: snd('east').out()
|
rhythm(speed, 2, 12) :: snd('east').out()
|
||||||
rhythm(speed, 3, 12) :: snd('east').n(4).out()
|
rhythm(speed, 3, 12) :: snd('east').n(4).out()
|
||||||
@ -179,16 +181,14 @@ rhythm(speed, 7, 12) :: snd('east').n(9).out()
|
|||||||
true
|
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>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.
|
- <ic>binrhythm(divisor: number, n: number): boolean: boolean</ic>: iterator-less version of the binary rhythm generator.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Change the integers for a surprise rhythm!",
|
"Change the integers for a surprise rhythm!",
|
||||||
`
|
`
|
||||||
mod(.5) && bin($(1), 34) && snd('kick').out()
|
beat(.5) && bin($(1), 34) && snd('kick').out()
|
||||||
mod(.5) && bin($(2), 48) && snd('sd').out()
|
beat(.5) && bin($(2), 48) && snd('sd').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -203,20 +203,21 @@ binrhythm(.5, 18) && snd('sd').out()
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Calling 911",
|
"Submarine jungle music",
|
||||||
`
|
`
|
||||||
mod(.5) && bin($(1), 911) && snd('subroc3d').n($(2)).delay(0.5).delayt(0.25).end(0.5).out()
|
beat(.5) && bin($(1), 911) && snd('ST69').n([2,3,4].beat())
|
||||||
mod(.5) && sound('less').n(irand(1, 10)).out()
|
.delay(0.125).delayt(0.25).end(0.25).speed(1/3).out()
|
||||||
|
beat(.5) && sound('amencutup').n(irand(2,7)).shape(0.3).out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Playing around with simple numbers",
|
"Using tabla to play unpredictable rhythms",
|
||||||
`
|
`
|
||||||
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()
|
&& 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
|
false
|
||||||
)}
|
)}
|
||||||
@ -226,34 +227,34 @@ If you don't find it spicy enough, you can add some more probabilities to your r
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Probablistic drums in one line!",
|
"Probablistic drums in one line!",
|
||||||
`
|
`
|
||||||
prob(60)::mod(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
prob(60)::beat(.5) && euclid($(1), 5, 8) && snd('kick').out()
|
||||||
prob(60)::mod(.5) && euclid($(2), 3, 8) && snd('sd').out()
|
prob(60)::beat(.5) && euclid($(2), 3, 8) && snd('sd').out()
|
||||||
prob(80)::mod(.5) && sound('hh').out()
|
prob(80)::beat(.5) && sound('hh').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
## Time Warping
|
## Time Warping
|
||||||
|
|
||||||
Time is cool. But it's even cooler when you can manipulate it to your liking. Think about jumping back or forward in time. Think about looping a specific part of your current pattern or song. This is all possible thanks to two simple functions: <ic>warp(n: number)</ic> and <ic>beat_warp(n: number)</ic>. They are both very easy to use and very powerful. Let's see how they work.
|
Time generally flows from the past to the future. However, it's even cooler when you can manipulate it to your liking by jumping back and forth. Think about looping a specific part of your current pattern or song or jumping all of the sudden in the future. This is entirely possible thanks to two simple functions: <ic>warp(n: number)</ic> and <ic>beat_warp(n: number)</ic>. They are both very easy to use and very powerful. Let's see how they work.
|
||||||
|
|
||||||
- <ic>warp(n: number)</ic>: this function jumps to the _n_ tick of the clock. <ic>1</ic> is the first pulsation ever, and the number keeps increasing to the infinite.
|
- <ic>warp(n: number)</ic>: this function jumps to the _n_ tick of the clock. <ic>1</ic> is the first pulsation ever and the number keeps increasing indefinitely. You are most likely currently listening to tick n°<ic>12838123</ic>.
|
||||||
|
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Jumping back and forth in time",
|
"Time is now super elastic!",
|
||||||
`
|
`
|
||||||
// Obscure Shenanigans - Bubobubobubo
|
// Obscure Shenanigans - Bubobubobubo
|
||||||
mod([1/4,1/8,1/16].div(8)):: sound('sine')
|
beat([1/4,1/8,1/16].beat(8)):: sound('sine')
|
||||||
.freq([100,50].div(16) + 50 * ($(1)%10))
|
.freq([100,50].beat(16) + 50 * ($(1)%10))
|
||||||
.gain(0.5).room(0.9).size(0.9)
|
.gain(0.5).room(0.9).size(0.9)
|
||||||
.sustain(0.1).out()
|
.sustain(0.1).out()
|
||||||
mod(1) :: sound('kick').out()
|
beat(1) :: sound('kick').out()
|
||||||
mod(2) :: sound('dr').n(5).out()
|
beat(2) :: sound('dr').n(5).out()
|
||||||
div(3) :: mod([.25,.5].div(.5)) :: sound('dr')
|
flip(3) :: beat([.25,.5].beat(.5)) :: sound('dr')
|
||||||
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].div(.25)).out()
|
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].beat(.25)).out()
|
||||||
// Time is elastic now!
|
// Jumping back and forth in time
|
||||||
mod(.25) :: warp([12, 48, 24, 1, 120, 30].pick())
|
beat(.25) :: warp([12, 48, 24, 1, 120, 30].pick())
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -264,18 +265,18 @@ ${makeExample(
|
|||||||
"Jumping back and forth with beats",
|
"Jumping back and forth with beats",
|
||||||
`
|
`
|
||||||
// Resonance bliss - Bubobubobubo
|
// Resonance bliss - Bubobubobubo
|
||||||
mod(.25)::snd('arpy')
|
beat(.25)::snd('arpy')
|
||||||
.note(30 + [0,3,7,10].beat())
|
.note(30 + [0,3,7,10].beat())
|
||||||
.cutoff(usine(.5) * 5000).resonance(10).gain(0.3)
|
.cutoff(usine(.5) * 5000).resonance(10).gain(0.3)
|
||||||
.end(0.8).room(0.9).size(0.9).n(0).out();
|
.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())
|
.note(30 + [0,3,7,10].beat())
|
||||||
.cutoff(usine(.5) * 5000).resonance(20).gain(0.3)
|
.cutoff(usine(.5) * 5000).resonance(20).gain(0.3)
|
||||||
.end(0.8).room(0.9).size(0.9).n(3).out();
|
.end(0.8).room(0.9).size(0.9).n(3).out();
|
||||||
mod(.5) :: snd('arpy').note(
|
beat(.5) :: snd('arpy').note(
|
||||||
[30, 33, 35].repeatAll(4).div(1) - [12,0].div(0.5)).out()
|
[30, 33, 35].repeatAll(4).beat(1) - [12,0].beat(0.5)).out()
|
||||||
// Comment me to stop warping!
|
// 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
|
true
|
||||||
)}
|
)}
|
||||||
@ -284,13 +285,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**.
|
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.
|
- <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(
|
${makeExample(
|
||||||
"Two beats of silence, two beats of playing",
|
"Two beats of silence, two beats of playing",
|
||||||
`
|
`
|
||||||
div(4) :: mod(1) :: snd('kick').out()
|
flip(4) :: beat(1) :: snd('kick').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -298,9 +299,10 @@ div(4) :: mod(1) :: snd('kick').out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Clapping on the edge",
|
"Clapping on the edge",
|
||||||
`
|
`
|
||||||
div(2.5, 10) :: mod(.25) :: snd('cp').out()
|
flip(2.5, 10) :: beat(.25) :: snd('cp').out()
|
||||||
div(2.5, 75) :: mod(.25) :: snd('click').speed(2).end(0.2).out()
|
flip(2.5, 75) :: beat(.25) :: snd('click').speed(2).end(0.2).out()
|
||||||
div(2.5) :: mod(.5) :: snd('bd').out()
|
flip(2.5) :: beat(.5) :: snd('bd').out()
|
||||||
|
beat(.25) :: sound('hh').out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
@ -308,35 +310,35 @@ div(2.5) :: mod(.5) :: snd('bd').out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Good old true and false",
|
"Good old true and false",
|
||||||
`
|
`
|
||||||
if (div(4, 75)) {
|
if (flip(4, 75)) {
|
||||||
mod(1) :: snd('kick').out()
|
beat(1) :: snd('kick').out()
|
||||||
} else {
|
} else {
|
||||||
mod(.5) :: snd('snare').out()
|
beat(.5) :: snd('snare').out()
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
true
|
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. Here is a silly composition that is using <ic>flip</ic> to generate a 4 bars long pattern.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Clunky algorithmic rap music",
|
"Clunky algorithmic rap music",
|
||||||
`
|
`
|
||||||
// Rap God VS Lil Wild -- Adel Faure
|
// Rap God VS Lil Wild -- Adel Faure
|
||||||
if (div(16)) {
|
if (flip(16)) {
|
||||||
// Playing this part for two bars
|
// Playing this part for two bars
|
||||||
mod(1.5)::snd('kick').out()
|
beat(1.5)::snd('kick').out()
|
||||||
mod(2)::snd('snare').out()
|
beat(2)::snd('snare').out()
|
||||||
mod(.5)::snd('hh').out()
|
beat(.5)::snd('hh').out()
|
||||||
} else {
|
} else {
|
||||||
// Now adding some birds and tablas
|
// Now adding some birds and tablas
|
||||||
mod(1.5)::snd('kick').out()
|
beat(1.5)::snd('kick').out()
|
||||||
mod(2)::snd('snare').out()
|
beat(2)::snd('snare').out()
|
||||||
mod(.5)::snd('hh').out()
|
beat(.5)::snd('hh').out()
|
||||||
mod(.5)::snd('tabla').speed([1,2].pick()).end(0.5).out()
|
beat(.5)::snd('tabla').speed([1,2].pick()).end(0.5).out()
|
||||||
mod(2.34)::snd('birds').n(irand(1,10))
|
beat(2.34)::snd('birds').n(irand(1,10))
|
||||||
.delay(0.5).delaytime(0.5).delayfb(0.25).out()
|
.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
|
true
|
||||||
@ -345,29 +347,29 @@ if (div(16)) {
|
|||||||
You can use it everywhere to spice things up, including as a method parameter picker:
|
You can use it everywhere to spice things up, including as a method parameter picker:
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"div is great for parameter variation",
|
"flip is great for parameter variation",
|
||||||
`
|
`
|
||||||
mod(.5)::snd(div(4) ? 'kick' : 'hat').out()
|
beat(.5)::snd(flip(4) ? 'kick' : 'hat').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
- <ic>divbar(n: number)</ic>: works just like <ic>div</ic> but at the level of bars instead of beats. It allows you to think about even bigger time cycles. You can also pair it with regular <ic>div</ic> for making complex algorithmic beats.
|
- <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.
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Thinking music over bars",
|
"Thinking music over bars",
|
||||||
`
|
`
|
||||||
divbar(2)::mod(1)::snd('kick').out()
|
flipbar(2) :: beat(1):: snd('kick').out()
|
||||||
divbar(3)::mod(.5)::snd('hat').out()
|
flipbar(3) :: beat(.5):: snd('hat').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"Alternating over four bars",
|
"Alternating over four bars",
|
||||||
`
|
`
|
||||||
divbar(2)
|
flipbar(2)
|
||||||
? mod(.5) && snd(['kick', 'hh'].div(1)).out()
|
? beat(.5) && snd(['kick', 'hh'].beat(1)).out()
|
||||||
: mod(.5) && snd(['east', 'snare'].div(1)).out()
|
: beat(.5) && snd(['east', 'east:2'].beat(1)).out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)};
|
)};
|
||||||
@ -378,16 +380,21 @@ divbar(2)
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Using onbar for filler drums",
|
"Using onbar for filler drums",
|
||||||
`
|
`
|
||||||
// Only play on the fourth bar of a four bar cycle.
|
bpm(150);
|
||||||
onbar(4, 4)::mod(.5)::snd('hh').out();
|
// Only play on the third and fourth bar of the cycle.
|
||||||
|
onbar([3,4], 4)::beat(.25)::snd('hh').out();
|
||||||
// Here comes a longer version using JavaScript normal control flow
|
// Using JavaScript regular control flow
|
||||||
if (onbar([4, 1], 3)) {
|
if (onbar([1,2], 4)) {
|
||||||
mod(1)::snd('kick').out();
|
beat(.5) :: sometimes() :: sound('east').out()
|
||||||
|
rhythm(.5, 3, 7) :: snd('kick').out();
|
||||||
|
rhythm(.5, 1, 7) :: snd('jvbass').out();
|
||||||
|
rhythm(.5, 2, 7) :: snd('snare').n(5).out();
|
||||||
} else {
|
} else {
|
||||||
mod(.5)::snd('sd').out();
|
beat(.5) :: rarely() :: sound('east').n($(1)).out()
|
||||||
}
|
rhythm(.5, 3, 7) :: snd('kick').n(4).out();
|
||||||
`,
|
rhythm(.5, 1, 7) :: snd('jvbass').n(2).out();
|
||||||
|
rhythm(.5, 2, 7) :: snd('snare').n(3).out();
|
||||||
|
}`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -401,13 +408,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:
|
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>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).
|
- <ic>ppqn()</ic>: returns the current **PPQN** (see above).
|
||||||
|
|
||||||
@ -420,15 +427,22 @@ These values are **extremely useful** to craft more complex syntax or to write m
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Manual mode: using time primitives!",
|
"Manual mode: using time primitives!",
|
||||||
`
|
`
|
||||||
if((bar() % 4) > 1) {
|
// Manual time condition
|
||||||
mod(1) && sound('kick').out()
|
if((cbar() % 4) > 1) {
|
||||||
rarely() && mod(.5) && sound('sd').out()
|
beat(2) && sound('kick').out()
|
||||||
mod(.5) && sound('jvbass').freq(500).out()
|
rarely() && beat(.5) && sound('sd').out()
|
||||||
|
beat([.5, .25].beat()) && sound('jvbass')
|
||||||
|
.freq(100 * [2, 1].pick()).dec(2)
|
||||||
|
.room(0.9).size(0.9).orbit(2).out()
|
||||||
} else {
|
} else {
|
||||||
mod(.5) && sound('hh').out()
|
beat(.5) && sound('hh').out()
|
||||||
mod(.75) && sound('cp').out()
|
beat(2) && sound('cp').out()
|
||||||
mod(.5) && sound('jvbass').freq(250).out()
|
beat([.5, .5, .25].beat(.5)) && sound('jvbass')
|
||||||
|
.freq(100 * [3, 1].pick()).dec(2)
|
||||||
|
.room(0.9).size(0.9).orbit(2).out()
|
||||||
}
|
}
|
||||||
|
// This is always playing no matter what happens
|
||||||
|
beat([.5, .5, 1, .25].beat(0.5)) :: sound('shaker').out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ z1('s 0 1 2 3 4 5 6 7 8 9').sound('pluck').release(0.1).sustain(0.25).out()
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Escaped pitches using curly brackets",
|
"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();
|
pattern.sound('pluck').sustain(0.1).room(0.9).out();
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
@ -52,7 +52,7 @@ pattern.sound('pluck').sustain(0.1).room(0.9).out();
|
|||||||
${makeExample(
|
${makeExample(
|
||||||
"Durations using letters and floating point numbers",
|
"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()
|
: z1('0.125 0 0.25 2').sound('sine').scale("locrian").out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
@ -62,8 +62,8 @@ ${makeExample(
|
|||||||
"Disco was invented thanks to Ziffers",
|
"Disco was invented thanks to Ziffers",
|
||||||
`
|
`
|
||||||
z1('e _ _ 0 ^ 0 _ 0 ^ 0').sound('jvbass').out()
|
z1('e _ _ 0 ^ 0 _ 0 ^ 0').sound('jvbass').out()
|
||||||
mod(1)::snd('bd').out(); mod(2)::snd('sd').out()
|
beat(1)::snd('bd').out(); beat(2)::snd('sd').out()
|
||||||
mod(3) :: snd('cp').room(0.5).size(0.5).orbit(2).out()
|
beat(3) :: snd('cp').room(0.5).size(0.5).orbit(2).out()
|
||||||
`,
|
`,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
@ -132,7 +132,7 @@ ${makeExample(
|
|||||||
"Transposing chords",
|
"Transposing chords",
|
||||||
`
|
`
|
||||||
z1('q Fmaj Amin Dmin Cmaj Cdim')
|
z1('q Fmaj Amin Dmin Cmaj Cdim')
|
||||||
.key(["F3","E3","D3","E3"].div(3))
|
.key(["F3","E3","D3","E3"].beat(3))
|
||||||
.sound('sawtooth').out()
|
.sound('sawtooth').out()
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
@ -177,7 +177,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
|||||||
.scale('minor').fmi(2).fmh(2).room(0.5)
|
.scale('minor').fmi(2).fmh(2).room(0.5)
|
||||||
.size(0.5).sustain(0.1) .delay(0.5)
|
.size(0.5).sustain(0.1) .delay(0.5)
|
||||||
.delay(0.125).delayfb(0.25).out();
|
.delay(0.125).delayfb(0.25).out();
|
||||||
mod(.5) :: snd(['kick', 'hat'].div(.5)).out()
|
beat(.5) :: snd(['kick', 'hat'].beat(.5)).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -188,17 +188,17 @@ Ziffers supports all the keys and scales. Keys can be defined by using [scientif
|
|||||||
|
|
||||||
| Scale name | Intervals |
|
| Scale name | Intervals |
|
||||||
|------------|------------------------|
|
|------------|------------------------|
|
||||||
| Lydian | <ic>2221221</ic> |
|
| Lydian | <ic>2221221</ic> |
|
||||||
| Mixolydian | <ic>2212212</ic> |
|
| Mixolydian | <ic>2212212</ic> |
|
||||||
| Aeolian | <ic>2122122</ic> |
|
| Aeolian | <ic>2122122</ic> |
|
||||||
| Locrian | <ic>1221222</ic> |
|
| Locrian | <ic>1221222</ic> |
|
||||||
| Ionian | <ic>2212221</ic> |
|
| Ionian | <ic>2212221</ic> |
|
||||||
| Dorian | <ic>2122212</ic> |
|
| Dorian | <ic>2122212</ic> |
|
||||||
| Phrygian | <ic>1222122</ic> |
|
| Phrygian | <ic>1222122</ic> |
|
||||||
| Soryllic | <ic>11122122</ic>|
|
| Soryllic | <ic>11122122</ic>|
|
||||||
| Modimic | <ic>412122</ic> |
|
| Modimic | <ic>412122</ic> |
|
||||||
| Ionalian | <ic>1312122</ic> |
|
| Ionalian | <ic>1312122</ic> |
|
||||||
| ... | And it goes on for **1490** scales |
|
| ... | And it goes on for **1490** scales |
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
"What the hell is the Modimic scale?",
|
"What the hell is the Modimic scale?",
|
||||||
@ -207,7 +207,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
|||||||
.scale('modimic').fmi(2).fmh(2).room(0.5)
|
.scale('modimic').fmi(2).fmh(2).room(0.5)
|
||||||
.size(0.5).sustain(0.1) .delay(0.5)
|
.size(0.5).sustain(0.1) .delay(0.5)
|
||||||
.delay(0.125).delayfb(0.25).out();
|
.delay(0.125).delayfb(0.25).out();
|
||||||
mod(.5) :: snd(['kick', 'hat'].div(.5)).out()
|
beat(.5) :: snd(['kick', 'hat'].beat(.5)).out()
|
||||||
`,
|
`,
|
||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
@ -221,16 +221,16 @@ You can also use more traditional <a href="https://ianring.com/musictheory/scale
|
|||||||
|
|
||||||
| Scale name | Intervals |
|
| Scale name | Intervals |
|
||||||
|------------|------------------------|
|
|------------|------------------------|
|
||||||
| Major | <ic>2212221</ic> |
|
| Major | <ic>2212221</ic> |
|
||||||
| Minor | <ic>2122122</ic> |
|
| Minor | <ic>2122122</ic> |
|
||||||
| Minor pentatonic | <ic>32232</ic> |
|
| Minor pentatonic | <ic>32232</ic> |
|
||||||
| Harmonic minor | <ic>2122131</ic>|
|
| Harmonic minor | <ic>2122131</ic>|
|
||||||
| Harmonic major | <ic>2212131</ic>|
|
| Harmonic major | <ic>2212131</ic>|
|
||||||
| Melodic minor | <ic>2122221</ic>|
|
| Melodic minor | <ic>2122221</ic>|
|
||||||
| Melodic major | <ic>2212122</ic>|
|
| Melodic major | <ic>2212122</ic>|
|
||||||
| Whole | <ic>222222</ic> |
|
| Whole | <ic>222222</ic> |
|
||||||
| Blues minor | <ic>321132</ic> |
|
| Blues minor | <ic>321132</ic> |
|
||||||
| Blues major | <ic>211323</ic> |
|
| Blues major | <ic>211323</ic> |
|
||||||
|
|
||||||
|
|
||||||
${makeExample(
|
${makeExample(
|
||||||
@ -240,7 +240,7 @@ z1("s (0,8) 0 0 (0,5) 0 0").sound('sine')
|
|||||||
.scale('blues minor').fmi(2).fmh(2).room(0.5)
|
.scale('blues minor').fmi(2).fmh(2).room(0.5)
|
||||||
.size(0.5).sustain(0.25).delay(0.25)
|
.size(0.5).sustain(0.25).delay(0.25)
|
||||||
.delay(0.25).delayfb(0.5).out();
|
.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
|
true
|
||||||
)}
|
)}
|
||||||
@ -258,7 +258,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)
|
.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)
|
.size(0.5).sustain(0.15).delay(0.1)
|
||||||
.delay(0.25).delayfb(0.5).out();
|
.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
|
true
|
||||||
)}
|
)}
|
||||||
@ -296,9 +296,6 @@ ${makeExample(
|
|||||||
true
|
true
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
- Basic notation
|
- Basic notation
|
||||||
|
|||||||
@ -1,47 +1,76 @@
|
|||||||
export const examples = [
|
export const examples = [
|
||||||
|
`// Entering the secret room - Bubobubobubo
|
||||||
|
let frequencies = [200,400,600,800,1000,2000].beat(2);
|
||||||
|
beat(2) :: sound('sine').freq(frequencies)
|
||||||
|
.delay(0.5).delayt(usine(.5)).delayfb(0.8).size(0.9).room(0.9).out()
|
||||||
|
beat(2) :: app.hydra.osc(frequencies/100, 0.25, 0.5)
|
||||||
|
.posterize([32,4,8,16].beat(2)).rotate(cpulse())
|
||||||
|
.kaleid([1,2,3].beat()).out()`,
|
||||||
|
`// The real internet of things - Bubobubobubo
|
||||||
|
beat(.5) :: sound('STA6').cut(1).vel(0.4)
|
||||||
|
.orbit(2).room(0.5).size(0.5).n(irand(1,4))
|
||||||
|
.speed([0.15, 0.30].beat()).out()
|
||||||
|
binrhythm(.5, 50) :: sound('shaker').out()
|
||||||
|
binrhythm(.5, 52) :: sound('808bd').n(3).out()
|
||||||
|
rhythm(.25, 6, 8) :: sound('808sd').out()`,
|
||||||
|
`// Numerology - Bubobubobubo
|
||||||
|
let mel = [
|
||||||
|
"0.125 _ (0 3 7 0 3 5 0 3 9)+(0 2)", "0.125 (0 7 0 10 0 5)+(0 3)",
|
||||||
|
"0.125 (0 3 7 0 3 5 0 3 9)+(0 2)", "0.125 (0 2 4 5 9 10)+(0 2)",
|
||||||
|
].beat(4);
|
||||||
|
z0(mel)
|
||||||
|
.scale('minor').sound('square').cutoff(800 + usine(.5) * 5000)
|
||||||
|
.fmi([2, 4, 8].beat(2)).fmh(flip(2) ? 2 : 4)
|
||||||
|
.delay(bpm() / 60 / 9).delayt(0.25).delayfb(0.5)
|
||||||
|
.fmsus(0.3).fmrel(0.3).rel(rand(0.5,0.8))
|
||||||
|
.sus(rand(0.05, 0.1)).out();
|
||||||
|
beat(1) :: sound(flip(2) ? 'kick' : ['sd', 'cp'].beat(3)).out();
|
||||||
|
beat([.25, .5].beat(4)) :: flip(6) && sound('dr')
|
||||||
|
.room(0.85).size(0.85).vel($(1) % 10 / 8)
|
||||||
|
.n([1, 2, 7].pick()).out();`,
|
||||||
`// Harmonic Leaps and Gaps -- Bubobubobubo
|
`// Harmonic Leaps and Gaps -- Bubobubobubo
|
||||||
let oscillation = quant(usine(.25) * 20, [35, 40, 38, 50, 55]);
|
let oscillation = quant(usine(.25) * 20, [35, 40, 38, 50, 55]);
|
||||||
let tonal = [0, 5, 0, 0, 7].palindrome().bar() + 40 - 24;
|
let tonal = [0, 5, 0, 0, 7].palindrome().bar() + 40 - 24;
|
||||||
[tonal, tonal + 7, tonal + [12,3].bar()].forEach((e) => {
|
[tonal, tonal + 7, tonal + [12,3].bar()].forEach((e) => {
|
||||||
div(2) :: mod(.5) :: sound('square').fmi(2)
|
flip(2) :: beat(.5) :: sound('square').fmi(2)
|
||||||
.cutoff(500 + usine(1/2)).n(irand(1,10))
|
.cutoff(500 + usine(1/2)).n(irand(1,10))
|
||||||
.note(e + oscillation + [0, 5].div(.5)).out()
|
.note(e + oscillation + [0, 5].beat(.5)).out()
|
||||||
!div(2) :: mod(.5) :: sound('sawtooth').fmi(2)
|
!flip(2) :: beat(.5) :: sound('sawtooth').fmi(2)
|
||||||
.cutoff(500 + usine(1/2) * 5000).n(irand(1,10))
|
.cutoff(500 + usine(1/2) * 5000).n(irand(1,10))
|
||||||
.note(e + oscillation + [0, 5].div(.5)).out()
|
.note(e + oscillation + [0, 5].beat(.5)).out()
|
||||||
});
|
});
|
||||||
oncount([2, 3.5, [5,0].pick()], 6) :: sound('snare').out()
|
oncount([2, 3.5, [5,0].pick()], 6) :: sound('snare').out()
|
||||||
`,
|
`,
|
||||||
`// Computer Music Classroom, Monday (8AM) -- Bubobubobubo
|
`// Computer Music Classroom, Monday (8AM) -- Bubobubobubo
|
||||||
let ur = [0, 12, 7].div(24),
|
let ur = [0, 12, 7].beat(24),
|
||||||
fundamental = [0, 5, 10, 8, 6].repeatAll(4).bar();
|
fundamental = [0, 5, 10, 8, 6].repeatAll(4).bar();
|
||||||
mod(.25) :: sound('square')
|
beat(.25) :: sound('square')
|
||||||
.note(ur + fundamental + 40).n(1 + $(1) % 8)
|
.note(ur + fundamental + 40).n(1 + $(1) % 8)
|
||||||
.atk(0.05).sustain(0.1).release(0.1)
|
.atk(0.05).sustain(0.1).release(0.1)
|
||||||
.room(0.9).size(0.9)
|
.room(0.9).size(0.9)
|
||||||
.out()
|
.out()
|
||||||
mod(.25) :: sound('sawtooth')
|
beat(.25) :: sound('sawtooth')
|
||||||
.note(ur + fundamental + 47).n(1 + $(2) % 8)
|
.note(ur + fundamental + 47).n(1 + $(2) % 8)
|
||||||
.atk(0.05).sustain(0.1).release(0.1)
|
.atk(0.05).sustain(0.1).release(0.1)
|
||||||
.room(0.9).size(0.9)
|
.room(0.9).size(0.9)
|
||||||
.out()
|
.out()
|
||||||
mod(.25) :: sound(['sawtooth', 'square'].bar())
|
beat(.25) :: sound(['sawtooth', 'square'].bar())
|
||||||
.note(ur + fundamental + 40+[10,12].bar()).n(1 + $(3) % 8)
|
.note(ur + fundamental + 40+[10,12].bar()).n(1 + $(3) % 8)
|
||||||
.atk(0.05).sustain(0.1).release(0.1)
|
.atk(0.05).sustain(0.1).release(0.1)
|
||||||
.room(0.9).size(0.9).out()
|
.room(0.9).size(0.9).out()
|
||||||
`,
|
`,
|
||||||
`// Lamento for Digital Harpists -- Bubobubobubo
|
`// Lamento for Digital Harpists -- Bubobubobubo
|
||||||
mod(4) :: sound('triangle')
|
beat(4) :: sound('triangle')
|
||||||
.note(60).fmwave('triangle').fmi(3.95)
|
.note(60).fmwave('triangle').fmi(3.95)
|
||||||
.fmh(0.25).release(1.5).sustain(0.5)
|
.fmh(0.25).release(1.5).sustain(0.5)
|
||||||
.decay(1.125).vel(0.35).room(1.5)
|
.decay(1.125).vel(0.35).room(1.5)
|
||||||
.size(1.9).out()
|
.size(1.9).out()
|
||||||
mod([.5,.25].div(1)) :: sound('triangle')
|
beat([.5,.25].beat(1)) :: sound('triangle')
|
||||||
.note([67,72,75,77,79].shuffle().div(.25) - [12, 24].pick())
|
.note([67,72,75,77,79].shuffle().beat(.25) - [12, 24].pick())
|
||||||
.fmwave('triangle').fmi(3.99).fmh([1.001].pick() + usine() / 100)
|
.fmwave('triangle').fmi(3.99).fmh([1.001].pick() + usine() / 100)
|
||||||
.release(.125).sustain(0.125)
|
.release(.125).sustain(0.125)
|
||||||
.room(1.5).size(1.9).out()
|
.room(1.5).size(1.9).out()
|
||||||
mod([4, 2, 8].pick() / [2,1].bar()) :: sound('triangle')
|
beat([4, 2, 8].pick() / [2,1].bar()) :: sound('triangle')
|
||||||
.note([67,72,75,77,79].shuffle().loop($('lezgo')))
|
.note([67,72,75,77,79].shuffle().loop($('lezgo')))
|
||||||
.fmwave('triangle').fmi(3.99).fmh([1.001].pick() + usine() / 100)
|
.fmwave('triangle').fmi(3.99).fmh([1.001].pick() + usine() / 100)
|
||||||
.release(2).sustain(0.125).gain(1.5)
|
.release(2).sustain(0.125).gain(1.5)
|
||||||
@ -50,35 +79,35 @@ mod([4, 2, 8].pick() / [2,1].bar()) :: sound('triangle')
|
|||||||
`,
|
`,
|
||||||
`// Super gentle computing - Bubobubobubo
|
`// Super gentle computing - Bubobubobubo
|
||||||
let melody = [30,30,34,35,37].palindrome()
|
let melody = [30,30,34,35,37].palindrome()
|
||||||
.beat() + [0, -12].repeatAll(2).div(2)
|
.beat() + [0, -12].repeatAll(2).beat(2)
|
||||||
if (div(8, 75)) {
|
if (flip(8, 75)) {
|
||||||
log('first section')
|
log('first section')
|
||||||
rhythm(.5, 4, 8) :: sound('ST12').n([0,1,2].div(0.5)).speed(0.5).out()
|
rhythm(.5, 4, 8) :: sound('ST12').n([0,1,2].beat(0.5)).speed(0.5).out()
|
||||||
rhythm(.5, 6, 8) :: sound('ST20').n([0,1,2].div(0.5) + 20)
|
rhythm(.5, 6, 8) :: sound('ST20').n([0,1,2].beat(0.5) + 20)
|
||||||
.speed(0.25).end(0.1).orbit(2).room(0.5).size(0.5).out()
|
.speed(0.25).end(0.1).orbit(2).room(0.5).size(0.5).out()
|
||||||
mod(.5) :: sound('ST01').note(melody)
|
beat(.5) :: sound('ST01').note(melody)
|
||||||
.n($(1)).speed(0.5).room(0.5).size(0.5).out()
|
.n($(1)).speed(0.5).room(0.5).size(0.5).out()
|
||||||
} else {
|
} else {
|
||||||
log('second section')
|
log('second section')
|
||||||
rhythm(.5, 2, 8) :: sound('ST20')
|
rhythm(.5, 2, 8) :: sound('ST20')
|
||||||
.n([0,1,2].div(0.5)).speed(0.5)
|
.n([0,1,2].beat(0.5)).speed(0.5)
|
||||||
.end(0.1).out()
|
.end(0.1).out()
|
||||||
mod(.5) :: sound('ST01').note(melody).n($(1)).speed(0.5).end(0.1).out()
|
beat(.5) :: sound('ST01').note(melody).n($(1)).speed(0.5).end(0.1).out()
|
||||||
mod(1) :: sound('ST02').note(melody).n($(1)).speed(0.5).end(0.1).out()
|
beat(1) :: sound('ST02').note(melody).n($(1)).speed(0.5).end(0.1).out()
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
`// Race day - Bubobubobubo
|
`// Race day - Bubobubobubo
|
||||||
bpm(125);
|
bpm(125);
|
||||||
mod(.5) :: sound('STB6')
|
beat(.5) :: sound('STB6')
|
||||||
.n(irand(1,10)).speed(0.5).rel(1)
|
.n(irand(1,10)).speed(0.5).rel(1)
|
||||||
.sus(0.1).out()
|
.sus(0.1).out()
|
||||||
rhythm(div(4) ? 1 : .5, 5, 8) :: sound('kick').out()
|
rhythm(flip(4) ? 1 : .5, 5, 8) :: sound('kick').out()
|
||||||
rhythm(div(2) ? .5 : .25, 7, 8) :: sound('click')
|
rhythm(flip(2) ? .5 : .25, 7, 8) :: sound('click')
|
||||||
.vel(0.1 + utriangle(.25)).n(irand(1,5)).out()
|
.vel(0.1 + utriangle(.25)).n(irand(1,5)).out()
|
||||||
rhythm(.5, 2, 8) :: sound('snare').out()
|
rhythm(.5, 2, 8) :: sound('snare').out()
|
||||||
`,
|
`,
|
||||||
`// Structure et approximation - Bubobubobubo
|
`// Structure et approximation - Bubobubobubo
|
||||||
mod(.25) :: sound('zzfx').zzfx(
|
beat(.25) :: sound('zzfx').zzfx(
|
||||||
// Randomized chaos :)
|
// Randomized chaos :)
|
||||||
[
|
[
|
||||||
rand(1,5),,rand(500,1000),rand(.01, 0.02),,
|
rand(1,5),,rand(500,1000),rand(.01, 0.02),,
|
||||||
@ -89,91 +118,91 @@ mod(.25) :: sound('zzfx').zzfx(
|
|||||||
.vel(0.1).gain(toss() ? .5 : .125)
|
.vel(0.1).gain(toss() ? .5 : .125)
|
||||||
.delay(toss() ? 0.5 : 0).delayt(0.045).delayfb(0.1).out()
|
.delay(toss() ? 0.5 : 0).delayt(0.045).delayfb(0.1).out()
|
||||||
rhythm(.5, toss() ? 5 : 7, 12) :: sound('kick').n(13).out()
|
rhythm(.5, toss() ? 5 : 7, 12) :: sound('kick').n(13).out()
|
||||||
rhythm(toss() ? .25 : .5, div(2) ? 3 : 5, 12) :: sound(
|
rhythm(toss() ? .25 : .5, flip(2) ? 3 : 5, 12) :: sound(
|
||||||
toss() ? 'snare' : 'cp').n(5).out()
|
toss() ? 'snare' : 'cp').n(5).out()
|
||||||
rhythm(div(2) ? .5 : .25, div(4) ? 8 : 11, 12) :: sound('hat')
|
rhythm(flip(2) ? .5 : .25, flip(4) ? 8 : 11, 12) :: sound('hat')
|
||||||
.orbit(3).room(0.5).size(0.5).n(0).out()
|
.orbit(3).room(0.5).size(0.5).n(0).out()
|
||||||
`,
|
`,
|
||||||
`// Part-Dieu - Bubobubobubo
|
`// Part-Dieu - Bubobubobubo
|
||||||
bpm(90);
|
bpm(90);
|
||||||
mod(rarely(12) ? .5 : .25) :: sound('ST22')
|
beat(rarely(12) ? .5 : .25) :: sound('ST22')
|
||||||
.note([30, 30, 30, 31].repeatAll(8).div(.5))
|
.note([30, 30, 30, 31].repeatAll(8).beat(.5))
|
||||||
.cut(1).n([19, 21].div(.75))
|
.cut(1).n([19, 21].beat(.75))
|
||||||
.cutoff(irand(200, 5000))
|
.cutoff(irand(200, 5000))
|
||||||
.resonance(rand(0.2,0.8))
|
.resonance(rand(0.2,0.8))
|
||||||
.room(0.9).size(1).orbit(2)
|
.room(0.9).size(1).orbit(2)
|
||||||
.speed(0.25).vel(0.3).end(0.5)
|
.speed(0.25).vel(0.3).end(0.5)
|
||||||
.out()
|
.out()
|
||||||
mod(.5) :: snd('dr')
|
beat(.5) :: snd('dr')
|
||||||
.n([0, 0, 0, 0, 2, 8].beat())
|
.n([0, 0, 0, 0, 2, 8].beat())
|
||||||
.gain(1).out()
|
.gain(1).out()
|
||||||
mod(div(2) ? 1 : 0.75) :: snd('bd').n(2).out()
|
beat(flip(2) ? 1 : 0.75) :: snd('bd').n(2).out()
|
||||||
mod(4) :: snd('snare').n(5)
|
beat(4) :: snd('snare').n(5)
|
||||||
.delay(0.5).delayt(bpm() / 60 / 8)
|
.delay(0.5).delayt(bpm() / 60 / 8)
|
||||||
.delayfb(0.25).out()
|
.delayfb(0.25).out()
|
||||||
`,
|
`,
|
||||||
`// Atarism - Bubobubobubo
|
`// Atarism - Bubobubobubo
|
||||||
bpm(85);
|
bpm(85);
|
||||||
let modifier = [.5, 1, 2].div(8);
|
let modifier = [.5, 1, 2].beat(8);
|
||||||
let othermod = [1, .5, 4].div(4);
|
let othermod = [1, .5, 4].beat(4);
|
||||||
mod(modifier / 2):: sound('STA9').n([0,2].div(.5)).speed(0.5).vel(0.5).out()
|
beat(modifier / 2):: sound('STA9').n([0,2].beat(.5)).speed(0.5).vel(0.5).out()
|
||||||
mod(.5)::sound('STA9').n([0, 20].div(.5)).speed([1,1.5].repeatAll(4).beat() / 4)
|
beat(.5)::sound('STA9').n([0, 20].beat(.5)).speed([1,1.5].repeatAll(4).beat() / 4)
|
||||||
.cutoff(500 + usine(.25) * 3000).vel(0.5).out()
|
.cutoff(500 + usine(.25) * 3000).vel(0.5).out()
|
||||||
mod(modifier / 2):: sound('STA9')
|
beat(modifier / 2):: sound('STA9')
|
||||||
.n([0,7].div(.5)).speed(div(othermod) ? 2 :4).vel(0.45).out()
|
.n([0,7].beat(.5)).speed(flip(othermod) ? 2 :4).vel(0.45).out()
|
||||||
rhythm(.25, 3, 8, 1) :: sound('STA9')
|
rhythm(.25, 3, 8, 1) :: sound('STA9')
|
||||||
.note([30, 33].pick()).n(32).speed(0.5).out()
|
.note([30, 33].pick()).n(32).speed(0.5).out()
|
||||||
rhythm(othermod, 5, 8) :: sound('dr').n([0,1,2].beat()).out()
|
rhythm(othermod, 5, 8) :: sound('dr').n([0,1,2].beat()).out()
|
||||||
mod(1) :: sound('kick').vel(1).out()
|
beat(1) :: sound('kick').vel(1).out()
|
||||||
`,
|
`,
|
||||||
`// Ancient rhythms - Bubobubobubo
|
`// Ancient rhythms - Bubobubobubo
|
||||||
mod(1)::snd('kick').out();
|
beat(1) :: snd('kick').out();
|
||||||
mod(2)::snd('sd').room(0.9).size(0.9).out();
|
beat(2) :: snd('sd').room(0.9).size(0.9).out();
|
||||||
mod(0.25)::snd('hh').out();
|
beat(0.25) :: snd('hh').out();
|
||||||
mod(2)::snd('square')
|
beat(2) :: snd('square')
|
||||||
.cutoff(500).note(50-12).resonance(20).sustain(0.2).out()
|
.cutoff(500).note(50-12).resonance(20).sustain(0.2).out()
|
||||||
mod(1/4)::snd(divseq(1, 'sawtooth', 'triangle', 'square'))
|
beat(1/4)::snd(['sawtooth', 'triangle', 'square'].beat(1))
|
||||||
.note(divseq(4, 50, 53, 55, 50, 50, 52, 58, 50+12, 50+15) + divseq(0.5, 0, 12, 24))
|
.note([50, 53, 55, 50, 50, 52, 58, 50+12, 50+15].beat(4) + [0, 12, 24].beat(0.5))
|
||||||
.cutoff(usine(.5)*10000).resonance(divseq(2, 10,20))
|
.cutoff(usine(.5)*10000).resonance([10,20].beat(2))
|
||||||
.fmi($(1) % 10).fmh($(2) % 5)
|
.fmi($(1) % 10).fmh($(2) % 5)
|
||||||
.room(0.8).size(0.9)
|
.room(0.8).size(0.9)
|
||||||
.delay(0.5).delaytime(0.25)
|
.delay(0.5).delaytime(0.25)
|
||||||
.delayfb(0.6)
|
.delayfb(0.6)
|
||||||
.sustain(0.01 + usine(.25) / 10).out()
|
.sustain(0.01 + usine(.25) / 10).out()
|
||||||
mod(4)::snd('amencutup').n($(19)).cut(1).orbit(2).pan(rand(0.0,1.0)).out()`,
|
beat(4)::snd('amencutup').n($(19)).cut(1).orbit(2).pan(rand(0.0,1.0)).out()`,
|
||||||
`// Crazy arpeggios - Bubobubobubo
|
`// Crazy arpeggios - Bubobubobubo
|
||||||
bpm(110)
|
bpm(110)
|
||||||
mod(0.125) && sound('sawtooth')
|
beat(0.125) && sound('sawtooth')
|
||||||
.note([60, 62, 63, 67, 70].div(.125) +
|
.note([60, 62, 63, 67, 70].beat(.125) +
|
||||||
[-12,0,12].beat() + [0, 0, 5, 7].bar())
|
[-12,0,12].beat() + [0, 0, 5, 7].bar())
|
||||||
.sustain(0.1).fmi(0.25).fmh(2).room(0.9)
|
.sustain(0.1).fmi(0.25).fmh(2).room(0.9)
|
||||||
.gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar())
|
.gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar())
|
||||||
.delay(0.5).delayt(0.25).delayfb(0.25)
|
.delay(0.5).delayt(0.25).delayfb(0.25)
|
||||||
.out();
|
.out();
|
||||||
mod(1) && snd('kick').out();
|
beat(1) && snd('kick').out();
|
||||||
mod(2) && snd('snare').out();
|
beat(2) && snd('snare').out();
|
||||||
mod(.5) && snd('hat').out();
|
beat(.5) && snd('hat').out();
|
||||||
`,
|
`,
|
||||||
`// Obscure Shenanigans - Bubobubobubo
|
`// Obscure Shenanigans - Bubobubobubo
|
||||||
mod([1/4,1/8,1/16].div(8)):: sound('sine')
|
beat([1/4,1/8,1/16].beat(8)):: sound('sine')
|
||||||
.freq([100,50].div(16) + 50 * ($(1)%10))
|
.freq([100,50].beat(16) + 50 * ($(1)%10))
|
||||||
.gain(0.5).room(0.9).size(0.9)
|
.gain(0.5).room(0.9).size(0.9)
|
||||||
.sustain(0.1).out()
|
.sustain(0.1).out()
|
||||||
mod(1) :: sound('kick').out()
|
beat(1) :: sound('kick').out()
|
||||||
mod(2) :: sound('dr').n(5).out()
|
beat(2) :: sound('dr').n(5).out()
|
||||||
div(3) :: mod([.25,.5].div(.5)) :: sound('dr')
|
flip(3) :: beat([.25,.5].beat(.5)) :: sound('dr')
|
||||||
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].div(.25)).out()
|
.n([8,9].pick()).gain([.8,.5,.25,.1,.0].beat(.25)).out()
|
||||||
`,
|
`,
|
||||||
`// Resonance bliss - Bubobubobubo
|
`// Resonance bliss - Bubobubobubo
|
||||||
mod(.25)::snd('arpy')
|
beat(.25)::snd('arpy')
|
||||||
.note(30 + [0,3,7,10].beat())
|
.note(30 + [0,3,7,10].beat())
|
||||||
.cutoff(usine(.5) * 5000).resonance(10).gain(0.3)
|
.cutoff(usine(.5) * 5000).resonance(10).gain(0.3)
|
||||||
.end(0.8).room(0.9).size(0.9).n(0).out();
|
.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())
|
.note(30 + [0,3,7,10].beat())
|
||||||
.cutoff(usine(.5) * 5000).resonance(20).gain(0.3)
|
.cutoff(usine(.5) * 5000).resonance(20).gain(0.3)
|
||||||
.end(0.8).room(0.9).size(0.9).n(3).out();
|
.end(0.8).room(0.9).size(0.9).n(3).out();
|
||||||
mod(.5) :: snd('arpy').note(
|
beat(.5) :: snd('arpy').note(
|
||||||
[30, 33, 35].repeatAll(4).div(1) - [12,0].div(0.5)).out()
|
[30, 33, 35].repeatAll(4).beat(1) - [12,0].beat(0.5)).out()
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,13 +1,25 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from "vite";
|
||||||
// import * as mdPlugin from 'vite-plugin-markdown';
|
// import * as mdPlugin from 'vite-plugin-markdown';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig(({ command, mode, ssrBuild }) => {
|
||||||
assetsInclude: ['**/*.md'],
|
if (command === "serve") {
|
||||||
// plugins: [mdPlugin(options)],
|
return {
|
||||||
build: {
|
assetsInclude: ["**/*.md"],
|
||||||
chunkSizeWarningLimit: 1600
|
server: {
|
||||||
},
|
port: 8000,
|
||||||
preview: {
|
strictPort: true,
|
||||||
open: true
|
},
|
||||||
}
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
chunkSizeWarningLimit: 1600 * 2,
|
||||||
|
build: {
|
||||||
|
outDir: "dist",
|
||||||
|
emptyOutDir: true,
|
||||||
|
cssCodeSplit: true,
|
||||||
|
cssMinify: true,
|
||||||
|
minify: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user