@thi.ng/dsp 4.6.16 → 4.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +1 -1
  3. package/add.js +24 -38
  4. package/addg.js +4 -19
  5. package/adsr.js +148 -156
  6. package/agen.js +17 -21
  7. package/allpass.js +37 -38
  8. package/alt.js +26 -22
  9. package/anti-alias.js +8 -37
  10. package/api.js +0 -1
  11. package/aproc.js +24 -30
  12. package/biquad.js +188 -184
  13. package/bounce.js +15 -16
  14. package/complex.js +4 -1
  15. package/const.js +12 -13
  16. package/convert.js +18 -64
  17. package/cosine.js +43 -48
  18. package/curve.js +12 -41
  19. package/dcblock.js +9 -10
  20. package/delay.js +100 -111
  21. package/feedback-delay.js +23 -30
  22. package/fft.js +188 -334
  23. package/filter-delay.js +23 -27
  24. package/filter-response.js +22 -33
  25. package/foldback.js +26 -35
  26. package/impulse-train.js +35 -37
  27. package/impulse.js +27 -42
  28. package/integrator.js +27 -32
  29. package/internal/ensure.js +4 -1
  30. package/internal/take.js +8 -5
  31. package/iterable.js +32 -43
  32. package/line.js +10 -25
  33. package/madd.js +25 -40
  34. package/mapg.js +77 -69
  35. package/merge.js +18 -20
  36. package/mix.js +20 -16
  37. package/mul.js +24 -38
  38. package/multiplex.js +15 -11
  39. package/onepole.js +41 -42
  40. package/osc-additive.js +25 -53
  41. package/osc-cos.js +4 -1
  42. package/osc-dsf.js +15 -52
  43. package/osc-mix.js +6 -20
  44. package/osc-parabolic.js +4 -13
  45. package/osc-rect.js +6 -8
  46. package/osc-saw.js +4 -1
  47. package/osc-sin.js +4 -1
  48. package/osc-tri.js +4 -1
  49. package/osc-wavetable.js +12 -9
  50. package/osc.js +40 -74
  51. package/package.json +13 -10
  52. package/pan.js +23 -29
  53. package/pink-noise.js +35 -57
  54. package/pipe.js +6 -4
  55. package/power.js +40 -96
  56. package/product.js +5 -4
  57. package/reciprocal.js +20 -22
  58. package/ref.js +24 -20
  59. package/serial.js +59 -60
  60. package/sincos.js +45 -61
  61. package/sum.js +5 -4
  62. package/svf.js +74 -78
  63. package/sweep.js +4 -27
  64. package/waveshaper.js +41 -60
  65. package/white-noise.js +17 -23
  66. package/window.js +67 -52
package/cosine.js CHANGED
@@ -1,51 +1,46 @@
1
1
  import { TAU } from "@thi.ng/math/api";
2
2
  import { AGen } from "./agen.js";
