@typeonce/ritmo-tools 0.18.0 → 0.19.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/CHANGELOG.md +38 -0
- package/README.md +304 -24
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/internal/version.d.ts +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/music/cli/commands.d.ts +15 -0
- package/dist/music/cli/commands.d.ts.map +1 -0
- package/dist/music/cli/commands.js +180 -0
- package/dist/music/cli/commands.js.map +1 -0
- package/dist/music/cli/io.d.ts +11 -0
- package/dist/music/cli/io.d.ts.map +1 -0
- package/dist/music/cli/io.js +28 -0
- package/dist/music/cli/io.js.map +1 -0
- package/dist/music/cli/serve.d.ts +13 -0
- package/dist/music/cli/serve.d.ts.map +1 -0
- package/dist/music/cli/serve.js +168 -0
- package/dist/music/cli/serve.js.map +1 -0
- package/dist/music/core/audio.d.ts +22 -0
- package/dist/music/core/audio.d.ts.map +1 -0
- package/dist/music/core/audio.js +95 -0
- package/dist/music/core/audio.js.map +1 -0
- package/dist/music/core/check.d.ts +51 -0
- package/dist/music/core/check.d.ts.map +1 -0
- package/dist/music/core/check.js +113 -0
- package/dist/music/core/check.js.map +1 -0
- package/dist/music/core/instruments.d.ts +179 -0
- package/dist/music/core/instruments.d.ts.map +1 -0
- package/dist/music/core/instruments.js +531 -0
- package/dist/music/core/instruments.js.map +1 -0
- package/dist/music/core/listen.d.ts +32 -0
- package/dist/music/core/listen.d.ts.map +1 -0
- package/dist/music/core/listen.js +350 -0
- package/dist/music/core/listen.js.map +1 -0
- package/dist/music/core/midi.d.ts +4 -0
- package/dist/music/core/midi.d.ts.map +1 -0
- package/dist/music/core/midi.js +76 -0
- package/dist/music/core/midi.js.map +1 -0
- package/dist/music/core/render.d.ts +37 -0
- package/dist/music/core/render.d.ts.map +1 -0
- package/dist/music/core/render.js +204 -0
- package/dist/music/core/render.js.map +1 -0
- package/dist/music/core/review.d.ts +41 -0
- package/dist/music/core/review.d.ts.map +1 -0
- package/dist/music/core/review.js +139 -0
- package/dist/music/core/review.js.map +1 -0
- package/dist/music/core/song.d.ts +144 -0
- package/dist/music/core/song.d.ts.map +1 -0
- package/dist/music/core/song.js +291 -0
- package/dist/music/core/song.js.map +1 -0
- package/dist/music/page/assets/index-BfO_jOqP.js +4 -0
- package/dist/music/page/assets/index-Dw14kxkL.css +1 -0
- package/dist/music/page/index.html +19 -0
- package/dist/pixel/cli/commands.d.ts.map +1 -1
- package/dist/pixel/cli/commands.js +122 -46
- package/dist/pixel/cli/commands.js.map +1 -1
- package/dist/pixel/cli/io.d.ts +5 -1
- package/dist/pixel/cli/io.d.ts.map +1 -1
- package/dist/pixel/cli/io.js +16 -1
- package/dist/pixel/cli/io.js.map +1 -1
- package/dist/pixel/core/animation.d.ts +23 -8
- package/dist/pixel/core/animation.d.ts.map +1 -1
- package/dist/pixel/core/animation.js +41 -18
- package/dist/pixel/core/animation.js.map +1 -1
- package/dist/pixel/core/grid.d.ts +3 -2
- package/dist/pixel/core/grid.d.ts.map +1 -1
- package/dist/pixel/core/grid.js +14 -6
- package/dist/pixel/core/grid.js.map +1 -1
- package/dist/pixel/core/preview.d.ts +8 -3
- package/dist/pixel/core/preview.d.ts.map +1 -1
- package/dist/pixel/core/preview.js +39 -25
- package/dist/pixel/core/preview.js.map +1 -1
- package/dist/pixel/core/project.d.ts +27 -0
- package/dist/pixel/core/project.d.ts.map +1 -0
- package/dist/pixel/core/project.js +117 -0
- package/dist/pixel/core/project.js.map +1 -0
- package/dist/pixel/core/recipe.d.ts.map +1 -1
- package/dist/pixel/core/recipe.js +43 -6
- package/dist/pixel/core/recipe.js.map +1 -1
- package/dist/pixel/core/report.d.ts +21 -3
- package/dist/pixel/core/report.d.ts.map +1 -1
- package/dist/pixel/core/report.js +52 -22
- package/dist/pixel/core/report.js.map +1 -1
- package/dist/pixel/core/sheet.d.ts +68 -8
- package/dist/pixel/core/sheet.d.ts.map +1 -1
- package/dist/pixel/core/sheet.js +250 -32
- package/dist/pixel/core/sheet.js.map +1 -1
- package/dist/pixel/core/spritesheet.d.ts +43 -35
- package/dist/pixel/core/spritesheet.d.ts.map +1 -1
- package/dist/pixel/core/spritesheet.js +63 -59
- package/dist/pixel/core/spritesheet.js.map +1 -1
- package/dist/sound/cli/commands.d.ts +25 -0
- package/dist/sound/cli/commands.d.ts.map +1 -0
- package/dist/sound/cli/commands.js +137 -0
- package/dist/sound/cli/commands.js.map +1 -0
- package/dist/sound/cli/io.d.ts +24 -0
- package/dist/sound/cli/io.d.ts.map +1 -0
- package/dist/sound/cli/io.js +51 -0
- package/dist/sound/cli/io.js.map +1 -0
- package/dist/sound/cli/serve.d.ts +11 -0
- package/dist/sound/cli/serve.d.ts.map +1 -0
- package/dist/sound/cli/serve.js +147 -0
- package/dist/sound/cli/serve.js.map +1 -0
- package/dist/sound/core/measure.d.ts +67 -0
- package/dist/sound/core/measure.d.ts.map +1 -0
- package/dist/sound/core/measure.js +138 -0
- package/dist/sound/core/measure.js.map +1 -0
- package/dist/sound/core/recipe.d.ts +143 -0
- package/dist/sound/core/recipe.d.ts.map +1 -0
- package/dist/sound/core/recipe.js +292 -0
- package/dist/sound/core/recipe.js.map +1 -0
- package/dist/sound/core/render.d.ts +37 -0
- package/dist/sound/core/render.d.ts.map +1 -0
- package/dist/sound/core/render.js +317 -0
- package/dist/sound/core/render.js.map +1 -0
- package/dist/sound/core/review.d.ts +52 -0
- package/dist/sound/core/review.d.ts.map +1 -0
- package/dist/sound/core/review.js +89 -0
- package/dist/sound/core/review.js.map +1 -0
- package/dist/sound/core/takes.d.ts +29 -0
- package/dist/sound/core/takes.d.ts.map +1 -0
- package/dist/sound/core/takes.js +109 -0
- package/dist/sound/core/takes.js.map +1 -0
- package/dist/sound/core/wav.d.ts +4 -0
- package/dist/sound/core/wav.d.ts.map +1 -0
- package/dist/sound/core/wav.js +28 -0
- package/dist/sound/core/wav.js.map +1 -0
- package/dist/sound/page/assets/index-Cjun5b92.js +6 -0
- package/dist/sound/page/assets/index-DZm59wkQ.css +1 -0
- package/dist/sound/page/index.html +19 -0
- package/package.json +10 -4
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns a recipe into samples: mono, 44.1 kHz by default, the same bits in
|
|
3
|
+
* Node and in every browser (noise comes from a seeded generator, not
|
|
4
|
+
* `Math.random`). The instruments follow Web Audio's own (exponential
|
|
5
|
+
* ramps, biquad filters, a wave-shaper curve, a convolution room), so a game
|
|
6
|
+
* that builds the same layers live with Web Audio sounds the same; a game can
|
|
7
|
+
* also play these samples as they are.
|
|
8
|
+
*/
|
|
9
|
+
import { type Layer, type Recipe } from "./recipe.ts";
|
|
10
|
+
export interface RenderOptions {
|
|
11
|
+
readonly sampleRate?: number;
|
|
12
|
+
/** Which take of the noise: two seeds make two slightly different hits of one sound. */
|
|
13
|
+
readonly seed?: number;
|
|
14
|
+
/** The game's master volume over every sound (the bank's `master`), 1 by default. */
|
|
15
|
+
readonly master?: number | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface Rendered {
|
|
18
|
+
readonly sampleRate: number;
|
|
19
|
+
readonly samples: Float32Array<ArrayBuffer>;
|
|
20
|
+
}
|
|
21
|
+
export declare const SAMPLE_RATE = 44100;
|
|
22
|
+
/** A seeded generator of numbers in [0, 1) (mulberry32). */
|
|
23
|
+
export declare const seeded: (seed: number) => (() => number);
|
|
24
|
+
/** Where a layer ends, in seconds from the sound's start. */
|
|
25
|
+
export declare const layerEnd: (layer: Layer) => number;
|
|
26
|
+
/** In place, the FFT of `re` and `im` (their length a power of two); `inverse` without the 1/n. */
|
|
27
|
+
export declare const fft: (re: Float64Array, im: Float64Array, inverse: boolean) => void;
|
|
28
|
+
/** How long the sound's own layers last, in seconds (the room rings past it). */
|
|
29
|
+
export declare const dryLength: (recipe: Recipe) => number;
|
|
30
|
+
/** Renders a recipe, its tune applied, trimmed where its tail falls silent. */
|
|
31
|
+
export declare const render: (recipe: Recipe, options?: RenderOptions) => Rendered;
|
|
32
|
+
/** Several sounds one after another (`at` seconds from the start), mixed: a combo, heard in context. */
|
|
33
|
+
export declare const renderSequence: (parts: ReadonlyArray<{
|
|
34
|
+
readonly recipe: Recipe;
|
|
35
|
+
readonly at: number;
|
|
36
|
+
}>, options?: RenderOptions) => Rendered;
|
|
37
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/sound/core/render.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA0B,KAAK,KAAK,EAAE,KAAK,MAAM,EAAa,MAAM,aAAa,CAAA;AAExF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,CAAA;CAC5C;AAED,eAAO,MAAM,WAAW,QAAQ,CAAA;AAWhC,4DAA4D;AAC5D,eAAO,MAAM,MAAM,SAAU,MAAM,KAAG,CAAC,MAAM,MAAM,CASlD,CAAA;AAqGD,6DAA6D;AAC7D,eAAO,MAAM,QAAQ,UAAW,KAAK,KAAG,MAAkF,CAAA;AA0H1H,mGAAmG;AACnG,eAAO,MAAM,GAAG,OAAQ,YAAY,MAAM,YAAY,WAAW,OAAO,KAAG,IAiC1E,CAAA;AAuDD,iFAAiF;AACjF,eAAO,MAAM,SAAS,WAAY,MAAM,KAAG,MAA4F,CAAA;AAKvI,+EAA+E;AAC/E,eAAO,MAAM,MAAM,WAAY,MAAM,YAAW,aAAa,KAAQ,QAcpE,CAAA;AAED,wGAAwG;AACxG,eAAO,MAAM,cAAc,UAAW,aAAa,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,YAAW,aAAa,KAAQ,QASpI,CAAA"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns a recipe into samples: mono, 44.1 kHz by default, the same bits in
|
|
3
|
+
* Node and in every browser (noise comes from a seeded generator, not
|
|
4
|
+
* `Math.random`). The instruments follow Web Audio's own (exponential
|
|
5
|
+
* ramps, biquad filters, a wave-shaper curve, a convolution room), so a game
|
|
6
|
+
* that builds the same layers live with Web Audio sounds the same; a game can
|
|
7
|
+
* also play these samples as they are.
|
|
8
|
+
*/
|
|
9
|
+
import { applyTune } from "./recipe.js";
|
|
10
|
+
export const SAMPLE_RATE = 44100;
|
|
11
|
+
/** How long the room rings, in seconds. */
|
|
12
|
+
const ROOM = 1.3;
|
|
13
|
+
/** How loud the room returns. */
|
|
14
|
+
const ROOM_LEVEL = 0.9;
|
|
15
|
+
/** Web Audio's ramps start and end here, not at 0 (an exponential ramp cannot reach 0). */
|
|
16
|
+
const FLOOR = 0.0001;
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Small pieces
|
|
19
|
+
/** A seeded generator of numbers in [0, 1) (mulberry32). */
|
|
20
|
+
export const seeded = (seed) => {
|
|
21
|
+
let state = seed >>> 0;
|
|
22
|
+
return () => {
|
|
23
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
24
|
+
let t = state;
|
|
25
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
26
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
27
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/** An exponential ramp from `a` to `b` over `[0, length]`, as Web Audio's `exponentialRampToValueAtTime`. */
|
|
31
|
+
const ramp = (a, b, t, length) => (length <= 0 ? b : a * Math.pow(b / a, Math.min(1, Math.max(0, t / length))));
|
|
32
|
+
/** A layer's loudness at `t` seconds into it: up from silence over `attack`, down to silence at `duration`. */
|
|
33
|
+
const envelope = (t, duration, gain, attack) => {
|
|
34
|
+
if (t < 0 || t >= duration)
|
|
35
|
+
return 0;
|
|
36
|
+
const top = Math.max(0.0002, gain);
|
|
37
|
+
const rise = Math.min(attack, duration * 0.9);
|
|
38
|
+
return t < rise ? ramp(FLOOR, top, t, rise) : ramp(top, FLOOR, t - rise, duration - rise);
|
|
39
|
+
};
|
|
40
|
+
/** Corrects a naive square or sawtooth at its jumps, so high notes do not alias (PolyBLEP). */
|
|
41
|
+
const blep = (phase, step) => {
|
|
42
|
+
if (phase < step) {
|
|
43
|
+
const t = phase / step;
|
|
44
|
+
return t + t - t * t - 1;
|
|
45
|
+
}
|
|
46
|
+
if (phase > 1 - step) {
|
|
47
|
+
const t = (phase - 1) / step;
|
|
48
|
+
return t * t + t + t + 1;
|
|
49
|
+
}
|
|
50
|
+
return 0;
|
|
51
|
+
};
|
|
52
|
+
const oscillator = (wave, phase, step) => {
|
|
53
|
+
switch (wave) {
|
|
54
|
+
case "sine":
|
|
55
|
+
return Math.sin(2 * Math.PI * phase);
|
|
56
|
+
case "triangle":
|
|
57
|
+
return phase < 0.5 ? 4 * phase - 1 : 3 - 4 * phase;
|
|
58
|
+
case "square":
|
|
59
|
+
return (phase < 0.5 ? 1 : -1) + blep(phase, step) - blep((phase + 0.5) % 1, step);
|
|
60
|
+
case "sawtooth":
|
|
61
|
+
return 2 * phase - 1 - blep(phase, step);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* A biquad filter (the RBJ cookbook, as Web Audio's BiquadFilterNode): `q`
|
|
66
|
+
* is in decibels for lowpass and highpass, a plain Q for bandpass. Its
|
|
67
|
+
* frequency can move every few samples.
|
|
68
|
+
*/
|
|
69
|
+
const makeBiquad = (type, q, sampleRate) => {
|
|
70
|
+
let b0 = 0;
|
|
71
|
+
let b1 = 0;
|
|
72
|
+
let b2 = 0;
|
|
73
|
+
let a1 = 0;
|
|
74
|
+
let a2 = 0;
|
|
75
|
+
let x1 = 0;
|
|
76
|
+
let x2 = 0;
|
|
77
|
+
let y1 = 0;
|
|
78
|
+
let y2 = 0;
|
|
79
|
+
const set = (frequency) => {
|
|
80
|
+
const w = (2 * Math.PI * Math.min(frequency, sampleRate * 0.49)) / sampleRate;
|
|
81
|
+
const cos = Math.cos(w);
|
|
82
|
+
const qLinear = type === "bandpass" ? Math.max(0.0001, q) : Math.pow(10, q / 20);
|
|
83
|
+
const alpha = Math.sin(w) / (2 * qLinear);
|
|
84
|
+
const a0 = 1 + alpha;
|
|
85
|
+
if (type === "lowpass") {
|
|
86
|
+
b0 = (1 - cos) / 2 / a0;
|
|
87
|
+
b1 = (1 - cos) / a0;
|
|
88
|
+
b2 = b0;
|
|
89
|
+
}
|
|
90
|
+
else if (type === "highpass") {
|
|
91
|
+
b0 = (1 + cos) / 2 / a0;
|
|
92
|
+
b1 = -(1 + cos) / a0;
|
|
93
|
+
b2 = b0;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
b0 = alpha / a0;
|
|
97
|
+
b1 = 0;
|
|
98
|
+
b2 = -alpha / a0;
|
|
99
|
+
}
|
|
100
|
+
a1 = (-2 * cos) / a0;
|
|
101
|
+
a2 = (1 - alpha) / a0;
|
|
102
|
+
};
|
|
103
|
+
const step = (x) => {
|
|
104
|
+
const y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
|
|
105
|
+
x2 = x1;
|
|
106
|
+
x1 = x;
|
|
107
|
+
y2 = y1;
|
|
108
|
+
y1 = y;
|
|
109
|
+
return y;
|
|
110
|
+
};
|
|
111
|
+
return { set, step };
|
|
112
|
+
};
|
|
113
|
+
/** How often (in samples) a moving filter recomputes itself. */
|
|
114
|
+
const FILTER_STEP = 16;
|
|
115
|
+
/** The metal's partials: [frequency ratio, level, share of the duration]. */
|
|
116
|
+
const PARTIALS = [
|
|
117
|
+
[1, 1, 1],
|
|
118
|
+
[2.76, 0.6, 0.7],
|
|
119
|
+
[5.4, 0.4, 0.45],
|
|
120
|
+
[8.93, 0.25, 0.3]
|
|
121
|
+
];
|
|
122
|
+
/** A click is a noise layer this short and bright. */
|
|
123
|
+
const CLICK = { filter: "highpass", from: 5000, to: 3000, q: 0.8, duration: 0.016, attack: 0.001 };
|
|
124
|
+
/** Where a layer ends, in seconds from the sound's start. */
|
|
125
|
+
export const layerEnd = (layer) => layer.delay + (layer.type === "click" ? CLICK.duration : layer.duration);
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Instruments: each adds its layer into `out`
|
|
128
|
+
const addTone = (out, rate, wave, from, to, duration, gain, delay, attack) => {
|
|
129
|
+
const start = Math.round(delay * rate);
|
|
130
|
+
const count = Math.ceil(duration * rate);
|
|
131
|
+
let phase = 0;
|
|
132
|
+
for (let i = 0; i < count && start + i < out.length; i++) {
|
|
133
|
+
const t = i / rate;
|
|
134
|
+
const frequency = ramp(from, Math.max(1, to), t, duration);
|
|
135
|
+
const step = frequency / rate;
|
|
136
|
+
out[start + i] += oscillator(wave, phase, step) * envelope(t, duration, gain, attack);
|
|
137
|
+
phase += step;
|
|
138
|
+
phase -= Math.floor(phase);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Filtered noise. `frequency` gives the filter's frequency at `t`, `level`
|
|
143
|
+
* the loudness; `shape` bends each sample after the filter (the crunch's
|
|
144
|
+
* distortion).
|
|
145
|
+
*/
|
|
146
|
+
const addNoise = (out, rate, random, filter, q, delay, duration, frequency, level, shape) => {
|
|
147
|
+
const start = Math.round(delay * rate);
|
|
148
|
+
const count = Math.ceil(duration * rate);
|
|
149
|
+
const biquad = makeBiquad(filter, q, rate);
|
|
150
|
+
for (let i = 0; i < count && start + i < out.length; i++) {
|
|
151
|
+
const t = i / rate;
|
|
152
|
+
if (i % FILTER_STEP === 0)
|
|
153
|
+
biquad.set(frequency(t));
|
|
154
|
+
let x = biquad.step(random() * 2 - 1);
|
|
155
|
+
if (shape !== undefined)
|
|
156
|
+
x = shape(x);
|
|
157
|
+
out[start + i] += x * level(t);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
/** The crunch's distortion: 6× drive into a tanh curve, clamped as Web Audio's wave shaper clamps its input. */
|
|
161
|
+
const crunchShape = (x) => Math.tanh(3 * Math.max(-1, Math.min(1, x * 6)));
|
|
162
|
+
const addLayer = (out, rate, layer, random) => {
|
|
163
|
+
switch (layer.type) {
|
|
164
|
+
case "tone":
|
|
165
|
+
addTone(out, rate, layer.wave, layer.from, layer.to, layer.duration, layer.gain, layer.delay, layer.attack);
|
|
166
|
+
return;
|
|
167
|
+
case "noise":
|
|
168
|
+
addNoise(out, rate, random, layer.filter, layer.q, layer.delay, layer.duration, (t) => ramp(layer.from, Math.max(1, layer.to), t, layer.duration), (t) => envelope(t, layer.duration, layer.gain, layer.attack));
|
|
169
|
+
return;
|
|
170
|
+
case "click":
|
|
171
|
+
addNoise(out, rate, random, CLICK.filter, CLICK.q, layer.delay, CLICK.duration, (t) => ramp(CLICK.from, CLICK.to, t, CLICK.duration), (t) => envelope(t, CLICK.duration, layer.gain, CLICK.attack));
|
|
172
|
+
return;
|
|
173
|
+
case "swish": {
|
|
174
|
+
const top = layer.duration * layer.peakAt;
|
|
175
|
+
addNoise(out, rate, random, "bandpass", layer.q, layer.delay, layer.duration, (t) => (t < top ? ramp(layer.low, layer.peak, t, top) : ramp(layer.peak, layer.low * 0.8, t - top, layer.duration - top)), (t) => (t < top ? ramp(FLOOR, Math.max(0.0002, layer.gain), t, top) : ramp(Math.max(0.0002, layer.gain), FLOOR, t - top, layer.duration - top)));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
case "crunch":
|
|
179
|
+
addNoise(out, rate, random, "bandpass", 1.4, layer.delay, layer.duration, (t) => ramp(layer.from, Math.max(1, layer.to), t, layer.duration), (t) => envelope(t, layer.duration, layer.gain, 0.002), crunchShape);
|
|
180
|
+
return;
|
|
181
|
+
case "metal":
|
|
182
|
+
for (const [ratio, level, share] of PARTIALS) {
|
|
183
|
+
addTone(out, rate, "sine", layer.pitch * ratio, layer.pitch * ratio * 0.998, layer.duration * share, layer.gain * level, layer.delay, 0.002);
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// The room
|
|
190
|
+
/** In place, the FFT of `re` and `im` (their length a power of two); `inverse` without the 1/n. */
|
|
191
|
+
export const fft = (re, im, inverse) => {
|
|
192
|
+
const n = re.length;
|
|
193
|
+
for (let i = 1, j = 0; i < n; i++) {
|
|
194
|
+
let bit = n >> 1;
|
|
195
|
+
for (; j & bit; bit >>= 1)
|
|
196
|
+
j ^= bit;
|
|
197
|
+
j ^= bit;
|
|
198
|
+
if (i < j) {
|
|
199
|
+
;
|
|
200
|
+
[re[i], re[j]] = [re[j], re[i]];
|
|
201
|
+
[im[i], im[j]] = [im[j], im[i]];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
for (let size = 2; size <= n; size <<= 1) {
|
|
205
|
+
const angle = ((inverse ? 2 : -2) * Math.PI) / size;
|
|
206
|
+
const wr = Math.cos(angle);
|
|
207
|
+
const wi = Math.sin(angle);
|
|
208
|
+
for (let i = 0; i < n; i += size) {
|
|
209
|
+
let cr = 1;
|
|
210
|
+
let ci = 0;
|
|
211
|
+
for (let k = 0; k < size / 2; k++) {
|
|
212
|
+
const a = i + k;
|
|
213
|
+
const b = a + size / 2;
|
|
214
|
+
const tr = re[b] * cr - im[b] * ci;
|
|
215
|
+
const ti = re[b] * ci + im[b] * cr;
|
|
216
|
+
re[b] = re[a] - tr;
|
|
217
|
+
im[b] = im[a] - ti;
|
|
218
|
+
re[a] = re[a] + tr;
|
|
219
|
+
im[a] = im[a] + ti;
|
|
220
|
+
const next = cr * wr - ci * wi;
|
|
221
|
+
ci = cr * wi + ci * wr;
|
|
222
|
+
cr = next;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
/** The room's impulse: noise decaying over `ROOM` seconds, darker as it fades (air takes the highs first). */
|
|
228
|
+
const roomImpulse = (rate) => {
|
|
229
|
+
const random = seeded(0x5eed);
|
|
230
|
+
const length = Math.floor(rate * ROOM);
|
|
231
|
+
const preDelay = Math.floor(rate * 0.012);
|
|
232
|
+
const impulse = new Float64Array(length);
|
|
233
|
+
let smooth = 0;
|
|
234
|
+
let power = 0;
|
|
235
|
+
for (let i = preDelay; i < length; i++) {
|
|
236
|
+
const t = (i - preDelay) / (length - preDelay);
|
|
237
|
+
const darken = 0.15 + 0.8 * t;
|
|
238
|
+
smooth = smooth * darken + (random() * 2 - 1) * (1 - darken);
|
|
239
|
+
impulse[i] = smooth * Math.pow(1 - t, 3) * (1.6 + 2 * t);
|
|
240
|
+
power += impulse[i] * impulse[i];
|
|
241
|
+
}
|
|
242
|
+
// Normalized as Web Audio's ConvolverNode normalizes its buffer.
|
|
243
|
+
const scale = 0.00125 / Math.sqrt(power / length);
|
|
244
|
+
for (let i = 0; i < length; i++)
|
|
245
|
+
impulse[i] *= scale;
|
|
246
|
+
return impulse;
|
|
247
|
+
};
|
|
248
|
+
const rooms = new Map();
|
|
249
|
+
/** The sound in the room: its own samples convolved with the room's impulse, `send` of it. */
|
|
250
|
+
const addRoom = (out, dryLength, rate, send) => {
|
|
251
|
+
if (send <= 0)
|
|
252
|
+
return;
|
|
253
|
+
let size = 1;
|
|
254
|
+
while (size < dryLength + Math.floor(rate * ROOM))
|
|
255
|
+
size <<= 1;
|
|
256
|
+
let room = rooms.get(rate);
|
|
257
|
+
if (room === undefined || room.size !== size) {
|
|
258
|
+
const impulse = roomImpulse(rate);
|
|
259
|
+
const re = new Float64Array(size);
|
|
260
|
+
const im = new Float64Array(size);
|
|
261
|
+
re.set(impulse);
|
|
262
|
+
fft(re, im, false);
|
|
263
|
+
room = { size, re, im };
|
|
264
|
+
rooms.set(rate, room);
|
|
265
|
+
}
|
|
266
|
+
const re = new Float64Array(size);
|
|
267
|
+
const im = new Float64Array(size);
|
|
268
|
+
for (let i = 0; i < dryLength; i++)
|
|
269
|
+
re[i] = out[i] * send;
|
|
270
|
+
fft(re, im, false);
|
|
271
|
+
for (let i = 0; i < size; i++) {
|
|
272
|
+
const r = re[i] * room.re[i] - im[i] * room.im[i];
|
|
273
|
+
im[i] = re[i] * room.im[i] + im[i] * room.re[i];
|
|
274
|
+
re[i] = r;
|
|
275
|
+
}
|
|
276
|
+
fft(re, im, true);
|
|
277
|
+
for (let i = 0; i < out.length && i < size; i++)
|
|
278
|
+
out[i] += (re[i] / size) * ROOM_LEVEL;
|
|
279
|
+
};
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
/** How long the sound's own layers last, in seconds (the room rings past it). */
|
|
282
|
+
export const dryLength = (recipe) => applyTune(recipe).layers.reduce((end, layer) => Math.max(end, layerEnd(layer)), 0);
|
|
283
|
+
/** Below this, a sample counts as silence when trimming the tail (-80 dBFS). */
|
|
284
|
+
const SILENCE = 0.0001;
|
|
285
|
+
/** Renders a recipe, its tune applied, trimmed where its tail falls silent. */
|
|
286
|
+
export const render = (recipe, options = {}) => {
|
|
287
|
+
const rate = options.sampleRate ?? SAMPLE_RATE;
|
|
288
|
+
const played = applyTune(recipe);
|
|
289
|
+
const random = seeded(options.seed ?? 1);
|
|
290
|
+
const dry = Math.ceil((dryLength(played) + 0.02) * rate);
|
|
291
|
+
const total = dry + (played.reverb > 0 ? Math.ceil(ROOM * rate) : 0);
|
|
292
|
+
const out = new Float32Array(total);
|
|
293
|
+
for (const layer of played.layers)
|
|
294
|
+
addLayer(out, rate, layer, random);
|
|
295
|
+
addRoom(out, dry, rate, played.reverb);
|
|
296
|
+
const master = options.master ?? 1;
|
|
297
|
+
if (master !== 1)
|
|
298
|
+
for (let i = 0; i < out.length; i++)
|
|
299
|
+
out[i] *= master;
|
|
300
|
+
let end = total;
|
|
301
|
+
while (end > 1 && Math.abs(out[end - 1]) < SILENCE)
|
|
302
|
+
end--;
|
|
303
|
+
return { sampleRate: rate, samples: out.slice(0, end) };
|
|
304
|
+
};
|
|
305
|
+
/** Several sounds one after another (`at` seconds from the start), mixed: a combo, heard in context. */
|
|
306
|
+
export const renderSequence = (parts, options = {}) => {
|
|
307
|
+
const rate = options.sampleRate ?? SAMPLE_RATE;
|
|
308
|
+
const rendered = parts.map((part, i) => ({ at: Math.round(part.at * rate), sound: render(part.recipe, { ...options, seed: (options.seed ?? 1) + i }) }));
|
|
309
|
+
const length = rendered.reduce((end, part) => Math.max(end, part.at + part.sound.samples.length), 0);
|
|
310
|
+
const out = new Float32Array(length);
|
|
311
|
+
for (const part of rendered) {
|
|
312
|
+
for (let i = 0; i < part.sound.samples.length; i++)
|
|
313
|
+
out[part.at + i] += part.sound.samples[i];
|
|
314
|
+
}
|
|
315
|
+
return { sampleRate: rate, samples: out };
|
|
316
|
+
};
|
|
317
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/sound/core/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The review: what a person said about each sound, kept in a file next to
|
|
3
|
+
* the bank (`game.sounds.json` → `game.sounds.review.json`) so the agent can
|
|
4
|
+
* read it. Each sound has a status (new, approved, or changes asked), a
|
|
5
|
+
* note in the person's words, and the takes the agent offered.
|
|
6
|
+
*
|
|
7
|
+
* The page writes picks straight into the bank (the chosen take becomes the
|
|
8
|
+
* sound), so the bank is always what the person last chose; the review
|
|
9
|
+
* holds only what words and choices can say about it.
|
|
10
|
+
*/
|
|
11
|
+
import { type Decoded } from "./recipe.ts";
|
|
12
|
+
import { type Take, type Toward } from "./takes.ts";
|
|
13
|
+
export type Status = "new" | "approved" | "changes";
|
|
14
|
+
export declare const statuses: ReadonlyArray<Status>;
|
|
15
|
+
export interface SoundReview {
|
|
16
|
+
readonly status: Status;
|
|
17
|
+
/** The person's words: what to change, or why it is right. */
|
|
18
|
+
readonly note: string;
|
|
19
|
+
/** The takes offered, and what they were made toward. */
|
|
20
|
+
readonly takes: ReadonlyArray<Take>;
|
|
21
|
+
readonly toward?: Toward | undefined;
|
|
22
|
+
/** The take the person chose (it is now the sound in the bank). */
|
|
23
|
+
readonly picked?: string | undefined;
|
|
24
|
+
}
|
|
25
|
+
export interface Review {
|
|
26
|
+
readonly sounds: Readonly<Record<string, SoundReview>>;
|
|
27
|
+
}
|
|
28
|
+
export declare const emptyReview: Review;
|
|
29
|
+
export declare const newSound: SoundReview;
|
|
30
|
+
/** Where a bank's review lives. */
|
|
31
|
+
export declare const reviewPath: (bankPath: string) => string;
|
|
32
|
+
export declare const decodeReview: (text: string) => Decoded<Review>;
|
|
33
|
+
export declare const encodeReview: (review: Review) => string;
|
|
34
|
+
/** What the agent needs from a review: every sound's status and note, and what is still to do. */
|
|
35
|
+
export declare const reviewSummary: (names: ReadonlyArray<string>, review: Review) => {
|
|
36
|
+
summary: string;
|
|
37
|
+
changes: {
|
|
38
|
+
name: string;
|
|
39
|
+
status: Status;
|
|
40
|
+
note: string | undefined;
|
|
41
|
+
picked: string | undefined;
|
|
42
|
+
takes: number;
|
|
43
|
+
}[];
|
|
44
|
+
sounds: {
|
|
45
|
+
name: string;
|
|
46
|
+
status: Status;
|
|
47
|
+
note: string | undefined;
|
|
48
|
+
picked: string | undefined;
|
|
49
|
+
takes: number;
|
|
50
|
+
}[];
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/sound/core/review.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAkC,KAAK,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAW,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAE5D,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAA;AACnD,eAAO,MAAM,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAkC,CAAA;AAE7E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,WAAW,EAAE,MAAuB,CAAA;AACjD,eAAO,MAAM,QAAQ,EAAE,WAAoD,CAAA;AAE3E,mCAAmC;AACnC,eAAO,MAAM,UAAU,aAAc,MAAM,KAAG,MAAuG,CAAA;AAIrJ,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAqCzD,CAAA;AAED,eAAO,MAAM,YAAY,WAAY,MAAM,KAAG,MAY7C,CAAA;AAED,kGAAkG;AAClG,eAAO,MAAM,aAAa,UAAW,aAAa,CAAC,MAAM,CAAC,UAAU,MAAM;;;;;;;;;;;;;;;;CAYzE,CAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The review: what a person said about each sound, kept in a file next to
|
|
3
|
+
* the bank (`game.sounds.json` → `game.sounds.review.json`) so the agent can
|
|
4
|
+
* read it. Each sound has a status (new, approved, or changes asked), a
|
|
5
|
+
* note in the person's words, and the takes the agent offered.
|
|
6
|
+
*
|
|
7
|
+
* The page writes picks straight into the bank (the chosen take becomes the
|
|
8
|
+
* sound), so the bank is always what the person last chose; the review
|
|
9
|
+
* holds only what words and choices can say about it.
|
|
10
|
+
*/
|
|
11
|
+
import { decodeRecipeValue, recipeValue } from "./recipe.js";
|
|
12
|
+
import { towards } from "./takes.js";
|
|
13
|
+
export const statuses = ["new", "approved", "changes"];
|
|
14
|
+
export const emptyReview = { sounds: {} };
|
|
15
|
+
export const newSound = { status: "new", note: "", takes: [] };
|
|
16
|
+
/** Where a bank's review lives. */
|
|
17
|
+
export const reviewPath = (bankPath) => (bankPath.endsWith(".json") ? bankPath.slice(0, -".json".length) : bankPath) + ".review.json";
|
|
18
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
|
+
export const decodeReview = (text) => {
|
|
20
|
+
let raw;
|
|
21
|
+
try {
|
|
22
|
+
raw = JSON.parse(text);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
return { ok: false, error: `not JSON: ${error instanceof Error ? error.message : String(error)}` };
|
|
26
|
+
}
|
|
27
|
+
if (!isRecord(raw) || !isRecord(raw.sounds))
|
|
28
|
+
return { ok: false, error: 'a review is {"version": 1, "sounds": {"name": {"status": ..., "note": ...}}}' };
|
|
29
|
+
const errors = [];
|
|
30
|
+
const sounds = {};
|
|
31
|
+
for (const [name, value] of Object.entries(raw.sounds)) {
|
|
32
|
+
if (!isRecord(value)) {
|
|
33
|
+
errors.push(`${name} must be an object`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const status = statuses.find((entry) => entry === value.status);
|
|
37
|
+
if (value.status !== undefined && status === undefined)
|
|
38
|
+
errors.push(`${name}.status must be one of ${statuses.join(", ")}`);
|
|
39
|
+
const takes = [];
|
|
40
|
+
if (value.takes !== undefined && !Array.isArray(value.takes))
|
|
41
|
+
errors.push(`${name}.takes must be a list`);
|
|
42
|
+
for (const [i, take] of (Array.isArray(value.takes) ? value.takes : []).entries()) {
|
|
43
|
+
if (!isRecord(take) || typeof take.id !== "string") {
|
|
44
|
+
errors.push(`${name}.takes[${i}] needs an id`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const recipe = decodeRecipeValue(take.recipe, `${name}.takes[${i}].recipe`, errors);
|
|
48
|
+
if (recipe !== undefined)
|
|
49
|
+
takes.push({ id: take.id, label: typeof take.label === "string" ? take.label : "", recipe });
|
|
50
|
+
}
|
|
51
|
+
const toward = towards.find((entry) => entry.id === value.toward)?.id;
|
|
52
|
+
sounds[name] = {
|
|
53
|
+
status: status ?? "new",
|
|
54
|
+
note: typeof value.note === "string" ? value.note : "",
|
|
55
|
+
takes,
|
|
56
|
+
toward,
|
|
57
|
+
picked: typeof value.picked === "string" ? value.picked : undefined
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return errors.length > 0 ? { ok: false, error: errors.join("; ") } : { ok: true, value: { sounds } };
|
|
61
|
+
};
|
|
62
|
+
export const encodeReview = (review) => {
|
|
63
|
+
const sounds = {};
|
|
64
|
+
for (const [name, entry] of Object.entries(review.sounds)) {
|
|
65
|
+
sounds[name] = {
|
|
66
|
+
status: entry.status,
|
|
67
|
+
...(entry.note === "" ? {} : { note: entry.note }),
|
|
68
|
+
...(entry.picked === undefined ? {} : { picked: entry.picked }),
|
|
69
|
+
...(entry.toward === undefined ? {} : { toward: entry.toward }),
|
|
70
|
+
...(entry.takes.length === 0 ? {} : { takes: entry.takes.map((take) => ({ id: take.id, label: take.label, recipe: recipeValue(take.recipe) })) })
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return JSON.stringify({ version: 1, sounds }, null, 2) + "\n";
|
|
74
|
+
};
|
|
75
|
+
/** What the agent needs from a review: every sound's status and note, and what is still to do. */
|
|
76
|
+
export const reviewSummary = (names, review) => {
|
|
77
|
+
const of = (name) => review.sounds[name] ?? newSound;
|
|
78
|
+
const sounds = names.map((name) => {
|
|
79
|
+
const entry = of(name);
|
|
80
|
+
return { name, status: entry.status, note: entry.note === "" ? undefined : entry.note, picked: entry.picked, takes: entry.takes.length };
|
|
81
|
+
});
|
|
82
|
+
const count = (status) => sounds.filter((sound) => sound.status === status).length;
|
|
83
|
+
return {
|
|
84
|
+
summary: `${count("approved")} approved, ${count("changes")} with changes asked, ${count("new")} not reviewed yet (of ${names.length}).`,
|
|
85
|
+
changes: sounds.filter((sound) => sound.status === "changes"),
|
|
86
|
+
sounds
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/sound/core/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Takes: other versions of a sound for a person to choose from. The agent
|
|
3
|
+
* (or the page) makes a few at once, each nudged toward what was asked
|
|
4
|
+
* ("heavier", "brighter") and a little different from the others, and the
|
|
5
|
+
* person picks the one that sounds right. Picking is quicker and surer than
|
|
6
|
+
* describing a sound in words.
|
|
7
|
+
*/
|
|
8
|
+
import { type Recipe } from "./recipe.ts";
|
|
9
|
+
export type Toward = "heavier" | "lighter" | "brighter" | "darker" | "shorter" | "longer" | "punchier" | "softer" | "wider";
|
|
10
|
+
export declare const towards: ReadonlyArray<{
|
|
11
|
+
readonly id: Toward;
|
|
12
|
+
readonly label: string;
|
|
13
|
+
readonly hint: string;
|
|
14
|
+
}>;
|
|
15
|
+
export interface Take {
|
|
16
|
+
/** Unique within the sound's takes: "t1", "t2", ... */
|
|
17
|
+
readonly id: string;
|
|
18
|
+
/** What changed, in a few words: "2.1 semitones lower, 18% longer". */
|
|
19
|
+
readonly label: string;
|
|
20
|
+
readonly recipe: Recipe;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `count` takes of a recipe, pushed `toward` a direction. Each take moves
|
|
24
|
+
* the whole sound (so it stays itself) and each layer a little on its own
|
|
25
|
+
* (so the takes differ in character, not only in pitch). The same seed
|
|
26
|
+
* makes the same takes. A tune on the recipe is folded into the takes.
|
|
27
|
+
*/
|
|
28
|
+
export declare const makeTakes: (recipe: Recipe, toward: Toward, count: number, seed?: number) => Array<Take>;
|
|
29
|
+
//# sourceMappingURL=takes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"takes.d.ts","sourceRoot":"","sources":["../../../src/sound/core/takes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAGhE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE3H,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUzG,CAAA;AAED,MAAM,WAAW,IAAI;IACnB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAsCD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,WAAY,MAAM,UAAU,MAAM,SAAS,MAAM,oBAAa,KAAK,CAAC,IAAI,CAmC7F,CAAA"}
|