diff --git a/src/API.ts b/src/API.ts
index e6392d7..ae722e2 100644
--- a/src/API.ts
+++ b/src/API.ts
@@ -1090,20 +1090,30 @@ export class UserAPI {
return (this.triangle(freq, offset) + 1) / 2;
};
- square = (freq: number = 1, offset: number = 0): number => {
+ square = (
+ freq: number = 1,
+ offset: number = 0,
+ duty: number = 0.5
+ ): number => {
/**
- * Returns a square wave between -1 and 1.
+ * Returns a square wave with a specified duty cycle between -1 and 1.
*
- * @returns A square wave between -1 and 1
+ * @returns A square wave with a specified duty cycle between -1 and 1
* @see saw
* @see triangle
* @see sine
* @see noise
*/
- return this.saw(freq, offset) > 0 ? 1 : -1;
+ const period = 1 / freq;
+ const t = (Date.now() / 1000 + offset) % period;
+ return t / period < dutyCycle ? 1 : -1;
};
- usquare = (freq: number = 1, offset: number = 0): number => {
+ usquare = (
+ freq: number = 1,
+ offset: number = 0,
+ duty: number = 0.5
+ ): number => {
/**
* Returns a square wave between 0 and 1.
*
@@ -1112,7 +1122,7 @@ export class UserAPI {
* @returns A square wave between 0 and 1
* @see square
*/
- return (this.square(freq, offset) + 1) / 2;
+ return (this.square(freq, offset, duty) + 1) / 2;
};
noise = (): number => {
diff --git a/src/Documentation.ts b/src/Documentation.ts
index d5197ee..8dbe00f 100644
--- a/src/Documentation.ts
+++ b/src/Documentation.ts
@@ -405,6 +405,44 @@ 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).
+## Low Frequency Oscillators
+
+Low Frequency Oscillators (_LFOs_) are an important piece in any digital audio workstation or synthesizer. Topos implements some basic waveforms you can play with to automatically modulate your paremeters.
+
+- sine(freq: number = 1, offset: number= 0): number: returns a sinusoïdal oscillation between -1 and 1.
+- usine(freq: number = 1, offset: number= 0): number: returns a sinusoïdal oscillation between 0 and 1. The u stands for _unipolar_.
+
+\`\`\`javascript
+ mod(.25) && snd('cp').speed(1 + usine(0.25) * 2).out()
+\`\`\`
+
+- triangle(freq: number = 1, offset: number= 0): number: returns a triangle oscillation between -1 and 1.
+- utriangle(freq: number = 1, offset: number= 0): number: returns a triangle oscillation between 0 and 1. The u stands for _unipolar_.
+
+\`\`\`javascript
+ mod(.25) && snd('cp').speed(1 + utriangle(0.25) * 2).out()
+\`\`\`
+
+- saw(freq: number = 1, offset: number= 0): number: returns a sawtooth-like oscillation between -1 and 1.
+- usaw(freq: number = 1, offset: number= 0): number: returns a sawtooth-like oscillation between 0 and 1. The u stands for _unipolar_.
+
+\`\`\`javascript
+ mod(.25) && snd('cp').speed(1 + usaw(0.25) * 2).out()
+\`\`\`
+
+- square(freq: number = 1, offset: number= 0, duty: number = .5): number: returns a square wave oscillation between -1 and 1. You can also control the duty cycle using the duty parameter.
+- usquare(freq: number = 1, offset: number= 0, duty: number = .5): number: returns a square wave oscillation between 0 and 1. The u stands for _unipolar_. You can also control the duty cycle using the duty parameter.
+
+\`\`\`javascript
+ mod(.25) && snd('cp').speed(1 + usquare(0.25, 0, 0.25) * 2).out()
+\`\`\`
+
+- noise(): returns a random value between -1 and 1.
+
+\`\`\`javascript
+ mod(.25) && snd('cp').speed(1 + noise() * 2).out()
+\`\`\`
+
## Probabilities
There are some simple functions to play with probabilities.