@openvalle/engine 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +64 -2
- package/dist/connection.d.ts +36 -0
- package/dist/element.d.ts +11 -0
- package/dist/element.js +85 -0
- package/dist/export.d.ts +25 -0
- package/dist/export.js +83 -0
- package/dist/index-19acnyeh.js +12 -0
- package/dist/index-5vzwpwd6.js +388 -0
- package/dist/index-cm27tnmf.js +120 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +12 -0
- package/dist/messages.d.ts +116 -0
- package/dist/sound.js +81 -0
- package/dist/valle_web_bg.wasm +0 -0
- package/dist/worker.js +33873 -0
- package/package.json +30 -4
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/** A file a page gives in place of fetching a path: its bytes, or where to fetch them. */
|
|
2
|
+
export type Source = string | Blob | ArrayBuffer | Uint8Array;
|
|
3
|
+
/** What a scene's controls are bound to: props and data by name, and the files of resources. */
|
|
4
|
+
export type Inputs = {
|
|
5
|
+
props: Record<string, unknown>;
|
|
6
|
+
data: Record<string, unknown>;
|
|
7
|
+
/** Each resource's files, as paths the worker reads. */
|
|
8
|
+
resources: Record<string, string[]>;
|
|
9
|
+
};
|
|
10
|
+
export type Request = {
|
|
11
|
+
type: "start";
|
|
12
|
+
canvas: OffscreenCanvas;
|
|
13
|
+
/** The address relative paths are fetched from. */
|
|
14
|
+
base: string;
|
|
15
|
+
/** Where the built-in fonts are fetched from, by their file names, if not their own addresses. */
|
|
16
|
+
fonts?: string;
|
|
17
|
+
/** Whether files are fetched through the page, which answers `{ fetch: id, url }`. */
|
|
18
|
+
proxied: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
type: "give";
|
|
21
|
+
files: Record<string, Source>;
|
|
22
|
+
} | {
|
|
23
|
+
type: "open";
|
|
24
|
+
entry: string;
|
|
25
|
+
inputs: Inputs;
|
|
26
|
+
} | {
|
|
27
|
+
type: "frame";
|
|
28
|
+
index: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: "pixels";
|
|
31
|
+
}
|
|
32
|
+
/** Draws frame `index` off the canvas, and answers its pixels as `pixels` does. */
|
|
33
|
+
| {
|
|
34
|
+
type: "still";
|
|
35
|
+
index: number;
|
|
36
|
+
}
|
|
37
|
+
/** Mixes the timeline's sound: its length in samples, or null where it has none. */
|
|
38
|
+
| {
|
|
39
|
+
type: "sound";
|
|
40
|
+
entry: string;
|
|
41
|
+
}
|
|
42
|
+
/** `samples` of it from `sample`, interleaved stereo. */
|
|
43
|
+
| {
|
|
44
|
+
type: "render-sound";
|
|
45
|
+
sample: number;
|
|
46
|
+
samples: number;
|
|
47
|
+
}
|
|
48
|
+
/** The MP4 of what is open; the worker says how far it is as `{ progress: id, done }`. */
|
|
49
|
+
| {
|
|
50
|
+
type: "export";
|
|
51
|
+
options: ExportOptions;
|
|
52
|
+
}
|
|
53
|
+
/** The port the audio worklet asks for the sound it plays at. */
|
|
54
|
+
| {
|
|
55
|
+
type: "worklet";
|
|
56
|
+
port: MessagePort;
|
|
57
|
+
} | {
|
|
58
|
+
type: "close";
|
|
59
|
+
} | {
|
|
60
|
+
type: "destroy";
|
|
61
|
+
};
|
|
62
|
+
/** How an export encodes what is open: H.264 of `width` × `height`, the frames fitted in whole,
|
|
63
|
+
* at `rate` frames a second, `bitrate` bits a second, with the sound or not. */
|
|
64
|
+
export type ExportOptions = {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
rate: [number, number];
|
|
68
|
+
bitrate: number;
|
|
69
|
+
audio: boolean;
|
|
70
|
+
};
|
|
71
|
+
/** The composition and the controls of what is open. */
|
|
72
|
+
export type Opened = {
|
|
73
|
+
width: number;
|
|
74
|
+
height: number;
|
|
75
|
+
/** Frames a second, as a whole number or a fraction such as `30000/1001`. */
|
|
76
|
+
fps: string;
|
|
77
|
+
frames: number;
|
|
78
|
+
duration: number;
|
|
79
|
+
loop: boolean;
|
|
80
|
+
controls: Controls;
|
|
81
|
+
};
|
|
82
|
+
/** What a scene's controls take, as `defineProps`, `defineData` and `defineResources` declare them. */
|
|
83
|
+
export type Controls = {
|
|
84
|
+
props: Record<string, Control>;
|
|
85
|
+
data: Record<string, Control>;
|
|
86
|
+
resources: Record<string, {
|
|
87
|
+
kind: string;
|
|
88
|
+
default?: string[];
|
|
89
|
+
}>;
|
|
90
|
+
};
|
|
91
|
+
export type Control = {
|
|
92
|
+
type: string;
|
|
93
|
+
default?: unknown;
|
|
94
|
+
required?: boolean;
|
|
95
|
+
label?: string;
|
|
96
|
+
min?: number;
|
|
97
|
+
max?: number;
|
|
98
|
+
step?: number;
|
|
99
|
+
values?: unknown[];
|
|
100
|
+
};
|
|
101
|
+
/** Why a request failed: `no-webgpu`, a `file` that could not be fetched, the `scene`'s error (a
|
|
102
|
+
* value that does not fit its control among them), or an export `cancelled`. */
|
|
103
|
+
export type Code = "no-webgpu" | "file" | "scene" | "cancelled";
|
|
104
|
+
export type Reply = {
|
|
105
|
+
id: number;
|
|
106
|
+
} & ({
|
|
107
|
+
ok: true;
|
|
108
|
+
value?: unknown;
|
|
109
|
+
} | {
|
|
110
|
+
ok: false;
|
|
111
|
+
code: Code;
|
|
112
|
+
message: string;
|
|
113
|
+
});
|
|
114
|
+
/** The composition's frame at each frame of an export at `rate`: its own at its own rate, else
|
|
115
|
+
* the one at each frame's time. */
|
|
116
|
+
export declare function exportFrames(composition: Opened, rate: [number, number]): number[];
|
package/dist/sound.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// web/packages/engine/src/sound.ts
|
|
2
|
+
var AHEAD = 0.25;
|
|
3
|
+
|
|
4
|
+
class Player extends AudioWorkletProcessor {
|
|
5
|
+
#source;
|
|
6
|
+
#gen = -1;
|
|
7
|
+
#chunks = [];
|
|
8
|
+
#offset = 0;
|
|
9
|
+
#queued = 0;
|
|
10
|
+
#asked = false;
|
|
11
|
+
#started = false;
|
|
12
|
+
#late = 0;
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.port.onmessage = (event) => {
|
|
16
|
+
const message = event.data;
|
|
17
|
+
if (message.port) {
|
|
18
|
+
this.#source = message.port;
|
|
19
|
+
this.#source.onmessage = (e) => this.#chunk(e.data.gen, e.data.data);
|
|
20
|
+
} else if (message.start !== undefined) {
|
|
21
|
+
this.#reset(message.start);
|
|
22
|
+
this.#asked = true;
|
|
23
|
+
this.#source?.postMessage({ gen: this.#gen, sample: message.sample });
|
|
24
|
+
} else if (message.stop) {
|
|
25
|
+
this.#reset(-1);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
#reset(gen) {
|
|
30
|
+
this.#gen = gen;
|
|
31
|
+
this.#chunks = [];
|
|
32
|
+
this.#offset = 0;
|
|
33
|
+
this.#queued = 0;
|
|
34
|
+
this.#asked = false;
|
|
35
|
+
this.#started = false;
|
|
36
|
+
this.#late = 0;
|
|
37
|
+
}
|
|
38
|
+
#chunk(gen, data) {
|
|
39
|
+
if (gen !== this.#gen) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.#asked = false;
|
|
43
|
+
const dropped = Math.min(this.#late, data.length / 2);
|
|
44
|
+
this.#late -= dropped;
|
|
45
|
+
if (dropped < data.length / 2) {
|
|
46
|
+
this.#chunks.push(data.subarray(2 * dropped));
|
|
47
|
+
this.#queued += data.length / 2 - dropped;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
process(_, outputs) {
|
|
51
|
+
const [left, right] = outputs[0];
|
|
52
|
+
let i = 0;
|
|
53
|
+
while (i < left.length && this.#chunks.length > 0) {
|
|
54
|
+
if (!this.#started) {
|
|
55
|
+
this.#started = true;
|
|
56
|
+
this.port.postMessage({ started: this.#gen, frame: currentFrame + i });
|
|
57
|
+
}
|
|
58
|
+
const chunk = this.#chunks[0];
|
|
59
|
+
for (;i < left.length && this.#offset < chunk.length; i++, this.#offset += 2) {
|
|
60
|
+
left[i] = chunk[this.#offset];
|
|
61
|
+
right[i] = chunk[this.#offset + 1];
|
|
62
|
+
}
|
|
63
|
+
if (this.#offset >= chunk.length) {
|
|
64
|
+
this.#chunks.shift();
|
|
65
|
+
this.#offset = 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
this.#queued -= i;
|
|
69
|
+
if (this.#started) {
|
|
70
|
+
this.#late += left.length - i;
|
|
71
|
+
}
|
|
72
|
+
left.fill(0, i);
|
|
73
|
+
right.fill(0, i);
|
|
74
|
+
if (this.#gen >= 0 && !this.#asked && this.#queued < AHEAD * sampleRate) {
|
|
75
|
+
this.#asked = true;
|
|
76
|
+
this.#source?.postMessage({ gen: this.#gen });
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
registerProcessor("valle-sound", Player);
|
|
Binary file
|