3
- /**
4
- * Approximated cosine generator using given normalized `freq` and `amp`
5
- * (default: 1).
6
- *
7
- * @param freq -
8
- * @param amp -
9
- */
10
- export const cosine = (freq, amp) => new Cosine(freq, amp);
11
- export class Cosine extends AGen {
12
- _freq;
13
- _amp;
14
- _cos;
15
- _nxt;
16
- constructor(_freq, _amp = 1) {
17
- super(0);
18
- this._freq = _freq;
19
- this._amp = _amp;
20
- this.calcCoeffs();
21
- }
22
- reset() {
23
- this.calcCoeffs();
24
- return this;
25
- }
26
- next() {
27
- const t = this._nxt * this._cos - this._val;
28
- this._val = this._nxt;
29
- this._nxt = t;
30
- return this._val;
31
- }
32
- freq() {
33
- return this._freq;
34
- }
35
- setFreq(freq) {
36
- this._freq = freq;
37
- this.calcCoeffs();
38
- }
39
- amp() {
40
- return this._amp;
41
- }
42
- setAmp(amp) {
43
- this._amp = amp;
44
- this.calcCoeffs();
45
- }
46
- calcCoeffs() {
47
- this._nxt = this._amp;
48
- this._cos = Math.cos(this._freq * TAU) * 2;
49
- this._val = this._cos * this._amp * 0.5;
50
- }
3
+ const cosine = (freq, amp) => new Cosine(freq, amp);
4
+ class Cosine extends AGen {
5
+ constructor(_freq, _amp = 1) {
6
+ super(0);
7
+ this._freq = _freq;
8
+ this._amp = _amp;
9
+ this.calcCoeffs();
10
+ }
11
+ _cos;
12
+ _nxt;
13
+ reset() {
14
+ this.calcCoeffs();
15
+ return this;
16
+ }
17
+ next() {
18
+ const t = this._nxt * this._cos - this._val;
19
+ this._val = this._nxt;
20
+ this._nxt = t;
21
+ return this._val;
22
+ }
23
+ freq() {
24
+ return this._freq;
25
+ }
26
+ setFreq(freq) {
27
+ this._freq = freq;
28
+ this.calcCoeffs();
29
+ }
30
+ amp() {
31
+ return this._amp;
32
+ }
33
+ setAmp(amp) {
34
+ this._amp = amp;
35
+ this.calcCoeffs();
36
+ }
37
+ calcCoeffs() {
38
+ this._nxt = this._amp;
39
+ this._cos = Math.cos(this._freq * TAU) * 2;
40
+ this._val = this._cos * this._amp * 0.5;
41
+ }
51
42
  }
43
+ export {
44
+ Cosine,
45
+ cosine
46
+ };
package/curve.js CHANGED
@@ -1,43 +1,14 @@
1
1
  import { MAdd } from "./madd.js";
2
- /**
3
- * Returns new {@link MAdd} gen, producing an exponential curve (with
4
- * adjustable curvature) between `start` and `end` values over `num`
5
- * steps. This is the exponential equivalent of {@link line}.
6
- *
7
- * @remarks
8
- * Unless `skipFirst` is true (default: false), the `end` value is only
9
- * reached at `num + 1` steps. Unless `clampEnd` is true (default:
10
- * false), the curve will NOT stop at `end` but continue indefinitely if
11
- * more values are requested from the generator.
12
- *
13
- * The curvature can be controlled via the logarithmic `rate` param.
14
- * Recommended range [0.0001 - 10000] (curved -> linear). Default: 0.1
15
- *
16
- * Also see {@link madd}.
17
- *
18
- * @example
19
- * ```ts
20
- * curve(-1, 1, 5, 0.1).take(7)
21
- * // [
22
- * // -1,
23
- * // -0.04228753006664476,
24
- * // 0.4786567612639258,
25
- * // 0.7620225554764573,
26
- * // 0.9161583712747458,
27
- * // 1.0000000000000002, // target
28
- * // 1.0456053557111122
29
- * // ]
30
- * ```
31
- *
32
- * @param start - start value
33
- * @param end - end value
34
- * @param num - num steps
35
- * @param rate - curvature control
36
- * @param skipFirst - true to skip start value (default: false)
37
- * @param clampEnd - true to clamp curve at end value (default: false)
38
- */
39
- export const curve = (start, end, num, rate = 0.1, skipFirst = false, clampEnd = false) => {
40
- const c = Math.exp(-Math.log((Math.abs(end - start) + rate) / rate) / num);
41
- const offset = (start < end ? end + rate : end - rate) * (1 - c);
42
- return new MAdd(c, skipFirst ? offset + start * c : start, offset, clampEnd ? end : undefined);
2
+ const curve = (start, end, num, rate = 0.1, skipFirst = false, clampEnd = false) => {
3
+ const c = Math.exp(-Math.log((Math.abs(end - start) + rate) / rate) / num);
4
+ const offset = (start < end ? end + rate : end - rate) * (1 - c);
5
+ return new MAdd(
6
+ c,
7
+ skipFirst ? offset + start * c : start,
8
+ offset,
9
+ clampEnd ? end : void 0
10
+ );
11
+ };
12
+ export {
13
+ curve
43
14
  };
package/dcblock.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { OnePole } from "./onepole.js";
2
- /**
3
- * One-pole DC blocker based on {@link OnePole}.
4
- *
5
- * @param freq -
6
- */
7
- export const dcBlock = (freq) => new DCBlock("lp", freq);
8
- export class DCBlock extends OnePole {
9
- next(x) {
10
- return x - super.next(x);
11
- }
2
+ const dcBlock = (freq) => new DCBlock("lp", freq);
3
+ class DCBlock extends OnePole {
4
+ next(x) {
5
+ return x - super.next(x);
6
+ }
12
7
  }
8
+ export {
9
+ DCBlock,
10
+ dcBlock
11
+ };
package/delay.js CHANGED
@@ -2,117 +2,106 @@ import { isFunction } from "@thi.ng/checks/is-function";
2
2
  import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
3
3
  import { wrap } from "@thi.ng/math/interval";
4
4
  import { AProc } from "./aproc.js";
5
- /**
6
- * Delay line of length `n` for numeric values.
7
- *
8
- * @param n -
9
- */
10
- export const delay = (n) => new Delay(n, 0);
11
- /**
12
- * Delay line of length `n` for arbitrary typed values.
13
- *
14
- * @param n -
15
- */
16
- export const delayT = (n, off) => new Delay(n, off);
17
- /**
18
- * Ring buffer / delay line for arbitrary values w/ support for tapping
19
- * at any delay time (within configured buffer size).
20
- */
21
- export class Delay extends AProc {
22
- _empty;
23
- _buf;
24
- _rpos;
25
- _wpos;
26
- /**
27
- * Constructs new delay line of size `n` and initializes all
28
- * elements to `empty`. If the latter is a function, the buffer will
29
- * be initialized with the results of that function (called for each
30
- * element).
31
- *
32
- * @param n -
33
- * @param _empty -
34
- */
35
- constructor(n, _empty) {
36
- super(isFunction(_empty) ? _empty() : _empty);
37
- this._empty = _empty;
38
- if (n < 1)
39
- illegalArgs("delay size must be >= 1");
40
- n >>>= 0;
41
- this._wpos = n - 1;
42
- this._rpos = 0;
43
- this._buf = new Array(n);
44
- this.clear();
5
+ const delay = (n) => new Delay(n, 0);
6
+ const delayT = (n, off) => new Delay(n, off);
7
+ class Delay extends AProc {
8
+ /**
9
+ * Constructs new delay line of size `n` and initializes all
10
+ * elements to `empty`. If the latter is a function, the buffer will
11
+ * be initialized with the results of that function (called for each
12
+ * element).
13
+ *
14
+ * @param n -
15
+ * @param _empty -
16
+ */
17
+ constructor(n, _empty) {
18
+ super(isFunction(_empty) ? _empty() : _empty);
19
+ this._empty = _empty;
20
+ if (n < 1)
21
+ illegalArgs("delay size must be >= 1");
22
+ n >>>= 0;
23
+ this._wpos = n - 1;
24
+ this._rpos = 0;
25
+ this._buf = new Array(n);
26
+ this.clear();
27
+ }
28
+ _buf;
29
+ _rpos;
30
+ _wpos;
31
+ get length() {
32
+ return this._buf.length;
33
+ }
34
+ clear() {
35
+ const { _buf, _empty } = this;
36
+ if (isFunction(_empty)) {
37
+ for (let i = _buf.length; i-- > 0; ) {
38
+ this._buf[i] = _empty();
39
+ }
40
+ } else {
41
+ this._buf.fill(_empty);
45
42
  }
46
- get length() {
47
- return this._buf.length;
48
- }
49
- clear() {
50
- const { _buf, _empty } = this;
51
- if (isFunction(_empty)) {
52
- for (let i = _buf.length; i-- > 0;) {
53
- this._buf[i] = _empty();
54
- }
55
- }
56
- else {
57
- this._buf.fill(_empty);
58
- }
59
- }
60
- copy() {
61
- return new Delay(this._buf.length, this._empty);
62
- }
63
- /**
64
- * Alias for {@link Delay.clear}
65
- */
66
- reset() {
67
- this.clear();
68
- return this;
69
- }
70
- /**
71
- * Returns the delayed value at current read position (i.e. `n`
72
- * samples behind current write pos, where `n` is the length of this
73
- * delay line).
74
- */
75
- deref() {
76
- return this._buf[this._rpos];
77
- }
78
- /**
79
- * Reads value at `t` relative to current write position. `t` should
80
- * be in `(-∞..0)` interval. E.g. `tap(-1)` returns the second
81
- * most recent value written.
82
- *
83
- * @param t -
84
- */
85
- tap(t) {
86
- return this._buf[wrap((t | 0) + this._wpos, 0, this._buf.length - 1)];
87
- }
88
- /**
89
- * Takes an array of offsets relative to current write position,
90
- * calls {@link Delay.tap} for each, writes results to `out` and
91
- * returns it.
92
- */
93
- multiTap(t, out = []) {
94
- for (let i = t.length; i-- > 0;) {
95
- out[i] = this.tap(t[i]);
96
- }
97
- return out;
98
- }
99
- /**
100
- * Progresses read & write pos, stores new value and returns delayed value.
101
- *
102
- * @param x -
103
- */
104
- next(x) {
105
- this.step();
106
- this._buf[this._wpos] = x;
107
- return (this._val = this._buf[this._rpos]);
108
- }
109
- /**
110
- * Moves read & write cursors one step forward. Useful for skipping
111
- * elements and/or to create gaps in the delay line.
112
- */
113
- step() {
114
- const n = this._buf.length;
115
- ++this._wpos >= n && (this._wpos -= n);
116
- ++this._rpos >= n && (this._rpos -= n);
43
+ }
44
+ copy() {
45
+ return new Delay(this._buf.length, this._empty);
46
+ }
47
+ /**
48
+ * Alias for {@link Delay.clear}
49
+ */
50
+ reset() {
51
+ this.clear();
52
+ return this;
53
+ }
54
+ /**
55
+ * Returns the delayed value at current read position (i.e. `n`
56
+ * samples behind current write pos, where `n` is the length of this
57
+ * delay line).
58
+ */
59
+ deref() {
60
+ return this._buf[this._rpos];
61
+ }
62
+ /**
63
+ * Reads value at `t` relative to current write position. `t` should
64
+ * be in `(-∞..0)` interval. E.g. `tap(-1)` returns the second
65
+ * most recent value written.
66
+ *
67
+ * @param t -
68
+ */
69
+ tap(t) {
70
+ return this._buf[wrap((t | 0) + this._wpos, 0, this._buf.length - 1)];
71
+ }
72
+ /**
73
+ * Takes an array of offsets relative to current write position,
74
+ * calls {@link Delay.tap} for each, writes results to `out` and
75
+ * returns it.
76
+ */
77
+ multiTap(t, out = []) {
78
+ for (let i = t.length; i-- > 0; ) {
79
+ out[i] = this.tap(t[i]);
117
80
  }
81
+ return out;
82
+ }
83
+ /**
84
+ * Progresses read & write pos, stores new value and returns delayed value.
85
+ *
86
+ * @param x -
87
+ */
88
+ next(x) {
89
+ this.step();
90
+ this._buf[this._wpos] = x;
91
+ return this._val = this._buf[this._rpos];
92
+ }
93
+ /**
94
+ * Moves read & write cursors one step forward. Useful for skipping
95
+ * elements and/or to create gaps in the delay line.
96
+ */
97
+ step() {
98
+ const n = this._buf.length;
99
+ ++this._wpos >= n && (this._wpos -= n);
100
+ ++this._rpos >= n && (this._rpos -= n);
101
+ }
118
102
  }
103
+ export {
104
+ Delay,
105
+ delay,
106
+ delayT
107
+ };
package/feedback-delay.js CHANGED
@@ -1,33 +1,26 @@
1
1
  import { clamp01 } from "@thi.ng/math/interval";
2
2
  import { Delay } from "./delay.js";
3
- /**
4
- * Extension of {@link Delay} which adds sum delayed value multiplied
5
- * with `feedback` for each new input.
6
- *
7
- * @remarks
8
- * Also see {@link filterFeedbackDelay} for filtered version.
9
- *
10
- * @param n - delay length
11
- * @param feedback - feedback factor (default: 0.5)
12
- */
13
- export const feedbackDelay = (n, feedback) => new FeedbackDelay(n, feedback);
14
- export class FeedbackDelay extends Delay {
15
- _feedback;
16
- constructor(n, _feedback = 0.5) {
17
- super(n, 0);
18
- this._feedback = _feedback;
19
- this.setFeedback(_feedback);
20
- }
21
- copy() {
22
- return new FeedbackDelay(this._buf.length, this._feedback);
23
- }
24
- next(x) {
25
- return super.next(x + this._buf[this._rpos] * this._feedback);
26
- }
27
- feedback() {
28
- return this._feedback;
29
- }
30
- setFeedback(feedback) {
31
- this._feedback = clamp01(feedback);
32
- }
3
+ const feedbackDelay = (n, feedback) => new FeedbackDelay(n, feedback);
4
+ class FeedbackDelay extends Delay {
5
+ constructor(n, _feedback = 0.5) {
6
+ super(n, 0);
7
+ this._feedback = _feedback;
8
+ this.setFeedback(_feedback);
9
+ }
10
+ copy() {
11
+ return new FeedbackDelay(this._buf.length, this._feedback);
12
+ }
13
+ next(x) {
14
+ return super.next(x + this._buf[this._rpos] * this._feedback);
15
+ }
16
+ feedback() {
17
+ return this._feedback;
18
+ }
19
+ setFeedback(feedback) {
20
+ this._feedback = clamp01(feedback);
21
+ }
33
22
  }
23
+ export {
24
+ FeedbackDelay,
25
+ feedbackDelay
26
+ };