@prosopo/audio-assets 0.0.0-stage → 0.2.0
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/.turbo/turbo-build$colon$cjs.log +23 -0
- package/.turbo/turbo-build$colon$tsc.log +14 -0
- package/.turbo/turbo-build.log +25 -0
- package/CHANGELOG.md +19 -0
- package/LICENSE +201 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -0
- package/dist/cjs/distort.cjs +91 -0
- package/dist/cjs/encode.cjs +40 -0
- package/dist/cjs/index.cjs +109 -0
- package/dist/cjs/levels.cjs +18 -0
- package/dist/cjs/phonemes.cjs +217 -0
- package/dist/cjs/synth.cjs +222 -0
- package/dist/distort.d.ts +7 -0
- package/dist/distort.d.ts.map +1 -0
- package/dist/distort.js +88 -0
- package/dist/distort.js.map +1 -0
- package/dist/encode.d.ts +4 -0
- package/dist/encode.d.ts.map +1 -0
- package/dist/encode.js +39 -0
- package/dist/encode.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/levels.d.ts +3 -0
- package/dist/levels.d.ts.map +1 -0
- package/dist/levels.js +17 -0
- package/dist/levels.js.map +1 -0
- package/dist/phonemes.d.ts +4 -0
- package/dist/phonemes.d.ts.map +1 -0
- package/dist/phonemes.js +216 -0
- package/dist/phonemes.js.map +1 -0
- package/dist/synth.d.ts +13 -0
- package/dist/synth.d.ts.map +1 -0
- package/dist/synth.js +220 -0
- package/dist/synth.js.map +1 -0
- package/dist/tests/audioAssets.unit.test.d.ts +2 -0
- package/dist/tests/audioAssets.unit.test.d.ts.map +1 -0
- package/dist/tests/audioAssets.unit.test.js +220 -0
- package/dist/tests/audioAssets.unit.test.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -3
- package/scripts/preview.ts +141 -0
- package/vite.cjs.config.ts +23 -0
- package/vite.esm.config.ts +20 -0
- package/vite.test.config.ts +32 -0
- package/README.md +0 -3
package/dist/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { rms } from "./levels.js";
|
|
3
|
+
import { addNoiseBed, addReverb, finalise, mixInto } from "./distort.js";
|
|
4
|
+
import { encodeWav, toDataUri } from "./encode.js";
|
|
5
|
+
import { ANSWER_ALPHABET, DIGITS } from "./phonemes.js";
|
|
6
|
+
import { SAMPLE_RATE, randomVoice, synthesiseUtterance } from "./synth.js";
|
|
7
|
+
import { createPrng, createPrng as createPrng$1, createSeed, createSeed as createSeed$1 } from "@prosopo/puzzle-assets";
|
|
8
|
+
//#region src/index.ts
|
|
9
|
+
/** Must match the `audio*Default` constants in `@prosopo/types` client settings. */
|
|
10
|
+
var DEFAULT_RENDER_SETTINGS = {
|
|
11
|
+
digitCount: 5,
|
|
12
|
+
noiseSnrDb: 14,
|
|
13
|
+
babbleGain: .16,
|
|
14
|
+
babbleVoices: 2,
|
|
15
|
+
reverbMix: .12,
|
|
16
|
+
gapMs: 220
|
|
17
|
+
};
|
|
18
|
+
var LEAD_IN_MS = 250;
|
|
19
|
+
var LEAD_OUT_MS = 350;
|
|
20
|
+
var GAP_JITTER_RATIO = .4;
|
|
21
|
+
var MAX_GAP_JITTER_MS = 360;
|
|
22
|
+
var BABBLE_MAX_START_MS = 400;
|
|
23
|
+
var BABBLE_MAX_PAUSE_MS = 500;
|
|
24
|
+
var msToSamples = (ms, sampleRate) => Math.round(ms / 1e3 * sampleRate);
|
|
25
|
+
/** Repeats allowed: forbidding them would let a solver narrow the last digit from the others. */
|
|
26
|
+
var chooseAnswer = (prng, count) => Array.from({ length: count }, () => prng.pick(DIGITS));
|
|
27
|
+
/**
|
|
28
|
+
* Other digit names by other speakers, from the answer's own alphabet, so
|
|
29
|
+
* transcribing everything audible yields a longer string with no marker for
|
|
30
|
+
* which digits were the foreground ones.
|
|
31
|
+
*/
|
|
32
|
+
var renderBabble = (prng, lengthSamples, sampleRate, voices) => {
|
|
33
|
+
const track = new Float32Array(lengthSamples);
|
|
34
|
+
const maxStart = msToSamples(BABBLE_MAX_START_MS, sampleRate);
|
|
35
|
+
const maxPause = msToSamples(BABBLE_MAX_PAUSE_MS, sampleRate);
|
|
36
|
+
for (let v = 0; v < voices; v++) {
|
|
37
|
+
const voice = {
|
|
38
|
+
...randomVoice(prng),
|
|
39
|
+
formantScale: prng.range(.8, 1.3),
|
|
40
|
+
rate: prng.range(.75, 1.35)
|
|
41
|
+
};
|
|
42
|
+
let cursor = prng.int(0, maxStart);
|
|
43
|
+
while (cursor < lengthSamples) {
|
|
44
|
+
const word = synthesiseUtterance(prng.pick(DIGITS), voice, prng, sampleRate);
|
|
45
|
+
mixInto(track, word.samples, cursor, prng.range(.6, 1));
|
|
46
|
+
cursor += word.samples.length + prng.int(0, maxPause);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return track;
|
|
50
|
+
};
|
|
51
|
+
/** The returned answer must stay on the challenge record and never reach the client. */
|
|
52
|
+
var renderAudioChallenge = (settings = DEFAULT_RENDER_SETTINGS, sampleRate = SAMPLE_RATE) => {
|
|
53
|
+
const prng = createPrng$1(createSeed$1());
|
|
54
|
+
const utterances = chooseAnswer(prng, settings.digitCount);
|
|
55
|
+
const answer = utterances.map((u) => u.answer).join("");
|
|
56
|
+
const voice = randomVoice(prng);
|
|
57
|
+
const words = utterances.map((u) => synthesiseUtterance(u, voice, prng, sampleRate));
|
|
58
|
+
const gapSamples = msToSamples(settings.gapMs, sampleRate);
|
|
59
|
+
const leadIn = msToSamples(LEAD_IN_MS, sampleRate);
|
|
60
|
+
const leadOut = msToSamples(LEAD_OUT_MS, sampleRate);
|
|
61
|
+
const maxJitter = msToSamples(Math.min(settings.gapMs * GAP_JITTER_RATIO, MAX_GAP_JITTER_MS), sampleRate);
|
|
62
|
+
const totalSamples = leadIn + words.reduce((total, w) => total + w.samples.length, 0) + gapSamples * Math.max(0, words.length - 1) + maxJitter * words.length + leadOut;
|
|
63
|
+
const samples = new Float32Array(totalSamples);
|
|
64
|
+
let cursor = leadIn;
|
|
65
|
+
for (const word of words) {
|
|
66
|
+
mixInto(samples, word.samples, cursor, 1);
|
|
67
|
+
cursor += word.samples.length + gapSamples + prng.int(-Math.floor(maxJitter / 2), maxJitter);
|
|
68
|
+
}
|
|
69
|
+
const buffer = {
|
|
70
|
+
samples,
|
|
71
|
+
sampleRate
|
|
72
|
+
};
|
|
73
|
+
if (settings.babbleGain > 0 && settings.babbleVoices > 0) mixInto(samples, renderBabble(prng, totalSamples, sampleRate, settings.babbleVoices), 0, settings.babbleGain);
|
|
74
|
+
addReverb(buffer, settings.reverbMix);
|
|
75
|
+
addNoiseBed(buffer, prng, settings.noiseSnrDb);
|
|
76
|
+
finalise(buffer);
|
|
77
|
+
return {
|
|
78
|
+
wav: encodeWav(buffer),
|
|
79
|
+
answer,
|
|
80
|
+
durationMs: Math.round(totalSamples / sampleRate * 1e3)
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { ANSWER_ALPHABET, DEFAULT_RENDER_SETTINGS, DIGITS, SAMPLE_RATE, addNoiseBed, createPrng, createSeed, encodeWav, randomVoice, renderAudioChallenge, rms, synthesiseUtterance, toDataUri };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/levels.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"levels.d.ts","sourceRoot":"","sources":["../src/levels.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,GAAG,YAAa,YAAY,KAAG,MAO3C,CAAC;AAGF,eAAO,MAAM,SAAS,YAAa,YAAY,QAAQ,MAAM,KAAG,IAU/D,CAAC"}
|
package/dist/levels.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/levels.ts
|
|
2
|
+
var rms = (samples) => {
|
|
3
|
+
if (samples.length === 0) return 0;
|
|
4
|
+
let total = 0;
|
|
5
|
+
for (const value of samples) total += value * value;
|
|
6
|
+
return Math.sqrt(total / samples.length);
|
|
7
|
+
};
|
|
8
|
+
/** Scale in place so the loudest sample sits at `peak`. No-op on silence. */
|
|
9
|
+
var normalise = (samples, peak) => {
|
|
10
|
+
let max = 0;
|
|
11
|
+
for (const value of samples) max = Math.max(max, Math.abs(value));
|
|
12
|
+
if (max === 0) return;
|
|
13
|
+
const gain = peak / max;
|
|
14
|
+
for (let n = 0; n < samples.length; n++) samples[n] = (samples[n] ?? 0) * gain;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { normalise, rms };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"levels.js","sourceRoot":"","sources":["../src/levels.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,OAAqB,EAAU,EAAE;IACpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAqB,EAAE,IAAY,EAAQ,EAAE;IACtE,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO;IACtB,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phonemes.d.ts","sourceRoot":"","sources":["../src/phonemes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,YAAY,CAAC;AAmJrD,eAAO,MAAM,MAAM,EAAE,SAAS,SAAS,EAWtC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,MAA6C,CAAC"}
|
package/dist/phonemes.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
//#region src/phonemes.ts
|
|
2
|
+
var STOP_BURST_MS = 18;
|
|
3
|
+
var VOICED_FRICATIVE_VOICE_GAIN = .45;
|
|
4
|
+
var NASAL_VOICE_GAIN = .5;
|
|
5
|
+
var APPROXIMANT_VOICE_GAIN = .85;
|
|
6
|
+
var segmentDefaults = {
|
|
7
|
+
bandwidths: [
|
|
8
|
+
80,
|
|
9
|
+
110,
|
|
10
|
+
160
|
|
11
|
+
],
|
|
12
|
+
voiceGain: 1,
|
|
13
|
+
noiseGain: 0,
|
|
14
|
+
noiseCentreHz: 0,
|
|
15
|
+
noiseBandwidthHz: 0
|
|
16
|
+
};
|
|
17
|
+
var vowel = (id, f1, f2, f3, durationMs) => ({
|
|
18
|
+
...segmentDefaults,
|
|
19
|
+
id,
|
|
20
|
+
excitation: "voiced",
|
|
21
|
+
formants: [
|
|
22
|
+
f1,
|
|
23
|
+
f2,
|
|
24
|
+
f3
|
|
25
|
+
],
|
|
26
|
+
durationMs
|
|
27
|
+
});
|
|
28
|
+
var fricative = (id, centreHz, bandwidthHz, gain, durationMs) => ({
|
|
29
|
+
...segmentDefaults,
|
|
30
|
+
id,
|
|
31
|
+
excitation: "unvoiced",
|
|
32
|
+
formants: [
|
|
33
|
+
0,
|
|
34
|
+
0,
|
|
35
|
+
0
|
|
36
|
+
],
|
|
37
|
+
durationMs,
|
|
38
|
+
voiceGain: 0,
|
|
39
|
+
noiseGain: gain,
|
|
40
|
+
noiseCentreHz: centreHz,
|
|
41
|
+
noiseBandwidthHz: bandwidthHz
|
|
42
|
+
});
|
|
43
|
+
var voicedFricative = (id, f1, f2, f3, centreHz, bandwidthHz, gain, durationMs) => ({
|
|
44
|
+
...segmentDefaults,
|
|
45
|
+
id,
|
|
46
|
+
excitation: "mixed",
|
|
47
|
+
formants: [
|
|
48
|
+
f1,
|
|
49
|
+
f2,
|
|
50
|
+
f3
|
|
51
|
+
],
|
|
52
|
+
durationMs,
|
|
53
|
+
voiceGain: VOICED_FRICATIVE_VOICE_GAIN,
|
|
54
|
+
noiseGain: gain,
|
|
55
|
+
noiseCentreHz: centreHz,
|
|
56
|
+
noiseBandwidthHz: bandwidthHz
|
|
57
|
+
});
|
|
58
|
+
var nasal = (id, f1, f2, f3, durationMs) => ({
|
|
59
|
+
...segmentDefaults,
|
|
60
|
+
id,
|
|
61
|
+
excitation: "voiced",
|
|
62
|
+
formants: [
|
|
63
|
+
f1,
|
|
64
|
+
f2,
|
|
65
|
+
f3
|
|
66
|
+
],
|
|
67
|
+
bandwidths: [
|
|
68
|
+
180,
|
|
69
|
+
250,
|
|
70
|
+
320
|
|
71
|
+
],
|
|
72
|
+
durationMs,
|
|
73
|
+
voiceGain: NASAL_VOICE_GAIN
|
|
74
|
+
});
|
|
75
|
+
var closure = (id, durationMs) => ({
|
|
76
|
+
...segmentDefaults,
|
|
77
|
+
id,
|
|
78
|
+
excitation: "silence",
|
|
79
|
+
formants: [
|
|
80
|
+
0,
|
|
81
|
+
0,
|
|
82
|
+
0
|
|
83
|
+
],
|
|
84
|
+
durationMs,
|
|
85
|
+
voiceGain: 0
|
|
86
|
+
});
|
|
87
|
+
var burst = (id, centreHz, bandwidthHz, gain) => ({
|
|
88
|
+
...segmentDefaults,
|
|
89
|
+
id,
|
|
90
|
+
excitation: "unvoiced",
|
|
91
|
+
formants: [
|
|
92
|
+
0,
|
|
93
|
+
0,
|
|
94
|
+
0
|
|
95
|
+
],
|
|
96
|
+
durationMs: STOP_BURST_MS,
|
|
97
|
+
voiceGain: 0,
|
|
98
|
+
noiseGain: gain,
|
|
99
|
+
noiseCentreHz: centreHz,
|
|
100
|
+
noiseBandwidthHz: bandwidthHz,
|
|
101
|
+
abrupt: true
|
|
102
|
+
});
|
|
103
|
+
var IY = vowel("IY", 270, 2290, 3010, 150);
|
|
104
|
+
var IH = vowel("IH", 390, 1990, 2550, 95);
|
|
105
|
+
var EH = vowel("EH", 530, 1840, 2480, 110);
|
|
106
|
+
var AH = vowel("AH", 640, 1190, 2390, 105);
|
|
107
|
+
var AA = vowel("AA", 730, 1090, 2440, 140);
|
|
108
|
+
var AO = vowel("AO", 570, 840, 2410, 150);
|
|
109
|
+
var UW = vowel("UW", 300, 870, 2240, 140);
|
|
110
|
+
var OW_OFF = vowel("OW^", 330, 900, 2300, 90);
|
|
111
|
+
var R = {
|
|
112
|
+
...vowel("R", 490, 1350, 1690, 85),
|
|
113
|
+
voiceGain: APPROXIMANT_VOICE_GAIN
|
|
114
|
+
};
|
|
115
|
+
var W = {
|
|
116
|
+
...vowel("W", 300, 610, 2200, 70),
|
|
117
|
+
voiceGain: APPROXIMANT_VOICE_GAIN
|
|
118
|
+
};
|
|
119
|
+
var N = nasal("N", 250, 1750, 2600, 90);
|
|
120
|
+
var S = fricative("S", 5800, 3200, .5, 130);
|
|
121
|
+
var F = fricative("F", 4200, 5e3, .24, 120);
|
|
122
|
+
var TH = fricative("TH", 5200, 5600, .2, 110);
|
|
123
|
+
var Z = voicedFricative("Z", 300, 1600, 2500, 5200, 3e3, .3, 110);
|
|
124
|
+
var V = voicedFricative("V", 320, 1100, 2400, 4e3, 4600, .16, 95);
|
|
125
|
+
var T = [closure("T-", 45), burst("T+", 3800, 3400, .55)];
|
|
126
|
+
var K = [closure("K-", 45), burst("K+", 2100, 2200, .5)];
|
|
127
|
+
var AY = [AA, {
|
|
128
|
+
...IY,
|
|
129
|
+
durationMs: 110
|
|
130
|
+
}];
|
|
131
|
+
var EY = [EH, {
|
|
132
|
+
...IY,
|
|
133
|
+
durationMs: 105
|
|
134
|
+
}];
|
|
135
|
+
/** "zero", not "oh": a lone vowel with no consonant anchor is the first thing lost to noise. */
|
|
136
|
+
var DIGITS = [
|
|
137
|
+
{
|
|
138
|
+
answer: "0",
|
|
139
|
+
phonemes: [
|
|
140
|
+
Z,
|
|
141
|
+
IH,
|
|
142
|
+
R,
|
|
143
|
+
...[AO, OW_OFF]
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
answer: "1",
|
|
148
|
+
phonemes: [
|
|
149
|
+
W,
|
|
150
|
+
AH,
|
|
151
|
+
N
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
answer: "2",
|
|
156
|
+
phonemes: [...T, UW]
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
answer: "3",
|
|
160
|
+
phonemes: [
|
|
161
|
+
TH,
|
|
162
|
+
R,
|
|
163
|
+
IY
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
answer: "4",
|
|
168
|
+
phonemes: [
|
|
169
|
+
F,
|
|
170
|
+
AO,
|
|
171
|
+
R
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
answer: "5",
|
|
176
|
+
phonemes: [
|
|
177
|
+
F,
|
|
178
|
+
...AY,
|
|
179
|
+
V
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
answer: "6",
|
|
184
|
+
phonemes: [
|
|
185
|
+
S,
|
|
186
|
+
IH,
|
|
187
|
+
...K,
|
|
188
|
+
S
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
answer: "7",
|
|
193
|
+
phonemes: [
|
|
194
|
+
S,
|
|
195
|
+
EH,
|
|
196
|
+
V,
|
|
197
|
+
AH,
|
|
198
|
+
N
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
answer: "8",
|
|
203
|
+
phonemes: [...EY, ...T]
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
answer: "9",
|
|
207
|
+
phonemes: [
|
|
208
|
+
N,
|
|
209
|
+
...AY,
|
|
210
|
+
N
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
];
|
|
214
|
+
var ANSWER_ALPHABET = DIGITS.map((d) => d.answer).join("");
|
|
215
|
+
//#endregion
|
|
216
|
+
export { ANSWER_ALPHABET, DIGITS };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phonemes.js","sourceRoot":"","sources":["../src/phonemes.ts"],"names":[],"mappings":"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"}
|
package/dist/synth.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Prng } from "@prosopo/puzzle-assets";
|
|
2
|
+
import type { AudioBuffer, Utterance } from "./types.js";
|
|
3
|
+
export declare const SAMPLE_RATE = 16000;
|
|
4
|
+
export interface Voice {
|
|
5
|
+
f0Hz: number;
|
|
6
|
+
f0DriftRatio: number;
|
|
7
|
+
formantScale: number;
|
|
8
|
+
rate: number;
|
|
9
|
+
tiltCornerHz: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const randomVoice: (prng: Prng) => Voice;
|
|
12
|
+
export declare const synthesiseUtterance: (utterance: Utterance, voice: Voice, prng: Prng, sampleRate?: number) => AudioBuffer;
|
|
13
|
+
//# sourceMappingURL=synth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth.d.ts","sourceRoot":"","sources":["../src/synth.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAW,SAAS,EAAE,MAAM,YAAY,CAAC;AAGlE,eAAO,MAAM,WAAW,QAAQ,CAAC;AAgBjC,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,MAAM,CAAC;IAEb,YAAY,EAAE,MAAM,CAAC;IAErB,YAAY,EAAE,MAAM,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;IAKb,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,SAAU,IAAI,KAAG,KAMvC,CAAC;AA2OH,eAAO,MAAM,mBAAmB,cACpB,SAAS,SACb,KAAK,QACN,IAAI,eACE,MAAM,KAChB,WA4DF,CAAC"}
|
package/dist/synth.js
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { normalise, rms } from "./levels.js";
|
|
2
|
+
//#region src/synth.ts
|
|
3
|
+
/** Not 8 kHz: /s/, /f/ and /θ/ live at 4-8 kHz and are what separate six, five and three. */
|
|
4
|
+
var SAMPLE_RATE = 16e3;
|
|
5
|
+
var NYQUIST_GUARD_HZ = 100;
|
|
6
|
+
var MIN_FORMANT_BANDWIDTH_HZ = 10;
|
|
7
|
+
var MIN_NOISE_BANDWIDTH_HZ = 100;
|
|
8
|
+
var LEVEL_RAMP_SECONDS = .004;
|
|
9
|
+
var EDGE_FADE_SECONDS = .008;
|
|
10
|
+
var WORD_PEAK = .9;
|
|
11
|
+
var SILENT_RMS = 1e-9;
|
|
12
|
+
var GLOTTAL_OPEN_QUOTIENT = .6;
|
|
13
|
+
var GLOTTAL_SPEED_QUOTIENT = .35;
|
|
14
|
+
var FORMANT_INDICES = [
|
|
15
|
+
0,
|
|
16
|
+
1,
|
|
17
|
+
2
|
|
18
|
+
];
|
|
19
|
+
var randomVoice = (prng) => ({
|
|
20
|
+
f0Hz: prng.range(85, 210),
|
|
21
|
+
f0DriftRatio: prng.range(.04, .16),
|
|
22
|
+
formantScale: prng.range(.86, 1.22),
|
|
23
|
+
rate: prng.range(.82, 1.24),
|
|
24
|
+
tiltCornerHz: prng.range(4500, 8e3)
|
|
25
|
+
});
|
|
26
|
+
/** Two-pole formant resonator, normalised to unity DC gain so a cascade stays bounded. */
|
|
27
|
+
var createResonator = (sampleRate) => {
|
|
28
|
+
let y1 = 0;
|
|
29
|
+
let y2 = 0;
|
|
30
|
+
let a = 1;
|
|
31
|
+
let b = 0;
|
|
32
|
+
let c = 0;
|
|
33
|
+
return {
|
|
34
|
+
setTarget(freqHz, bandwidthHz) {
|
|
35
|
+
const f = Math.min(Math.max(freqHz, 1), sampleRate / 2 - NYQUIST_GUARD_HZ);
|
|
36
|
+
const bw = Math.max(bandwidthHz, MIN_FORMANT_BANDWIDTH_HZ);
|
|
37
|
+
const r = Math.exp(-Math.PI * bw / sampleRate);
|
|
38
|
+
const theta = 2 * Math.PI * f / sampleRate;
|
|
39
|
+
b = 2 * r * Math.cos(theta);
|
|
40
|
+
c = -(r * r);
|
|
41
|
+
a = 1 - b - c;
|
|
42
|
+
},
|
|
43
|
+
process(x) {
|
|
44
|
+
const y = a * x + b * y1 + c * y2;
|
|
45
|
+
y2 = y1;
|
|
46
|
+
y1 = y;
|
|
47
|
+
return y;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
var createOnePoleLowPass = (sampleRate, cutoffHz) => {
|
|
52
|
+
const dt = 1 / sampleRate;
|
|
53
|
+
const alpha = dt / (1 / (2 * Math.PI * cutoffHz) + dt);
|
|
54
|
+
let y = 0;
|
|
55
|
+
return (x) => {
|
|
56
|
+
y += alpha * (x - y);
|
|
57
|
+
return y;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Lip radiation, a +6 dB/octave differentiator. Without it the glottal
|
|
62
|
+
* pulse's DC and steep rolloff bury F2 and F3, which are what tell vowels
|
|
63
|
+
* apart.
|
|
64
|
+
*/
|
|
65
|
+
var createRadiation = () => {
|
|
66
|
+
let previous = 0;
|
|
67
|
+
return (x) => {
|
|
68
|
+
const y = x - previous;
|
|
69
|
+
previous = x;
|
|
70
|
+
return y;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/** Rosenberg glottal pulse; a bare impulse train through the formants sounds like a buzzer. */
|
|
74
|
+
var createGlottalSource = (sampleRate) => {
|
|
75
|
+
const rise = GLOTTAL_OPEN_QUOTIENT * (1 - GLOTTAL_SPEED_QUOTIENT);
|
|
76
|
+
const fall = GLOTTAL_OPEN_QUOTIENT * GLOTTAL_SPEED_QUOTIENT;
|
|
77
|
+
let phase = 0;
|
|
78
|
+
return (f0Hz) => {
|
|
79
|
+
phase += f0Hz / sampleRate;
|
|
80
|
+
if (phase >= 1) phase -= 1;
|
|
81
|
+
if (phase < rise) return .5 * (1 - Math.cos(Math.PI * phase / rise));
|
|
82
|
+
if (phase < GLOTTAL_OPEN_QUOTIENT) return Math.cos(Math.PI / 2 * ((phase - rise) / fall));
|
|
83
|
+
return 0;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
var lerp = (from, to, t) => from + (to - from) * t;
|
|
87
|
+
var isBlendable = (previous, current) => !current.abrupt && !previous.abrupt && previous.excitation !== "silence" && current.excitation !== "silence";
|
|
88
|
+
var buildFrames = (phonemes, voice, sampleRate) => {
|
|
89
|
+
const frames = [];
|
|
90
|
+
const segments = [];
|
|
91
|
+
const scaled = (p) => [
|
|
92
|
+
p.formants[0] * voice.formantScale,
|
|
93
|
+
p.formants[1] * voice.formantScale,
|
|
94
|
+
p.formants[2] * voice.formantScale
|
|
95
|
+
];
|
|
96
|
+
let previous;
|
|
97
|
+
for (const current of phonemes) {
|
|
98
|
+
const lengthSamples = Math.max(1, Math.round(current.durationMs * voice.rate * sampleRate / 1e3));
|
|
99
|
+
const from = previous && isBlendable(previous, current) ? previous : current;
|
|
100
|
+
const blendSamples = from === current ? 0 : Math.floor(lengthSamples / 3);
|
|
101
|
+
const source = scaled(from);
|
|
102
|
+
const target = scaled(current);
|
|
103
|
+
segments.push({
|
|
104
|
+
start: frames.length,
|
|
105
|
+
end: frames.length + lengthSamples,
|
|
106
|
+
targetLevel: current.excitation === "silence" ? 0 : Math.max(current.voiceGain, current.noiseGain)
|
|
107
|
+
});
|
|
108
|
+
for (let n = 0; n < lengthSamples; n++) {
|
|
109
|
+
const t = blendSamples > 0 ? Math.min(1, n / blendSamples) : 1;
|
|
110
|
+
frames.push({
|
|
111
|
+
formants: [
|
|
112
|
+
lerp(source[0], target[0], t),
|
|
113
|
+
lerp(source[1], target[1], t),
|
|
114
|
+
lerp(source[2], target[2], t)
|
|
115
|
+
],
|
|
116
|
+
bandwidths: [
|
|
117
|
+
lerp(from.bandwidths[0], current.bandwidths[0], t),
|
|
118
|
+
lerp(from.bandwidths[1], current.bandwidths[1], t),
|
|
119
|
+
lerp(from.bandwidths[2], current.bandwidths[2], t)
|
|
120
|
+
],
|
|
121
|
+
voiceGain: lerp(from.voiceGain, current.voiceGain, t),
|
|
122
|
+
noiseGain: lerp(from.noiseGain, current.noiseGain, t),
|
|
123
|
+
noiseCentreHz: current.noiseCentreHz,
|
|
124
|
+
noiseBandwidthHz: current.noiseBandwidthHz,
|
|
125
|
+
silent: current.excitation === "silence"
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
previous = current;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
frames,
|
|
132
|
+
segments
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Rescale each segment to its target level, ramping the gain across
|
|
137
|
+
* boundaries: a gain step clicks, and a click at every phoneme boundary is a
|
|
138
|
+
* free segmentation cue for an attacker.
|
|
139
|
+
*/
|
|
140
|
+
var applySegmentLevels = (samples, segments, sampleRate) => {
|
|
141
|
+
const rampLength = Math.max(1, Math.round(sampleRate * LEVEL_RAMP_SECONDS));
|
|
142
|
+
const gains = segments.map((segment) => {
|
|
143
|
+
if (segment.targetLevel <= 0) return 0;
|
|
144
|
+
const level = rms(samples.subarray(segment.start, segment.end));
|
|
145
|
+
return level < SILENT_RMS ? 0 : segment.targetLevel / level;
|
|
146
|
+
});
|
|
147
|
+
const track = new Float32Array(samples.length);
|
|
148
|
+
segments.forEach((segment, i) => {
|
|
149
|
+
track.fill(gains[i] ?? 0, segment.start, segment.end);
|
|
150
|
+
});
|
|
151
|
+
for (let i = 1; i < segments.length; i++) {
|
|
152
|
+
const segment = segments[i];
|
|
153
|
+
const gain = gains[i];
|
|
154
|
+
const previousGain = gains[i - 1];
|
|
155
|
+
if (!segment || gain === void 0 || previousGain === void 0) continue;
|
|
156
|
+
const length = Math.min(rampLength, segment.end - segment.start);
|
|
157
|
+
for (let n = 0; n < length; n++) {
|
|
158
|
+
const index = segment.start + n;
|
|
159
|
+
if (index >= track.length) break;
|
|
160
|
+
const t = .5 * (1 - Math.cos(Math.PI * n / length));
|
|
161
|
+
track[index] = previousGain + (gain - previousGain) * t;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
for (let n = 0; n < samples.length; n++) samples[n] = (samples[n] ?? 0) * (track[n] ?? 0);
|
|
165
|
+
};
|
|
166
|
+
/** Raised-cosine fade in and out, in place. */
|
|
167
|
+
var applyEdgeFade = (samples, fadeLength) => {
|
|
168
|
+
const length = Math.min(fadeLength, Math.floor(samples.length / 2));
|
|
169
|
+
for (let n = 0; n < length; n++) {
|
|
170
|
+
const gain = .5 * (1 - Math.cos(Math.PI * n / length));
|
|
171
|
+
const tail = samples.length - 1 - n;
|
|
172
|
+
samples[n] = (samples[n] ?? 0) * gain;
|
|
173
|
+
samples[tail] = (samples[tail] ?? 0) * gain;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
var synthesiseUtterance = (utterance, voice, prng, sampleRate = SAMPLE_RATE) => {
|
|
177
|
+
const { frames, segments } = buildFrames(utterance.phonemes, voice, sampleRate);
|
|
178
|
+
const out = new Float32Array(frames.length);
|
|
179
|
+
const formantFilters = [
|
|
180
|
+
createResonator(sampleRate),
|
|
181
|
+
createResonator(sampleRate),
|
|
182
|
+
createResonator(sampleRate)
|
|
183
|
+
];
|
|
184
|
+
const noiseFilter = createResonator(sampleRate);
|
|
185
|
+
const glottis = createGlottalSource(sampleRate);
|
|
186
|
+
const radiation = createRadiation();
|
|
187
|
+
const tilt = createOnePoleLowPass(sampleRate, voice.tiltCornerHz);
|
|
188
|
+
const f0Start = voice.f0Hz * (1 + voice.f0DriftRatio / 2);
|
|
189
|
+
const f0End = voice.f0Hz * (1 - voice.f0DriftRatio / 2);
|
|
190
|
+
const jitterDepth = prng.range(.004, .02);
|
|
191
|
+
frames.forEach((frame, n) => {
|
|
192
|
+
if (frame.silent) return;
|
|
193
|
+
const progress = frames.length > 1 ? n / (frames.length - 1) : 0;
|
|
194
|
+
const f0 = lerp(f0Start, f0End, progress) * (1 + jitterDepth * (prng.next() - .5));
|
|
195
|
+
let sample = 0;
|
|
196
|
+
if (frame.voiceGain > 0) {
|
|
197
|
+
let voiced = tilt(glottis(f0));
|
|
198
|
+
for (const k of FORMANT_INDICES) {
|
|
199
|
+
formantFilters[k].setTarget(frame.formants[k], frame.bandwidths[k]);
|
|
200
|
+
voiced = formantFilters[k].process(voiced);
|
|
201
|
+
}
|
|
202
|
+
sample += voiced * frame.voiceGain;
|
|
203
|
+
}
|
|
204
|
+
if (frame.noiseGain > 0) {
|
|
205
|
+
noiseFilter.setTarget(frame.noiseCentreHz, Math.max(frame.noiseBandwidthHz, MIN_NOISE_BANDWIDTH_HZ));
|
|
206
|
+
const noise = prng.next() * 2 - 1;
|
|
207
|
+
sample += noiseFilter.process(noise) * frame.noiseGain;
|
|
208
|
+
}
|
|
209
|
+
out[n] = radiation(sample);
|
|
210
|
+
});
|
|
211
|
+
applySegmentLevels(out, segments, sampleRate);
|
|
212
|
+
applyEdgeFade(out, Math.round(sampleRate * EDGE_FADE_SECONDS));
|
|
213
|
+
normalise(out, WORD_PEAK);
|
|
214
|
+
return {
|
|
215
|
+
samples: out,
|
|
216
|
+
sampleRate
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
//#endregion
|
|
220
|
+
export { SAMPLE_RATE, randomVoice, synthesiseUtterance };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth.js","sourceRoot":"","sources":["../src/synth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioAssets.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/audioAssets.unit.test.ts"],"names":[],"mappings":""}
|