cantor-digitalis 0.0.5 → 0.0.6
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.
- package/dist/index.js +50 -48
- package/dist/index.js.map +1 -1
- package/dist/nodes/anti-resonance.d.ts +2 -2
- package/dist/nodes/anti-resonance.d.ts.map +1 -1
- package/dist/nodes/formant-bank.d.ts +2 -2
- package/dist/nodes/formant-bank.d.ts.map +1 -1
- package/dist/nodes/formant-resonator.d.ts +2 -2
- package/dist/nodes/formant-resonator.d.ts.map +1 -1
- package/dist/nodes/gain.d.ts +2 -2
- package/dist/nodes/gain.d.ts.map +1 -1
- package/dist/nodes/glottal-flow-derivative.d.ts +2 -2
- package/dist/nodes/glottal-flow-derivative.d.ts.map +1 -1
- package/dist/nodes/glottal-formant.d.ts +2 -2
- package/dist/nodes/glottal-formant.d.ts.map +1 -1
- package/dist/nodes/noise-source.d.ts +1 -1
- package/dist/nodes/noise-source.d.ts.map +1 -1
- package/dist/nodes/pulse-train.d.ts +2 -2
- package/dist/nodes/pulse-train.d.ts.map +1 -1
- package/dist/nodes/spectral-tilt.d.ts +2 -2
- package/dist/nodes/spectral-tilt.d.ts.map +1 -1
- package/dist/nodes/types.d.ts +1 -1
- package/dist/nodes/types.d.ts.map +1 -1
- package/dist/nodes/vocal-tract.d.ts +2 -2
- package/dist/nodes/vocal-tract.d.ts.map +1 -1
- package/dist/nodes/voice.d.ts +2 -2
- package/dist/nodes/voice.d.ts.map +1 -1
- package/dist/nodes/worklet-utils.d.ts +6 -4
- package/dist/nodes/worklet-utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ class T {
|
|
|
26
26
|
* Computes the frequency response of the gain node (static version).
|
|
27
27
|
*
|
|
28
28
|
* Returns an array filled with the specified gain value (flat response).
|
|
29
|
-
* This static method allows frequency response calculation without an
|
|
29
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
30
30
|
*
|
|
31
31
|
* @param frequencies Array of frequencies in Hz
|
|
32
32
|
* @param gain The gain value (linear amplitude)
|
|
@@ -44,20 +44,22 @@ class T {
|
|
|
44
44
|
return T.getFrequencyResponse(t, this.gainNode.gain.value);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
const O = /* @__PURE__ */ new
|
|
47
|
+
const O = /* @__PURE__ */ new WeakMap();
|
|
48
48
|
async function R(a, t, e) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
let s = O.get(a);
|
|
50
|
+
s || (s = /* @__PURE__ */ new Map(), O.set(a, s));
|
|
51
|
+
const n = s.get(t);
|
|
52
|
+
if (n)
|
|
53
|
+
return n;
|
|
54
|
+
const o = (async () => {
|
|
55
|
+
const i = new Blob([e], { type: "application/javascript" }), u = URL.createObjectURL(i);
|
|
54
56
|
try {
|
|
55
|
-
await a.audioWorklet.addModule(
|
|
57
|
+
await a.audioWorklet.addModule(u);
|
|
56
58
|
} finally {
|
|
57
|
-
URL.revokeObjectURL(
|
|
59
|
+
URL.revokeObjectURL(u);
|
|
58
60
|
}
|
|
59
61
|
})();
|
|
60
|
-
return
|
|
62
|
+
return s.set(t, o), o;
|
|
61
63
|
}
|
|
62
64
|
const ft = `
|
|
63
65
|
class PulseTrainProcessor extends AudioWorkletProcessor {
|
|
@@ -248,7 +250,7 @@ class x {
|
|
|
248
250
|
*
|
|
249
251
|
* PulseTrain is a source node that generates signal, not a filter.
|
|
250
252
|
* The response represents that no frequency-dependent filtering is applied.
|
|
251
|
-
* This static method allows frequency response calculation without an
|
|
253
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
252
254
|
*
|
|
253
255
|
* @param frequencies Array of frequencies in Hz
|
|
254
256
|
* @returns Array of linear amplitude values (all equal to 1.0)
|
|
@@ -268,13 +270,13 @@ class x {
|
|
|
268
270
|
}
|
|
269
271
|
function Q(a, t, e, s) {
|
|
270
272
|
return e.map((n) => {
|
|
271
|
-
const o = 2 * Math.PI * n / s, i = Math.cos(o),
|
|
273
|
+
const o = 2 * Math.PI * n / s, i = Math.cos(o), u = Math.cos(2 * o), c = Math.sin(o), d = Math.sin(2 * o), l = a[0] + a[1] * i + a[2] * u, m = -a[1] * c - a[2] * d, h = t[0] + t[1] * i + t[2] * u, p = -t[1] * c - t[2] * d, f = Math.sqrt(l * l + m * m), g = Math.sqrt(h * h + p * p);
|
|
272
274
|
return g === 0 ? 0 : f / g;
|
|
273
275
|
});
|
|
274
276
|
}
|
|
275
|
-
function
|
|
277
|
+
function W(a, t, e, s) {
|
|
276
278
|
return e.map((n) => {
|
|
277
|
-
const o = 2 * Math.PI * n / s, i = Math.cos(o),
|
|
279
|
+
const o = 2 * Math.PI * n / s, i = Math.cos(o), u = Math.sin(o), c = a[0] + a[1] * i, d = -a[1] * u, l = t[0] + t[1] * i, m = -t[1] * u, h = Math.sqrt(c * c + d * d), p = Math.sqrt(l * l + m * m);
|
|
278
280
|
return p === 0 ? 0 : h / p;
|
|
279
281
|
});
|
|
280
282
|
}
|
|
@@ -289,7 +291,7 @@ function w(...a) {
|
|
|
289
291
|
e[n] *= s[n];
|
|
290
292
|
return e;
|
|
291
293
|
}
|
|
292
|
-
function
|
|
294
|
+
function E(...a) {
|
|
293
295
|
if (a.length === 0) return [];
|
|
294
296
|
const t = a[0].length, e = new Array(t).fill(0);
|
|
295
297
|
for (const s of a)
|
|
@@ -421,7 +423,7 @@ class M {
|
|
|
421
423
|
/**
|
|
422
424
|
* Computes the frequency response of the glottal formant filter (static version).
|
|
423
425
|
*
|
|
424
|
-
* This static method allows frequency response calculation without an
|
|
426
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
425
427
|
*
|
|
426
428
|
* @param frequencies Array of frequencies in Hz
|
|
427
429
|
* @param params The glottal formant parameters (Fg, Bg, Ag)
|
|
@@ -429,7 +431,7 @@ class M {
|
|
|
429
431
|
* @returns Array of linear amplitude values
|
|
430
432
|
*/
|
|
431
433
|
static getFrequencyResponse(t, e, s = 96e3) {
|
|
432
|
-
const { Fg: n, Bg: o, Ag: i } = e,
|
|
434
|
+
const { Fg: n, Bg: o, Ag: i } = e, u = 1 / s, c = Math.exp(-Math.PI * o * u), d = [0, -i, i], l = 2 * Math.PI * n * u, m = -2 * c * Math.cos(l), h = c * c;
|
|
433
435
|
return Q(d, [1, m, h], t, s);
|
|
434
436
|
}
|
|
435
437
|
/**
|
|
@@ -585,13 +587,13 @@ class F {
|
|
|
585
587
|
static computeStageCoefficientsStatic(t, e) {
|
|
586
588
|
if (t <= 0)
|
|
587
589
|
return [0, 1];
|
|
588
|
-
const s = 1 / e, n = Math.cos(2 * Math.PI * 3e3 * s), o = Math.pow(10, t / 10), i = 1 + (1 - n) / (o - 1),
|
|
589
|
-
return [
|
|
590
|
+
const s = 1 / e, n = Math.cos(2 * Math.PI * 3e3 * s), o = Math.pow(10, t / 10), i = 1 + (1 - n) / (o - 1), u = i - Math.sqrt(i * i - 1), c = 1 - u;
|
|
591
|
+
return [u, c];
|
|
590
592
|
}
|
|
591
593
|
/**
|
|
592
594
|
* Computes the frequency response of the spectral tilt filter (static version).
|
|
593
595
|
*
|
|
594
|
-
* This static method allows frequency response calculation without an
|
|
596
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
595
597
|
*
|
|
596
598
|
* @param frequencies Array of frequencies in Hz
|
|
597
599
|
* @param params The spectral tilt parameters (Tl1, Tl2)
|
|
@@ -599,7 +601,7 @@ class F {
|
|
|
599
601
|
* @returns Array of linear amplitude values
|
|
600
602
|
*/
|
|
601
603
|
static getFrequencyResponse(t, e, s = 96e3) {
|
|
602
|
-
const { Tl1: n, Tl2: o } = e, [i,
|
|
604
|
+
const { Tl1: n, Tl2: o } = e, [i, u] = F.computeStageCoefficientsStatic(n, s), [c, d] = F.computeStageCoefficientsStatic(o, s), l = W([u, 0], [1, -i], t, s), m = W([d, 0], [1, -c], t, s);
|
|
603
605
|
return w(l, m);
|
|
604
606
|
}
|
|
605
607
|
/**
|
|
@@ -749,7 +751,7 @@ class S {
|
|
|
749
751
|
* and the noise modulation path where noise is multiplied by the GFD signal.
|
|
750
752
|
*/
|
|
751
753
|
static async create(t, e) {
|
|
752
|
-
const [s, n, o, i,
|
|
754
|
+
const [s, n, o, i, u] = await Promise.all([
|
|
753
755
|
x.create(t, {
|
|
754
756
|
f0: e.f0,
|
|
755
757
|
jitterDepth: e.jitterDepth,
|
|
@@ -759,14 +761,14 @@ class S {
|
|
|
759
761
|
F.create(t, { Tl1: e.Tl1, Tl2: e.Tl2 }),
|
|
760
762
|
G.create(t, { An: e.An }),
|
|
761
763
|
T.create(t, { gain: 1 })
|
|
762
|
-
]),
|
|
763
|
-
return
|
|
764
|
+
]), c = t.createGain();
|
|
765
|
+
return c.gain.setValueAtTime(0, t.currentTime), s.out.connect(n.in), n.out.connect(o.in), o.out.connect(u.in), o.out.connect(c.gain), i.out.connect(c), c.connect(u.in), new S(
|
|
764
766
|
s,
|
|
765
767
|
n,
|
|
766
768
|
o,
|
|
767
769
|
i,
|
|
768
|
-
|
|
769
|
-
|
|
770
|
+
c,
|
|
771
|
+
u
|
|
770
772
|
);
|
|
771
773
|
}
|
|
772
774
|
/**
|
|
@@ -837,7 +839,7 @@ class S {
|
|
|
837
839
|
/**
|
|
838
840
|
* Computes the frequency response of the glottal flow derivative filter chain (static version).
|
|
839
841
|
*
|
|
840
|
-
* This static method allows frequency response calculation without an
|
|
842
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
841
843
|
* Returns the response of the voiced path: GlottalFormant → SpectralTilt.
|
|
842
844
|
* The noise path has its own bandpass filtering but is mixed separately.
|
|
843
845
|
*
|
|
@@ -1009,7 +1011,7 @@ class k {
|
|
|
1009
1011
|
/**
|
|
1010
1012
|
* Computes the frequency response of the formant resonator (static version).
|
|
1011
1013
|
*
|
|
1012
|
-
* This static method allows frequency response calculation without an
|
|
1014
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
1013
1015
|
*
|
|
1014
1016
|
* @param frequencies Array of frequencies in Hz
|
|
1015
1017
|
* @param params The formant resonator parameters (F, B, A)
|
|
@@ -1017,7 +1019,7 @@ class k {
|
|
|
1017
1019
|
* @returns Array of linear amplitude values
|
|
1018
1020
|
*/
|
|
1019
1021
|
static getFrequencyResponse(t, e, s = 96e3) {
|
|
1020
|
-
const { F: n, B: o, A: i } = e,
|
|
1022
|
+
const { F: n, B: o, A: i } = e, u = 1 / s, c = Math.exp(-Math.PI * o * u), d = 2 * Math.PI * n * u, l = 1 - c, m = i * l, h = -i * l * c, p = [m, 0, h], f = -2 * c * Math.cos(d), g = c * c;
|
|
1021
1023
|
return Q(p, [1, f, g], t, s);
|
|
1022
1024
|
}
|
|
1023
1025
|
/**
|
|
@@ -1100,7 +1102,7 @@ class N {
|
|
|
1100
1102
|
/**
|
|
1101
1103
|
* Computes the frequency response of the formant bank (static version).
|
|
1102
1104
|
*
|
|
1103
|
-
* This static method allows frequency response calculation without an
|
|
1105
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
1104
1106
|
* The response is the sum of all parallel formant resonators.
|
|
1105
1107
|
*
|
|
1106
1108
|
* @param frequencies Array of frequencies in Hz
|
|
@@ -1112,7 +1114,7 @@ class N {
|
|
|
1112
1114
|
const n = e.map(
|
|
1113
1115
|
(o) => k.getFrequencyResponse(t, o, s)
|
|
1114
1116
|
);
|
|
1115
|
-
return
|
|
1117
|
+
return E(...n);
|
|
1116
1118
|
}
|
|
1117
1119
|
/**
|
|
1118
1120
|
* Computes the frequency response of the formant bank.
|
|
@@ -1123,7 +1125,7 @@ class N {
|
|
|
1123
1125
|
const s = this.resonators.map(
|
|
1124
1126
|
(n) => n.getFrequencyResponse(t, e)
|
|
1125
1127
|
);
|
|
1126
|
-
return
|
|
1128
|
+
return E(...s);
|
|
1127
1129
|
}
|
|
1128
1130
|
}
|
|
1129
1131
|
const bt = `
|
|
@@ -1256,7 +1258,7 @@ class B {
|
|
|
1256
1258
|
/**
|
|
1257
1259
|
* Computes the frequency response of the anti-resonance (notch) filter (static version).
|
|
1258
1260
|
*
|
|
1259
|
-
* This static method allows frequency response calculation without an
|
|
1261
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
1260
1262
|
*
|
|
1261
1263
|
* @param frequencies Array of frequencies in Hz
|
|
1262
1264
|
* @param params The anti-resonance parameters (F, Q)
|
|
@@ -1264,7 +1266,7 @@ class B {
|
|
|
1264
1266
|
* @returns Array of linear amplitude values
|
|
1265
1267
|
*/
|
|
1266
1268
|
static getFrequencyResponse(t, e, s = 96e3) {
|
|
1267
|
-
const { F: n, Q: o } = e, i = 1 / s,
|
|
1269
|
+
const { F: n, Q: o } = e, i = 1 / s, u = 2 * Math.PI * n * i, c = Math.sin(u) / (2 * o), d = -2 * Math.cos(u), l = 1 + c, m = [1 / l, d / l, 1 / l], h = [1, d / l, (1 - c) / l];
|
|
1268
1270
|
return Q(m, h, t, s);
|
|
1269
1271
|
}
|
|
1270
1272
|
/**
|
|
@@ -1340,7 +1342,7 @@ class D {
|
|
|
1340
1342
|
/**
|
|
1341
1343
|
* Computes the frequency response of the vocal tract (static version).
|
|
1342
1344
|
*
|
|
1343
|
-
* This static method allows frequency response calculation without an
|
|
1345
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
1344
1346
|
* The response is the formant bank (parallel) followed by the anti-resonance (series).
|
|
1345
1347
|
*
|
|
1346
1348
|
* @param frequencies Array of frequencies in Hz
|
|
@@ -1461,7 +1463,7 @@ class Y {
|
|
|
1461
1463
|
/**
|
|
1462
1464
|
* Computes the frequency response of the complete voice synthesizer (static version).
|
|
1463
1465
|
*
|
|
1464
|
-
* This static method allows frequency response calculation without an
|
|
1466
|
+
* This static method allows frequency response calculation without an BaseAudioContext.
|
|
1465
1467
|
* Returns the response of the full chain: Source → VocalTract → OutputGain.
|
|
1466
1468
|
*
|
|
1467
1469
|
* @param frequencies Array of frequencies in Hz
|
|
@@ -1516,19 +1518,19 @@ function qt(a, t, e = Z) {
|
|
|
1516
1518
|
);
|
|
1517
1519
|
}
|
|
1518
1520
|
a = Math.max(0, Math.min(1, a)), t = Math.max(0, Math.min(1, t));
|
|
1519
|
-
const i = s.map((h) => Math.hypot(h.h - a, h.v - t)),
|
|
1520
|
-
if (
|
|
1521
|
-
const h = s[i.indexOf(
|
|
1521
|
+
const i = s.map((h) => Math.hypot(h.h - a, h.v - t)), u = Math.min(...i);
|
|
1522
|
+
if (u < At) {
|
|
1523
|
+
const h = s[i.indexOf(u)], p = h.volumeAdjustment ?? 0;
|
|
1522
1524
|
return h.formants.map((f) => ({
|
|
1523
1525
|
...f,
|
|
1524
1526
|
amplitude: f.amplitude + p
|
|
1525
1527
|
}));
|
|
1526
1528
|
}
|
|
1527
|
-
const
|
|
1529
|
+
const c = i.map((h) => 1 / Math.pow(h, n)), d = c.reduce((h, p) => h + p, 0), l = s[0].formants.length, m = [];
|
|
1528
1530
|
for (let h = 0; h < l; h++) {
|
|
1529
1531
|
let p = 0, f = 0, g = 0;
|
|
1530
1532
|
for (let y = 0; y < s.length; y++) {
|
|
1531
|
-
const A =
|
|
1533
|
+
const A = c[y] / d, b = s[y].formants[h];
|
|
1532
1534
|
b && (p += A * b.frequency, f += A * (b.amplitude + (s[y].volumeAdjustment ?? 0)), g += A * b.bandwidth);
|
|
1533
1535
|
}
|
|
1534
1536
|
m.push({ frequency: p, amplitude: f, bandwidth: g });
|
|
@@ -1718,8 +1720,8 @@ function Qt(a) {
|
|
|
1718
1720
|
function Gt(a, t, e) {
|
|
1719
1721
|
if (e >= 3)
|
|
1720
1722
|
return 0;
|
|
1721
|
-
const s = 15 + 85 * ((a - 50) / 1450), n = [10, 15, 25][e], i = Math.round(t / a) * a,
|
|
1722
|
-
return
|
|
1723
|
+
const s = 15 + 85 * ((a - 50) / 1450), n = [10, 15, 25][e], i = Math.round(t / a) * a, u = Math.abs(i - t);
|
|
1724
|
+
return u < s ? (1 - u / s) * n : 0;
|
|
1723
1725
|
}
|
|
1724
1726
|
function zt(a, t = {}) {
|
|
1725
1727
|
var I;
|
|
@@ -1728,13 +1730,13 @@ function zt(a, t = {}) {
|
|
|
1728
1730
|
pitchOffset: n,
|
|
1729
1731
|
vocalEffort: o,
|
|
1730
1732
|
vowelHeight: i,
|
|
1731
|
-
vowelBackness:
|
|
1732
|
-
tenseness:
|
|
1733
|
+
vowelBackness: u,
|
|
1734
|
+
tenseness: c,
|
|
1733
1735
|
breathiness: d,
|
|
1734
1736
|
roughness: l,
|
|
1735
1737
|
vocalTractSize: m,
|
|
1736
1738
|
isFalsetto: h
|
|
1737
|
-
} = a, p = h ? 2 : 1, f = n + 35 * s, g = Bt(f), y = xt(
|
|
1739
|
+
} = a, p = h ? 2 : 1, f = n + 35 * s, g = Bt(f), y = xt(c, o, p), A = St(c, p), b = g / (2 * y), tt = Nt(g, y, A), et = Vt(o, y), { Tl1: st, Tl2: nt } = Dt(o, p), at = Ct(d, o), ot = l * 0.3, rt = l * 1, it = (I = e.vowelTable) != null && I.sourceVocalTractSize ? X(e.vowelTable.sourceVocalTractSize) : 1, j = X(m), ut = Qt(g), ct = qt(u, i, e.vowelTable).map((q, V) => {
|
|
1738
1740
|
const C = e.formantFrequencyScaling ? ut * j / it : 1;
|
|
1739
1741
|
let P = C * q.frequency;
|
|
1740
1742
|
if (V === 0 && e.f1Tuning) {
|
|
@@ -1776,11 +1778,11 @@ export {
|
|
|
1776
1778
|
F as SpectralTilt,
|
|
1777
1779
|
D as VocalTract,
|
|
1778
1780
|
Y as Voice,
|
|
1779
|
-
|
|
1781
|
+
E as combineParallel,
|
|
1780
1782
|
w as combineSeries,
|
|
1781
1783
|
Z as defaultVowelTable,
|
|
1782
1784
|
Q as evaluateBiquad,
|
|
1783
|
-
|
|
1785
|
+
W as evaluateFirstOrder,
|
|
1784
1786
|
zt as generateSynthParams,
|
|
1785
1787
|
qt as interpolateFormants,
|
|
1786
1788
|
Ot as linearToDb
|