diff --git a/package.json b/package.json index 3278cc9..a171265 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "postcss": "^8.4.27", "showdown": "^2.1.0", "showdown-highlight": "^3.1.0", - "superdough": "^0.9.3", + "superdough": "^0.9.5", "tailwind-highlightjs": "^2.0.1", "tailwindcss": "^3.3.3", "tone": "^14.8.49", diff --git a/src/API.ts b/src/API.ts index 7888485..e6392d7 100644 --- a/src/API.ts +++ b/src/API.ts @@ -842,7 +842,7 @@ export class UserAPI { return Math.random() > 0.5; }; - min = (...values: number[]): number => { + public min = (...values: number[]): number => { /** * Returns the minimum value of a list of numbers. * @@ -852,7 +852,7 @@ export class UserAPI { return Math.min(...values); }; - max = (...values: number[]): number => { + public max = (...values: number[]): number => { /** * Returns the maximum value of a list of numbers. * @@ -862,6 +862,20 @@ export class UserAPI { return Math.max(...values); }; + public mean = (...values: number[]): number => { + /** + * Returns the mean of a list of numbers. + * + * @param values - The list of numbers + * @returns The mean value of the list of numbers + */ + const sum = values.reduce( + (accumulator, currentValue) => accumulator + currentValue, + 0 + ); + return sum / values.length; + }; + limit = (value: number, min: number, max: number): number => { /** * Limits a value between a minimum and a maximum. diff --git a/src/Documentation.ts b/src/Documentation.ts index 0948845..d5197ee 100644 --- a/src/Documentation.ts +++ b/src/Documentation.ts @@ -98,7 +98,6 @@ To make a beat, you need a certain number of time grains or **pulses**. The **pu **Note:** the ppqn(number) function can serve both for getting and setting the **PPQN** value. - ## Time Primitives Every script can access the current time by using the following functions: @@ -142,6 +141,25 @@ Some functions can be leveraged to play rhythms without thinking too much about - onbar(...values: number[]): returns true if the bar is currently equal to any of the specified values. - modbar(...values: number[]): returns true if the bar is currently a multiple of any of the specified values. +## Rhythm generators + +We included a bunch of popular rhythm generators in Topos such as the euclidian rhythms algorithms or the one to generate rhythms based on a binary sequence. They all work using _iterators_ that you will gradually learn to use for iterating over lists. + +- euclid(iterator: number, pulses: number, length: number, rotate: number): boolean: generates true or false values from an euclidian rhythm sequence. This algorithm is very popular in the electronic music making world. + +\`\`\`javascript + mod(.5) && euclid($(1), 5, 8) && snd('kick').out() + mod(.5) && euclid($(2), 2, 8) && snd('sd').out() +\`\`\` + +- bin(iterator: number, n: number): boolean: a binary rhythm generator. It transforms the given number into its binary representation (_e.g_ 34 becomes 100010). It then returns a boolean value based on the iterator in order to generate a rhythm. + + +\`\`\`javascript + mod(.5) && euclid($(1), 34) && snd('kick').out() + mod(.5) && euclid($(2), 48) && snd('sd').out() +\`\`\` + ## Using time as a conditional You can use the time functions as conditionals. The following example will play a pattern A for 2 bars and a pattern B for 2 bars: @@ -387,6 +405,25 @@ You can get the current position of the mouse on the screen by using the followi - mouseX(): the horizontal position of the mouse on the screen (as a floating point number). - mouseY(): the vertical position of the mouse on the screen (as a floating point number). +## Probabilities + +There are some simple functions to play with probabilities. + +- prob(p: number): return true _p_% of time, false in other cases. +- toss(): throwing a coin. Head (true) or tails (false). + +## Math functions + +- max(...values: number[]): number: returns the maximum value of a list of numbers. +- min(...values: number[]): number: returns the minimum value of a list of numbers. +- mean(...values: number[]): number: returns the arithmetic mean of a list of numbers. +- limit(value: number, min: number, max: number): number: Limits a value between a minimum and a maximum. + +## Delay functions + +- delay(ms: number, func: Function): void: Delays the execution of a function by a given number of milliseconds. +- delayr(ms: number, nb: number, func: Function): void: Delays the execution of a function by a given number of milliseconds, repeated a given number of times. + `; diff --git a/src/Sound.ts b/src/Sound.ts index bbec16a..2531e86 100644 --- a/src/Sound.ts +++ b/src/Sound.ts @@ -12,6 +12,30 @@ export class Sound { this.values = { s: sound, dur: 0.5 }; } + attack = (value: number): this => { + this.values["attack"] = value; + return this; + }; + atk = this.attack; + + decay = (value: number): this => { + this.values["decay"] = value; + return this; + }; + dec = this.decay; + + sustain = (value: number): this => { + this.values["sustain"] = value; + return this; + }; + sus = this.sustain; + + release = (value: number): this => { + this.values["release"] = value; + return this; + }; + rel = this.release; + unit = (value: number): this => { this.values["unit"] = value; return this; diff --git a/yarn.lock b/yarn.lock index 1c15dce..2b928fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,10 +1267,10 @@ sucrase@^3.32.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" -superdough@^0.9.3: - version "0.9.4" - resolved "https://registry.yarnpkg.com/superdough/-/superdough-0.9.4.tgz#cfae0bc6dfe5976ea0abb423a9cf2b3670944b86" - integrity sha512-1wOJbnm5e/9tn9TzYuhzlxhrXPJ3m6sY21tf+nNnU9JXA0ZUAGbGyHDWTT8R/cEtKziFAmgVxdwGBFOAxgTWdw== +superdough@^0.9.5: + version "0.9.5" + resolved "https://registry.yarnpkg.com/superdough/-/superdough-0.9.5.tgz#316b9fa9699cf1b86285e65c4084c4e2ea4489dd" + integrity sha512-PcEzWaD9oQ6apDCLmQq9OtyiAVB+Ell4U3RsYTR48L6jTssZILfYEG8pzHVf06QHeCl0rhl3/QlgO5Vf9HKMkg== dependencies: nanostores "^0.8.1"