@msb235/blits 0.7.1 → 0.8.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 +180 -0
- package/README.md +22 -4
- package/dist/book.js +4 -4
- package/dist/chain.d.ts +1 -1
- package/dist/chain.js +57 -54
- package/dist/channels.d.ts +26 -5
- package/dist/channels.js +12 -8
- package/dist/clock.d.ts +8 -1
- package/dist/clock.js +14 -3
- package/dist/clone.d.ts +3 -0
- package/dist/clone.js +16 -1
- package/dist/closed.d.ts +1 -1
- package/dist/closed.js +3 -2
- package/dist/color.d.ts +0 -11
- package/dist/color.js +4 -24
- package/dist/columns.js +0 -1
- package/dist/copyout.d.ts +6 -0
- package/dist/copyout.js +38 -0
- package/dist/crowd.d.ts +7 -5
- package/dist/crowd.js +32 -18
- package/dist/cue.d.ts +3 -1
- package/dist/cue.js +31 -20
- package/dist/departed.d.ts +34 -0
- package/dist/departed.js +73 -0
- package/dist/easing.d.ts +5 -0
- package/dist/easing.js +31 -2
- package/dist/everyone.d.ts +56 -0
- package/dist/everyone.js +221 -0
- package/dist/fade.d.ts +8 -1
- package/dist/fade.js +34 -6
- package/dist/fill.d.ts +22 -13
- package/dist/fill.js +104 -41
- package/dist/fit.js +2 -1
- package/dist/fold.d.ts +37 -0
- package/dist/fold.js +213 -28
- package/dist/gather.d.ts +15 -9
- package/dist/gather.js +60 -25
- package/dist/gone.js +10 -0
- package/dist/handle.d.ts +16 -5
- package/dist/handle.js +56 -6
- package/dist/held.d.ts +8 -5
- package/dist/held.js +56 -58
- package/dist/history.d.ts +17 -13
- package/dist/history.js +47 -28
- package/dist/hosts.js +55 -8
- package/dist/index.d.ts +9 -4
- package/dist/index.js +5 -2
- package/dist/keyfill.d.ts +7 -0
- package/dist/keyfill.js +124 -0
- package/dist/keyrows.d.ts +1 -0
- package/dist/keyrows.js +1 -1
- package/dist/lane.d.ts +32 -2
- package/dist/lane.js +5 -0
- package/dist/lanes.d.ts +32 -8
- package/dist/lanes.js +69 -37
- package/dist/leavings.d.ts +26 -0
- package/dist/leavings.js +70 -0
- package/dist/meet.js +14 -8
- package/dist/mixer.d.ts +39 -7
- package/dist/mixer.js +50 -10
- package/dist/motion.d.ts +2 -0
- package/dist/motion.js +4 -1
- package/dist/motions.d.ts +22 -15
- package/dist/motions.js +40 -34
- package/dist/move.js +23 -16
- package/dist/moved.d.ts +11 -0
- package/dist/moved.js +29 -0
- package/dist/origin.d.ts +19 -0
- package/dist/origin.js +68 -0
- package/dist/owed.d.ts +4 -4
- package/dist/owed.js +8 -8
- package/dist/owner.d.ts +1 -1
- package/dist/owner.js +2 -2
- package/dist/pace.d.ts +13 -5
- package/dist/pace.js +21 -8
- package/dist/pack.d.ts +3 -1
- package/dist/pack.js +15 -24
- package/dist/paging.d.ts +8 -2
- package/dist/paging.js +44 -4
- package/dist/patch.d.ts +14 -9
- package/dist/patch.js +83 -21
- package/dist/place.js +18 -3
- package/dist/project.d.ts +12 -1
- package/dist/project.js +101 -83
- package/dist/pull.d.ts +2 -0
- package/dist/pull.js +8 -0
- package/dist/qualify.js +10 -2
- package/dist/reading.d.ts +5 -0
- package/dist/reading.js +5 -0
- package/dist/record.d.ts +9 -0
- package/dist/record.js +42 -0
- package/dist/relink.d.ts +11 -5
- package/dist/relink.js +7 -5
- package/dist/restored.d.ts +41 -0
- package/dist/restored.js +91 -0
- package/dist/revive.d.ts +10 -3
- package/dist/revive.js +31 -23
- package/dist/roster.d.ts +11 -0
- package/dist/roster.js +46 -0
- package/dist/rotation.d.ts +29 -0
- package/dist/rotation.js +91 -0
- package/dist/rows.d.ts +5 -5
- package/dist/rows.js +5 -5
- package/dist/sample.d.ts +3 -2
- package/dist/sample.js +32 -15
- package/dist/seek.js +97 -114
- package/dist/shared.d.ts +6 -0
- package/dist/shared.js +15 -0
- package/dist/signals.d.ts +24 -3
- package/dist/signals.js +50 -11
- package/dist/spans.js +7 -0
- package/dist/stack.d.ts +11 -0
- package/dist/stack.js +47 -0
- package/dist/standing.d.ts +10 -0
- package/dist/standing.js +79 -0
- package/dist/store.d.ts +3 -3
- package/dist/store.js +3 -3
- package/dist/strays.js +3 -0
- package/dist/tape.d.ts +8 -5
- package/dist/tape.js +21 -13
- package/dist/testing.d.ts +35 -0
- package/dist/testing.js +116 -0
- package/dist/touch.d.ts +6 -0
- package/dist/touch.js +28 -0
- package/dist/transport.d.ts +49 -6
- package/dist/transport.js +89 -19
- package/dist/turns.d.ts +18 -0
- package/dist/turns.js +72 -0
- package/dist/tweened.js +1 -1
- package/dist/types/channel.d.ts +46 -0
- package/dist/types/channel.js +1 -0
- package/dist/types/history.d.ts +139 -0
- package/dist/types/history.js +1 -0
- package/dist/types/mix.d.ts +336 -0
- package/dist/types/mix.js +1 -0
- package/dist/types/patch.d.ts +187 -0
- package/dist/types/patch.js +1 -0
- package/dist/types/place.d.ts +157 -0
- package/dist/types/place.js +1 -0
- package/dist/types/transport.d.ts +71 -0
- package/dist/types/transport.js +1 -0
- package/dist/types/voice.d.ts +323 -0
- package/dist/types/voice.js +1 -0
- package/dist/types.d.ts +7 -1162
- package/dist/unpage.d.ts +2 -2
- package/dist/unpage.js +53 -25
- package/dist/voice.d.ts +90 -22
- package/dist/voice.js +105 -43
- package/dist/wave.d.ts +42 -0
- package/dist/wave.js +62 -0
- package/dist/weigh.js +1 -1
- package/docs/schema.html +42 -36
- package/package.json +8 -3
package/dist/types.d.ts
CHANGED
|
@@ -1,1162 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
/**
|
|
9
|
-
* Names this channel's arithmetic, so a patch written against one channel can be checked against
|
|
10
|
-
* another of the same name. Two channels of one kind must fold identically; the stock ones set it,
|
|
11
|
-
* as `'sum'` or `'vec(3, sum)'`. Absent, a channel matches only itself.
|
|
12
|
-
*/
|
|
13
|
-
kind?: string;
|
|
14
|
-
/**
|
|
15
|
-
* The range a numeric value means anything in, such as 0..1 for an opacity. The mix clamps the
|
|
16
|
-
* folded value to it, axis by axis for an array, so neither stacked voices nor a retarget that
|
|
17
|
-
* carries speed can push it out; overshoot stops flat at the bound.
|
|
18
|
-
*/
|
|
19
|
-
bounds?: readonly [min: number, max: number];
|
|
20
|
-
/** Identity. Absent means the channel has none: it replaces rather than contributes. */
|
|
21
|
-
rest?: V;
|
|
22
|
-
/** Fold two contributions into one. */
|
|
23
|
-
merge(a: V, b: V): V;
|
|
24
|
-
/** Fade toward `rest` by weight 0..1. Required when `rest` is set; absent otherwise. */
|
|
25
|
-
scale?(v: V, w: number): V;
|
|
26
|
-
/** Interpolate, for retargeting, for blending alternatives, and for folding a locus. */
|
|
27
|
-
lerp(a: V, b: V, u: number): V;
|
|
28
|
-
/**
|
|
29
|
-
* Optional: `merge(into, scale(v, w))`, written into `into` and returned, so a channel whose
|
|
30
|
-
* values are objects need not allocate per contribution. The mix only hands it a value it made.
|
|
31
|
-
*/
|
|
32
|
-
fold?(into: V, v: V, w: number): V;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* The channel set for one kind of delta.
|
|
36
|
-
*
|
|
37
|
-
* @category channel
|
|
38
|
-
*/
|
|
39
|
-
export type Kit<O> = {
|
|
40
|
-
readonly [K in keyof O]-?: Channel<NonNullable<O[K]>>;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* A curve on 0..1, as data where it can be: CSS's names, a `cubic-bezier`, or `steps`, which a
|
|
44
|
-
* WAAPI or GPU engine can read. The function form runs on the CPU engine only.
|
|
45
|
-
*
|
|
46
|
-
* @category patch
|
|
47
|
-
*/
|
|
48
|
-
export type Easing = ((u: number) => number) | 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | {
|
|
49
|
-
readonly bezier: readonly [x1: number, y1: number, x2: number, y2: number];
|
|
50
|
-
} | {
|
|
51
|
-
readonly steps: number;
|
|
52
|
-
readonly jump?: 'start' | 'end';
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* One stop of a `keys` patch.
|
|
56
|
-
*
|
|
57
|
-
* @category patch
|
|
58
|
-
*/
|
|
59
|
-
export interface Keyframe<O> {
|
|
60
|
-
/** Phase, 0..1. */
|
|
61
|
-
at: number;
|
|
62
|
-
delta: Partial<O>;
|
|
63
|
-
ease?: Easing;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* What a patch may read and did not compute, for one subject this frame. The mix reuses the object,
|
|
67
|
-
* so it is valid only during the call it is handed to.
|
|
68
|
-
*
|
|
69
|
-
* @category state
|
|
70
|
-
*/
|
|
71
|
-
export interface Setting<S = void, H = unknown> {
|
|
72
|
-
/**
|
|
73
|
-
* The mix clock at this frame: the host's timestamp less any time `rebase` took out, run at the
|
|
74
|
-
* mix's `rate`. Identical for every probe in the frame.
|
|
75
|
-
*/
|
|
76
|
-
timestamp: number;
|
|
77
|
-
/**
|
|
78
|
-
* The gap this subject is catching up by: milliseconds since it last advanced, which is the gap
|
|
79
|
-
* since the previous sync only for a subject sampled every frame. Infinity under reduced motion;
|
|
80
|
-
* no more than `maxDt` where the mix sets one. Inside a `step` under `stepMs`, it is `stepMs`, and
|
|
81
|
-
* `timestamp` is the end of that interval.
|
|
82
|
-
*/
|
|
83
|
-
dt: number;
|
|
84
|
-
/** Milliseconds this voice has been playing, rate applied. */
|
|
85
|
-
elapsed: number;
|
|
86
|
-
/** Which pass this is, 0 first. */
|
|
87
|
-
pass: number;
|
|
88
|
-
/** This voice's weight for this subject this frame, after fades, signals and any locus. */
|
|
89
|
-
weight: number;
|
|
90
|
-
/** This subject's state, when the patch declares one. */
|
|
91
|
-
state: S;
|
|
92
|
-
/** Anything the host adds for its own patches: the mix's `host`, typed as its `H`. */
|
|
93
|
-
host: H;
|
|
94
|
-
/**
|
|
95
|
-
* The state `owner` keeps for this voice and this subject, made by `init` on first ask. The mix
|
|
96
|
-
* holds it, so a read at another time can copy it instead of moving it. A stateful signal keeps
|
|
97
|
-
* its state here and nowhere else. With lanes on, a patch or weight signal that first calls it
|
|
98
|
-
* partway through playing can have that state advanced once for one subject probed the frame
|
|
99
|
-
* before it starts and not on that frame; one that keeps state from its first call, or a patch
|
|
100
|
-
* that declares `state`, never does.
|
|
101
|
-
*/
|
|
102
|
-
keep<K>(owner: object, init: () => K): K;
|
|
103
|
-
/**
|
|
104
|
-
* Reports an event at `timestamp`, for this voice and this subject. The mix queues it until the
|
|
105
|
-
* host drains it, and never calls back. Meant for `step`, where under `stepMs` the timestamp is
|
|
106
|
-
* the interval the event happened in rather than the frame that sampled it. Sent from a stateless
|
|
107
|
-
* patch's `at` while it runs on a lane, it goes out for every subject the lane fills, probed that
|
|
108
|
-
* frame or not: each probed that frame or the last; `at` is not asked for a subject at weight 0,
|
|
109
|
-
* so nothing is sent from it there.
|
|
110
|
-
*/
|
|
111
|
-
send(event: unknown): void;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* One event a patch sent, as `drain` hands it back.
|
|
115
|
-
*
|
|
116
|
-
* @category state
|
|
117
|
-
*/
|
|
118
|
-
export interface Sent<I, E = unknown> {
|
|
119
|
-
/** The mix clock when it was sent. */
|
|
120
|
-
timestamp: number;
|
|
121
|
-
subject: I;
|
|
122
|
-
/** The id of the voice whose patch sent it, as its handle reports. */
|
|
123
|
-
voice: number;
|
|
124
|
-
/** That voice's tags. */
|
|
125
|
-
tags: readonly string[];
|
|
126
|
-
event: E;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* What a `'motion'` patch is made of, as data an engine can read: the kind of motion and its
|
|
130
|
-
* constants. Each subject's start, target and starting velocity stay on the patch, since they may
|
|
131
|
-
* be functions of the subject.
|
|
132
|
-
*
|
|
133
|
-
* @category patch
|
|
134
|
-
*/
|
|
135
|
-
export type MotionSpec = {
|
|
136
|
-
readonly kind: 'spring';
|
|
137
|
-
/** Per second squared. */
|
|
138
|
-
readonly stiffness: number;
|
|
139
|
-
/** Per second. */
|
|
140
|
-
readonly damping: number;
|
|
141
|
-
readonly mass: number;
|
|
142
|
-
readonly settle: number;
|
|
143
|
-
} | {
|
|
144
|
-
readonly kind: 'glide';
|
|
145
|
-
/** The friction's time constant, ms. */
|
|
146
|
-
readonly ms: number;
|
|
147
|
-
readonly settle: number;
|
|
148
|
-
} | {
|
|
149
|
-
readonly kind: 'tween';
|
|
150
|
-
/** How long a stretch takes; undefined where it varies by subject, kept on the patch then. */
|
|
151
|
-
readonly ms: number | undefined;
|
|
152
|
-
readonly ease: Easing;
|
|
153
|
-
};
|
|
154
|
-
/**
|
|
155
|
-
* A pure function of phase and a subject that returns a delta. Optionally stateful.
|
|
156
|
-
*
|
|
157
|
-
* @category patch
|
|
158
|
-
*/
|
|
159
|
-
export interface Patch<I, O, S = void, H = unknown> {
|
|
160
|
-
/**
|
|
161
|
-
* Which authoring form built it: `'fn'` from `patch`, `'keys'` from `keys`, `'motion'` from
|
|
162
|
-
* `spring`, `glide` or `tween`. An engine declares which forms it runs.
|
|
163
|
-
*/
|
|
164
|
-
readonly form: 'fn' | 'keys' | 'motion';
|
|
165
|
-
/** Milliseconds one pass lasts, whether or not the voice loops. 0 has no passes: phase and pass stay 0. */
|
|
166
|
-
readonly duration: number;
|
|
167
|
-
/** @deprecated Use `duration`. A patch that sets only `period` still plays. */
|
|
168
|
-
readonly period?: number;
|
|
169
|
-
/** The channels this patch contributes to. Every key `at` sets, and no others. */
|
|
170
|
-
readonly writes: readonly (keyof O)[];
|
|
171
|
-
/**
|
|
172
|
-
* The channels this patch was written against. `cue` refuses a mix whose channel of the same name
|
|
173
|
-
* is of another kind, so a patch published in one package cannot fold by another's arithmetic.
|
|
174
|
-
*/
|
|
175
|
-
readonly kit?: Partial<Kit<O>>;
|
|
176
|
-
/** The fields of `setting.host` this patch reads. `cue` refuses a mix whose host lacks one. */
|
|
177
|
-
readonly reads?: readonly string[];
|
|
178
|
-
/**
|
|
179
|
-
* `phase` is 0..1 across one pass, wrapping. Not asked for a subject its voice gives no weight, unless the voice is fading to rest;
|
|
180
|
-
* `step` still runs. A `keys` patch's stops are not read there either, unless its voice is in a locus.
|
|
181
|
-
*/
|
|
182
|
-
at(phase: number, subject: I, setting: Setting<S, H>): Partial<O>;
|
|
183
|
-
/** Per-subject state, created on the first frame this patch sees a subject. */
|
|
184
|
-
state?(subject: I): S;
|
|
185
|
-
/**
|
|
186
|
-
* Advances state once per subject per sampled frame, by the whole gap since it last advanced; or,
|
|
187
|
-
* where the mix sets `stepMs`, once per whole interval of that length.
|
|
188
|
-
*/
|
|
189
|
-
step?(state: S, dt: number, subject: I, setting: Setting<S, H>): void;
|
|
190
|
-
/** Present when the patch was authored as keyframes, so an engine that reads data can. */
|
|
191
|
-
readonly keys?: readonly Keyframe<O>[];
|
|
192
|
-
/** Present on a `'motion'` patch: its kind and constants, for an engine that reads data. */
|
|
193
|
-
readonly motion?: MotionSpec;
|
|
194
|
-
/**
|
|
195
|
-
* A copy of `state` that shares nothing with it, for a read at another time. Default
|
|
196
|
-
* `structuredClone`, which is enough for plain data; a state holding a class instance or a
|
|
197
|
-
* function needs its own.
|
|
198
|
-
*/
|
|
199
|
-
clone?(state: S): S;
|
|
200
|
-
/**
|
|
201
|
-
* `state` as data that survives `structuredClone`, for a history `store` to keep; `unpack` makes
|
|
202
|
-
* a state from it again. With a store, a patch with `state` or `step` needs both, or `cue`
|
|
203
|
-
* refuses it.
|
|
204
|
-
*/
|
|
205
|
-
pack?(state: S): unknown;
|
|
206
|
-
unpack?(data: unknown): S;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* A 0..1 scalar resolved per subject per frame from something outside the clock. `input` is set
|
|
210
|
-
* when it reads something the clock does not drive, such as a value the host writes; a signal
|
|
211
|
-
* built on one inherits it.
|
|
212
|
-
*
|
|
213
|
-
* @category signal
|
|
214
|
-
*/
|
|
215
|
-
export type Signal<I, H = unknown> = ((subject: I, setting: Setting<void, H>) => number) & {
|
|
216
|
-
readonly input?: boolean;
|
|
217
|
-
};
|
|
218
|
-
/**
|
|
219
|
-
* A voice's own ramps in and out, in ms, and the curve both take.
|
|
220
|
-
*
|
|
221
|
-
* @category blending
|
|
222
|
-
*/
|
|
223
|
-
export interface FadeSpec {
|
|
224
|
-
in?: number;
|
|
225
|
-
out?: number;
|
|
226
|
-
ease?: Easing;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* The times a voice is known by on the mix clock: when its fade in begins (`start`), when it is
|
|
230
|
-
* fully in (`in`), when its last pass ends (`coast`), when its fade out begins (`out`), and when it
|
|
231
|
-
* is gone (`end`). A voice coasts when `played` resolves true, for its latest-staggered subject: at
|
|
232
|
-
* its `out` where it does not freeze, and where it starts showing its last frame where it does. A
|
|
233
|
-
* voice that loops for good, or fades before its last pass ends, never coasts.
|
|
234
|
-
*
|
|
235
|
-
* @category score
|
|
236
|
-
*/
|
|
237
|
-
export type Mark = 'start' | 'in' | 'coast' | 'out' | 'end';
|
|
238
|
-
/**
|
|
239
|
-
* Selects voices by what the plan knows of them, never by a channel's value, within the asking
|
|
240
|
-
* voice's own score unless it names another. Where several match,
|
|
241
|
-
* the resolver picks one: `last` cued (the default), `first` cued, `next` (the earliest whose mark
|
|
242
|
-
* is still to come), `earliest` or `latest` by the mark's time.
|
|
243
|
-
*
|
|
244
|
-
* @category score
|
|
245
|
-
*/
|
|
246
|
-
export interface Query {
|
|
247
|
-
/** The score to look in. Default: the asking voice's own. */
|
|
248
|
-
score?: string;
|
|
249
|
-
name?: string;
|
|
250
|
-
tag?: string;
|
|
251
|
-
/** A channel the voice's patch writes. */
|
|
252
|
-
writes?: string;
|
|
253
|
-
resolver?: 'last' | 'first' | 'next' | 'earliest' | 'latest';
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* A time given by another voice: `mark` of the voice `of` selects, moved by `by` ms. `after` is
|
|
257
|
-
* sugar for that voice's `end`, `with` for its `start`, and `before` for its start less `by`. A
|
|
258
|
-
* string selects by name. `all` is the latest of its anchors, known once every one is; `any` the
|
|
259
|
-
* earliest, known once one has passed or every one is known.
|
|
260
|
-
*
|
|
261
|
-
* @category score
|
|
262
|
-
*/
|
|
263
|
-
export type Anchor = {
|
|
264
|
-
of: string | Query;
|
|
265
|
-
mark: Mark;
|
|
266
|
-
by?: number;
|
|
267
|
-
} | {
|
|
268
|
-
after: string | Query;
|
|
269
|
-
by?: number;
|
|
270
|
-
} | {
|
|
271
|
-
with: string | Query;
|
|
272
|
-
by?: number;
|
|
273
|
-
} | {
|
|
274
|
-
before: string | Query;
|
|
275
|
-
by?: number;
|
|
276
|
-
} | {
|
|
277
|
-
all: readonly Anchor[];
|
|
278
|
-
} | {
|
|
279
|
-
any: readonly Anchor[];
|
|
280
|
-
};
|
|
281
|
-
/**
|
|
282
|
-
* Where a voice sits on the mix clock: at most one of `start` and `in`, and at most one of `out`
|
|
283
|
-
* and `end`, each a timestamp on the host's clock or an anchor to another voice. A voice whose
|
|
284
|
-
* anchor has no answer yet waits pending; one whose anchored mark is already past starts partway
|
|
285
|
-
* through, as playback does from the middle of a region.
|
|
286
|
-
*
|
|
287
|
-
* @category score
|
|
288
|
-
*/
|
|
289
|
-
export interface Placement {
|
|
290
|
-
start?: number | Anchor;
|
|
291
|
-
in?: number | Anchor;
|
|
292
|
-
out?: number | Anchor;
|
|
293
|
-
end?: number | Anchor;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* One mark as `marks` lists it: one of a voice's, or one the host announced on a score, which has a
|
|
297
|
-
* name and no voice.
|
|
298
|
-
*
|
|
299
|
-
* @category score
|
|
300
|
-
*/
|
|
301
|
-
export interface Marked {
|
|
302
|
-
/** On the host's clock. */
|
|
303
|
-
timestamp: number;
|
|
304
|
-
/** Which of a voice's this is; undefined for an announced mark. */
|
|
305
|
-
mark: Mark | undefined;
|
|
306
|
-
/** The voice it belongs to; undefined for an announced mark. */
|
|
307
|
-
voice: number | undefined;
|
|
308
|
-
score: string | undefined;
|
|
309
|
-
name: string | undefined;
|
|
310
|
-
tags: readonly string[];
|
|
311
|
-
/** The `name` of the mix the voice is in, or that announced the mark; undefined for none. */
|
|
312
|
-
mix: string | undefined;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* An event at a time on a voice's own clock, which `book` hands a host ahead of time. It plays once
|
|
316
|
-
* per pass, for the voice and not per subject, so `stagger` does not spread it.
|
|
317
|
-
*
|
|
318
|
-
* @category score
|
|
319
|
-
*/
|
|
320
|
-
export interface Hit<E = unknown> {
|
|
321
|
-
/** Voice ms into each pass: 0 up to the patch's `duration`, or any time at all for a patch with none. */
|
|
322
|
-
at: number;
|
|
323
|
-
event: E;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* One pass of one hit, as `book` takes it.
|
|
327
|
-
*
|
|
328
|
-
* @category score
|
|
329
|
-
*/
|
|
330
|
-
export interface BookedHit<E = unknown> {
|
|
331
|
-
/** On the host's clock. */
|
|
332
|
-
timestamp: number;
|
|
333
|
-
voice: number;
|
|
334
|
-
/** Which of the voice's `hits`, by index. */
|
|
335
|
-
hit: number;
|
|
336
|
-
/** Which pass, 0 first. */
|
|
337
|
-
pass: number;
|
|
338
|
-
event: E;
|
|
339
|
-
score: string | undefined;
|
|
340
|
-
name: string | undefined;
|
|
341
|
-
tags: readonly string[];
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* What `book` takes: an outside clock, how far ahead to book on it, and what to do with each item.
|
|
345
|
-
*
|
|
346
|
-
* @category score
|
|
347
|
-
*/
|
|
348
|
-
export interface BookOptions<E = unknown> {
|
|
349
|
-
/**
|
|
350
|
-
* The outside clock, in ms: `audio.currentTime * 1000`, `performance.now()`, or whatever the host
|
|
351
|
-
* schedules against. Read once a sync. The mix maps its host time onto it by an offset that folds
|
|
352
|
-
* in 5% of each frame's difference, and starts over from the clock's own reading on a jump past
|
|
353
|
-
* 50 ms, such as a suspended context or a hidden tab.
|
|
354
|
-
*/
|
|
355
|
-
clock: () => number;
|
|
356
|
-
/** How far ahead to book, host ms. It has to cover the longest gap between two syncs. */
|
|
357
|
-
ahead: number;
|
|
358
|
-
/** How far past an item first seen late may be and still be taken, host ms. */
|
|
359
|
-
late: number;
|
|
360
|
-
/**
|
|
361
|
-
* Called once per item: a mark as `marks` lists it, or a hit. `when` is on the outside clock;
|
|
362
|
-
* `lateBy` is how many host ms past the item was when first seen, 0 for one booked ahead, which
|
|
363
|
-
* is then taken at the clock's now. Return a `stop` to hear about a booking whose time moved by
|
|
364
|
-
* more than 1 ms or that went away (a seek, a rate or ramp on the voice or the mix, a fade, a
|
|
365
|
-
* `rebase`, an anchor's target moving, the voice leaving); the item is then booked again, at its
|
|
366
|
-
* new time, at the same sync.
|
|
367
|
-
*/
|
|
368
|
-
take(item: Marked | BookedHit<E>, when: number, lateBy: number): {
|
|
369
|
-
stop(): void;
|
|
370
|
-
} | undefined;
|
|
371
|
-
/** Book only the voices, and announced marks, carrying this tag. */
|
|
372
|
-
tag?: string;
|
|
373
|
-
/** Book only this score's voices and marks. */
|
|
374
|
-
score?: string;
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* A running booker, returned by `book`.
|
|
378
|
-
*
|
|
379
|
-
* @category score
|
|
380
|
-
*/
|
|
381
|
-
export interface Booker {
|
|
382
|
-
/** Stops every booking still ahead, and books nothing more. */
|
|
383
|
-
stop(): void;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* What `cue` takes: a patch, and the clock, weight and reach it plays with.
|
|
387
|
-
*
|
|
388
|
-
* @category voice
|
|
389
|
-
*/
|
|
390
|
-
/**
|
|
391
|
-
* How a voice or owner held by a span may give way so the span keeps its budget, which the span's
|
|
392
|
-
* fit reads. Anything it does not allow, it will not do. Read only under a span.
|
|
393
|
-
*
|
|
394
|
-
* @category score
|
|
395
|
-
*/
|
|
396
|
-
export interface SpanHints {
|
|
397
|
-
/** How many times faster than its own rate it may play. Default 1: no faster. */
|
|
398
|
-
faster?: number;
|
|
399
|
-
/** How many times slower than its own rate it may play. Default 1: no slower. */
|
|
400
|
-
slower?: number;
|
|
401
|
-
/** Whether it may start before the one before it ends, where the span's order would not. */
|
|
402
|
-
overlap?: boolean;
|
|
403
|
-
/** Whether it may jump to its end instead of playing. A span held by a span is never skipped. */
|
|
404
|
-
ballast?: boolean;
|
|
405
|
-
/** How hard its own length holds against the span's budget. Default `weak`. */
|
|
406
|
-
priority?: Strength;
|
|
407
|
-
}
|
|
408
|
-
export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
|
|
409
|
-
patch: Patch<I, O, unknown, H>;
|
|
410
|
-
/**
|
|
411
|
-
* What `history.revive` rebuilds this spec from, so a history `store` can page the voice out once
|
|
412
|
-
* it has left. A voice cued without it stays in memory for as long as history reaches it.
|
|
413
|
-
*/
|
|
414
|
-
as?: Described;
|
|
415
|
-
/**
|
|
416
|
-
* Which subjects this voice reaches. Default: all of them. The predicate is fixed at `cue`; it
|
|
417
|
-
* runs per subject the first time the mix sees that subject, and the answer is kept. Every
|
|
418
|
-
* voice's predicate meets every subject, so voices that each reach a known few cost the square
|
|
419
|
-
* of their number in time; name those with `subjects` instead. A no is kept as a bit by the
|
|
420
|
-
* number lanes give the subject, but with `lanes: false` as a map entry per voice per subject
|
|
421
|
-
* asked (about 37 MB for 1,000 such voices over 1,000 subjects).
|
|
422
|
-
*/
|
|
423
|
-
target?: (subject: I) => boolean;
|
|
424
|
-
/**
|
|
425
|
-
* The subjects this voice reaches, fixed at `cue` and matched by identity; a probe of any other
|
|
426
|
-
* never asks this voice. Takes the place of `target`, and a cue giving both is refused: a
|
|
427
|
-
* predicate over a fixed list is that list filtered, which the host can do before cueing.
|
|
428
|
-
*/
|
|
429
|
-
subjects?: readonly I[];
|
|
430
|
-
/**
|
|
431
|
-
* When the voice starts, in ms on the host's clock, the one it passes `sync`: a rAF timestamp and
|
|
432
|
-
* `performance.now()` share an origin, `Date.now()` does not. Default: the next sync.
|
|
433
|
-
*/
|
|
434
|
-
start?: number;
|
|
435
|
-
/** Playback rate. 1 is real time; 0 freezes. */
|
|
436
|
-
rate?: number;
|
|
437
|
-
/**
|
|
438
|
-
* true loops for good, false plays one pass, n plays n passes. A finite loop leaves when its
|
|
439
|
-
* passes are done for the latest-staggered subject it has seen — over `fade.out` where one is
|
|
440
|
-
* set, at once where none is — unless it freezes after.
|
|
441
|
-
*/
|
|
442
|
-
loop?: boolean | number;
|
|
443
|
-
/**
|
|
444
|
-
* Per-subject delay in voice ms, klieg's stagger grammar reduced to the one thing the mix needs.
|
|
445
|
-
* Like `target`, it runs once per subject on first sight, and the answer is kept.
|
|
446
|
-
*/
|
|
447
|
-
stagger?: (subject: I) => number;
|
|
448
|
-
/**
|
|
449
|
-
* Show a subject the first frame before it starts — while the voice is pending and while the
|
|
450
|
-
* subject waits out its `stagger` — the last frame of the last pass after a finite loop plays
|
|
451
|
-
* out, or both. A frozen subject's clock stands still: `at` is asked for the edge frame and `step`
|
|
452
|
-
* does not run, past one last step to the end of the last pass. `fade.in` counts from the first
|
|
453
|
-
* frame the voice shows. A voice freezing after stays, `frozen`, until `fade()` or an anchored
|
|
454
|
-
* `out` takes it out, so every one cued must be faded or it stays in the mix for good. Does
|
|
455
|
-
* nothing to a motion patch, which keeps its target already. Default: neither.
|
|
456
|
-
*/
|
|
457
|
-
freeze?: 'before' | 'after' | 'both';
|
|
458
|
-
/** @deprecated Use `freeze`. A voice that sets only `hold` still freezes; `freeze` wins over it. */
|
|
459
|
-
hold?: 'before' | 'after' | 'both';
|
|
460
|
-
/** Steady weight, or a signal read per subject per frame. Default 1. */
|
|
461
|
-
weight?: number | Signal<I, H>;
|
|
462
|
-
/** Ramp in and out, ms. Out applies on `fade()` and when a finite loop ends. */
|
|
463
|
-
fade?: FadeSpec;
|
|
464
|
-
/** Voices sharing a locus are alternatives: the mix folds them through each channel's `lerp`. */
|
|
465
|
-
locus?: string;
|
|
466
|
-
/** A `keys` voice whose first stop reads wherever this subject is now. */
|
|
467
|
-
from?: 'current';
|
|
468
|
-
/** Words a source attaches to this voice, so its events and its handle can be taken as a set. */
|
|
469
|
-
tags?: readonly string[];
|
|
470
|
-
/** What other voices call this one by. A label blits never reads. */
|
|
471
|
-
name?: string;
|
|
472
|
-
/**
|
|
473
|
-
* The plan this voice belongs to. Each source keeps its own, so two sources can use one name
|
|
474
|
-
* without meeting: a bare name in an anchor means a voice in the same score, and a query names
|
|
475
|
-
* `score` to reach into another. Default: the mix's one unnamed score.
|
|
476
|
-
*/
|
|
477
|
-
score?: string;
|
|
478
|
-
/** Where it sits relative to the clock or to other voices, in place of `start`. */
|
|
479
|
-
anchor?: Placement;
|
|
480
|
-
/**
|
|
481
|
-
* Events at times on this voice's clock, which `book` hands a host ahead of time. Patch-sent
|
|
482
|
-
* events are not known ahead, so they stay drain-only; these are the plan.
|
|
483
|
-
*/
|
|
484
|
-
hits?: readonly Hit[];
|
|
485
|
-
/**
|
|
486
|
-
* The owner this voice plays under, a handle `owns` returned. Its `start` and `anchor` are then on
|
|
487
|
-
* the owner's clock, in ms from when the owner starts, and default to where that clock is now; a
|
|
488
|
-
* bare name in an anchor means a sibling, another voice the owner holds. Its clock runs on the
|
|
489
|
-
* owner's, so the owner's rate, ramp and seeks move it, and its weight is multiplied by the
|
|
490
|
-
* owner's weight and fade. Without a `freeze` of its own it takes the owner's.
|
|
491
|
-
*/
|
|
492
|
-
owner?: Handle<I>;
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* What `owns` takes: an owner has no patch, and plays only through the voices it holds.
|
|
496
|
-
*
|
|
497
|
-
* @category voice
|
|
498
|
-
*/
|
|
499
|
-
export interface OwnerSpec<I, H = unknown> extends SpanHints {
|
|
500
|
-
/**
|
|
501
|
-
* When the owner starts, on its own owner's clock: the host's for an owner on the mix, as a
|
|
502
|
-
* voice's `start` is. Default: now.
|
|
503
|
-
*/
|
|
504
|
-
start?: number;
|
|
505
|
-
/** Its clock's rate, multiplied into every child's own. Default 1. */
|
|
506
|
-
rate?: number;
|
|
507
|
-
/**
|
|
508
|
-
* Multiplied into every child's weight per subject, as the child's own fade is, before the child's
|
|
509
|
-
* locus folds it: a number, or a signal read per subject per frame. Default 1.
|
|
510
|
-
*/
|
|
511
|
-
weight?: number | Signal<I, H>;
|
|
512
|
-
/** One ramp in and out over every child, multiplied into their weights as `weight` is. */
|
|
513
|
-
fade?: FadeSpec;
|
|
514
|
-
/** The freeze every child without one of its own takes. */
|
|
515
|
-
freeze?: 'before' | 'after' | 'both';
|
|
516
|
-
/** @deprecated Use `freeze`. An owner that sets only `hold` still freezes; `freeze` wins over it. */
|
|
517
|
-
hold?: 'before' | 'after' | 'both';
|
|
518
|
-
/** Words a source attaches to it, as a voice's. */
|
|
519
|
-
tags?: readonly string[];
|
|
520
|
-
/** What other voices call it by, among its siblings. */
|
|
521
|
-
name?: string;
|
|
522
|
-
/** The plan it belongs to, as a voice's. */
|
|
523
|
-
score?: string;
|
|
524
|
-
/** Where it sits relative to its own owner's clock or to other voices, in place of `start`. */
|
|
525
|
-
anchor?: Placement;
|
|
526
|
-
/** The owner it plays under, so owners nest. */
|
|
527
|
-
owner?: Handle<I>;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* What `span` takes: an owner with a budget, which lays out the voices it holds in an order and
|
|
531
|
-
* fits them into the budget.
|
|
532
|
-
*
|
|
533
|
-
* @category score
|
|
534
|
-
*/
|
|
535
|
-
export interface SpanSpec<I, H = unknown> extends OwnerSpec<I, H> {
|
|
536
|
-
/** Its budget, ms on its own clock. Default: none, so its children only keep their order. */
|
|
537
|
-
duration?: number;
|
|
538
|
-
/** How hard the budget holds against its children's own lengths. Default `strong`. */
|
|
539
|
-
priority?: Strength;
|
|
540
|
-
/** How its children are laid out, in the order they were cued. Default `queue`. */
|
|
541
|
-
order?: Order;
|
|
542
|
-
/** How far through the one before a child starts under `stagger`, 0..1. Default 0.5. */
|
|
543
|
-
share?: number;
|
|
544
|
-
/**
|
|
545
|
-
* How the children are fitted once they are retimed toward the budget, faster or slower as
|
|
546
|
-
* their hints allow. Default `pipe(condense(), shed())`.
|
|
547
|
-
*/
|
|
548
|
-
fit?: Fit;
|
|
549
|
-
/**
|
|
550
|
-
* What happens where the fit leaves them too long for a span at least `strong`: `instant` jumps
|
|
551
|
-
* every child weaker than the span to its end at once, and `overrun` lets them run long.
|
|
552
|
-
* Default `instant`.
|
|
553
|
-
*/
|
|
554
|
-
spill?: 'instant' | 'overrun';
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* How a span's last fit came out.
|
|
558
|
-
*
|
|
559
|
-
* @category score
|
|
560
|
-
*/
|
|
561
|
-
export interface FitResult {
|
|
562
|
-
/** Its budget, ms on its own clock; Infinity for none. */
|
|
563
|
-
budget: number;
|
|
564
|
-
/** Where its children end, ms on its own clock from its start. */
|
|
565
|
-
length: number;
|
|
566
|
-
/** How far `length` runs past the budget, 0 where it does not. */
|
|
567
|
-
over: number;
|
|
568
|
-
/** How many children it jumps to their end. */
|
|
569
|
-
skipped: number;
|
|
570
|
-
/** Whether the fit failed and `spill` decided. */
|
|
571
|
-
fell: boolean;
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* A span's handle: an owner's, and how its children were last fitted.
|
|
575
|
-
*
|
|
576
|
-
* @category score
|
|
577
|
-
*/
|
|
578
|
-
export interface SpanHandle<I = unknown> extends Handle<I> {
|
|
579
|
-
readonly result: FitResult;
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* How a voice leaves when it is faded: the whole voice, or one subject.
|
|
583
|
-
*
|
|
584
|
-
* @category blending
|
|
585
|
-
*/
|
|
586
|
-
export type FadeOptions<I = unknown> = {
|
|
587
|
-
/** The ramp, ms. Defaults to the voice's own `fade.out`. */
|
|
588
|
-
over?: number;
|
|
589
|
-
/**
|
|
590
|
-
* When the fade begins. A mix time: ahead, the voice plays untouched until then and begins
|
|
591
|
-
* its fade exactly there, its `out` mark fixed from now, and `rise` before then takes it
|
|
592
|
-
* back with nothing changed; at or behind now, the fade began then and is partway. `'rest'`:
|
|
593
|
-
* leave per subject at the first frame that subject's contribution is at rest. Default now.
|
|
594
|
-
*/
|
|
595
|
-
at?: number | 'rest';
|
|
596
|
-
/** Ms after which the voice leaves whether or not it rested. */
|
|
597
|
-
deadline?: number;
|
|
598
|
-
subject?: never;
|
|
599
|
-
} | {
|
|
600
|
-
/**
|
|
601
|
-
* The one subject to fade out of this voice, which plays on for the rest. Once the ramp ends
|
|
602
|
-
* the voice forgets the subject and reaches it no more, until a motion patch's `to` brings it
|
|
603
|
-
* back, met afresh: `from`, `target` and `stagger` asked again.
|
|
604
|
-
*/
|
|
605
|
-
subject: I;
|
|
606
|
-
/** The ramp, ms. Defaults to the voice's own `fade.out`; 0 takes the subject out at once. */
|
|
607
|
-
over?: number;
|
|
608
|
-
};
|
|
609
|
-
/**
|
|
610
|
-
* The live controls on one voice, returned by `cue`.
|
|
611
|
-
*
|
|
612
|
-
* @category voice
|
|
613
|
-
*/
|
|
614
|
-
export interface Handle<I = unknown> {
|
|
615
|
-
readonly id: number;
|
|
616
|
-
/** `frozen`: a voice freezing after has played every pass and shows its last frame until faded. */
|
|
617
|
-
readonly state: 'pending' | 'live' | 'frozen' | 'fading' | 'done';
|
|
618
|
-
/** The handle of the owner this voice plays under; undefined for one on the mix clock. */
|
|
619
|
-
readonly owner: Handle<I> | undefined;
|
|
620
|
-
/** Live. Writes land on the next sync. */
|
|
621
|
-
weight: number;
|
|
622
|
-
/** Playback rate now. Setting it changes speed at once; `ramp` eases into a new one. */
|
|
623
|
-
rate: number;
|
|
624
|
-
/**
|
|
625
|
-
* Moves the rate to `rate` linearly over `over` mix ms, so a pause or a slow-motion eases in
|
|
626
|
-
* rather than snapping. The voice clock integrates the ramp, so its position stays continuous and
|
|
627
|
-
* its speed does too. A later `rate` write or `ramp` replaces it; `seek` keeps it.
|
|
628
|
-
*/
|
|
629
|
-
ramp(rate: number, over: number): void;
|
|
630
|
-
/**
|
|
631
|
-
* Moves this voice's clock, forward or back. Phase is computed from the reading rather than
|
|
632
|
-
* accumulated into, so state is left where it is and never run forward to meet the new position.
|
|
633
|
-
*/
|
|
634
|
-
seek(elapsed: number): void;
|
|
635
|
-
fade(opts?: FadeOptions<I>): void;
|
|
636
|
-
/**
|
|
637
|
-
* Turns a fade out around: the voice climbs back from where its fade had got to, up the same
|
|
638
|
-
* curve, over `over` ms for the whole curve (default its `fade.in`, else its `fade.out`), and
|
|
639
|
-
* plays on as if never faded. A fade waiting for rest is taken back at once; a voice not fading
|
|
640
|
-
* is left as it is. A voice whose own end began the fade starts it again at its next frame.
|
|
641
|
-
*/
|
|
642
|
-
rise(opts?: {
|
|
643
|
-
over?: number;
|
|
644
|
-
}): void;
|
|
645
|
-
/**
|
|
646
|
-
* The weight this voice gave `subject` the last frame that subject was probed: after its fades
|
|
647
|
-
* and its weight signal, before a locus folds it with its alternatives. 0 for a subject it does
|
|
648
|
-
* not reach, has not started on and does not freeze before, has left at rest, or has never been
|
|
649
|
-
* probed for; 0 once done.
|
|
650
|
-
* Costs nothing until it is asked.
|
|
651
|
-
*/
|
|
652
|
-
weightOf(subject: I): number;
|
|
653
|
-
/** Resolves when the voice has been removed from the mix, however that happened. */
|
|
654
|
-
readonly done: Promise<void>;
|
|
655
|
-
/**
|
|
656
|
-
* Resolves true when a finite loop's last pass ends, for the latest-staggered subject it has
|
|
657
|
-
* seen, and false if the voice leaves before that. Never rejects.
|
|
658
|
-
*/
|
|
659
|
-
readonly played: Promise<boolean>;
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* How a mix is built: its engine, reduced motion, the host, and its limits.
|
|
663
|
-
*
|
|
664
|
-
* @category mix
|
|
665
|
-
*/
|
|
666
|
-
export interface MixOptions<H = unknown> {
|
|
667
|
-
engine?: Engine;
|
|
668
|
-
/** Reduced motion: fades and warm-ups snap, `dt` reads Infinity. */
|
|
669
|
-
reduce?: boolean | (() => boolean);
|
|
670
|
-
/** Merged into every `setting.host`. Its type is the mix's `H`, which every patch and signal it cues reads. */
|
|
671
|
-
host?: H;
|
|
672
|
-
/**
|
|
673
|
-
* The band a rest-less channel's contribution switches on and off across. It has to clear the frame
|
|
674
|
-
* noise in a real signal; these are placeholders until the klieg port measures one.
|
|
675
|
-
*/
|
|
676
|
-
band?: {
|
|
677
|
-
on: number;
|
|
678
|
-
off: number;
|
|
679
|
-
};
|
|
680
|
-
/**
|
|
681
|
-
* The most `dt` a `step` or signal is handed, however long the gap. Off by default, since a
|
|
682
|
-
* patch with a closed form wants the whole gap; an integrator wants this set.
|
|
683
|
-
*/
|
|
684
|
-
maxDt?: number;
|
|
685
|
-
/**
|
|
686
|
-
* Run every `step` at this fixed interval, ms, instead of once by the frame's gap, so stateful
|
|
687
|
-
* patches play the same at any frame rate. Intervals count from when a subject's delay ran out,
|
|
688
|
-
* the remainder carrying to the next sample; `maxDt` then caps how many one sample may run.
|
|
689
|
-
* Signals and `at` still see the frame. Off by default.
|
|
690
|
-
*/
|
|
691
|
-
stepMs?: number;
|
|
692
|
-
/**
|
|
693
|
-
* How far back `project` may read, in ms of mix time, and how often a stateful voice's state is
|
|
694
|
-
* kept per subject on the way, `every` ms (default 200). Within it the mix remembers what it cued,
|
|
695
|
-
* every change a handle made and when, the voices that have left, and those copies of state, so a
|
|
696
|
-
* read back restores the nearest copy and steps forward from it. Off by default, and a mix without
|
|
697
|
-
* it keeps nothing. With `inputs`, it also keeps what each input signal on a voice's weight read
|
|
698
|
-
* per subject, and the host fields patches `reads`, each time they changed, so a read back over a
|
|
699
|
-
* `level` or a pointer is known rather than held. With `tape`, the mix also records every call
|
|
700
|
-
* the host makes on it, its handles and its motion patches, so `seek` can move it and play those
|
|
701
|
-
* calls again.
|
|
702
|
-
*/
|
|
703
|
-
history?: HistoryOptions;
|
|
704
|
-
/**
|
|
705
|
-
* A subject's key, for a history `store`: unique among this mix's subjects for the session. A
|
|
706
|
-
* string or number subject is its own key; with a store, an object subject needs this.
|
|
707
|
-
*/
|
|
708
|
-
keyOf?(subject: never): string | number;
|
|
709
|
-
/**
|
|
710
|
-
* Whether a channel may run as a lane: computed for every subject at once in flat arrays, when
|
|
711
|
-
* every voice writing it can run that way. On by default; the pose is the same either way, so
|
|
712
|
-
* turning it off is for ruling a lane out, or for comparing against. Two things differ: a
|
|
713
|
-
* stateless patch's `setting.send` from `at` sends for every subject a lane fills, those probed
|
|
714
|
-
* this frame or the last, and a patch that first calls `setting.keep` partway through playing can
|
|
715
|
-
* advance that state once more for one subject probed the frame before (see `Setting.keep`).
|
|
716
|
-
*/
|
|
717
|
-
lanes?: boolean;
|
|
718
|
-
/**
|
|
719
|
-
* The transport this mix plays on, shared with other mixes, so they keep one clock and a query
|
|
720
|
-
* naming a score looks in all of them. The transport's `sync`, `rebase`, `rate`, `ramp` and
|
|
721
|
-
* `seek` move it, and the mix's own throw. Its history is the transport's, so the mix takes no
|
|
722
|
-
* `history` of its own.
|
|
723
|
-
*/
|
|
724
|
-
transport?: Transport;
|
|
725
|
-
/** What `Marked.mix` and errors call this mix. */
|
|
726
|
-
name?: string;
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* What a mix or transport remembers, for `seek` and `project` to read back: see
|
|
730
|
-
* `MixOptions.history`.
|
|
731
|
-
*
|
|
732
|
-
* @category mix
|
|
733
|
-
*/
|
|
734
|
-
export interface HistoryOptions {
|
|
735
|
-
/** How much stays in memory, ms of mix time. With a `store`, the rest is paged out, not dropped. */
|
|
736
|
-
ms: number;
|
|
737
|
-
every?: number;
|
|
738
|
-
inputs?: boolean;
|
|
739
|
-
tape?: TapeMaker;
|
|
740
|
-
/**
|
|
741
|
-
* Where history older than `ms` goes instead of being dropped. A `seek` or `project` reaching
|
|
742
|
-
* past memory needs `prepare` first, or throws `HistoryMiss`. With a store, blits never prunes
|
|
743
|
-
* the tape: the host bounds it.
|
|
744
|
-
*/
|
|
745
|
-
store?: HistoryStore;
|
|
746
|
-
/** Rebuilds a cued voice's spec from the descriptor it was cued with, so the voice can be paged out. */
|
|
747
|
-
revive?(d: Described): VoiceSpec<any, any>;
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* A voice as plain data: `kind` names what built it, and `data` survives `structuredClone`.
|
|
751
|
-
*
|
|
752
|
-
* @category mix
|
|
753
|
-
*/
|
|
754
|
-
export interface Described {
|
|
755
|
-
kind: string;
|
|
756
|
-
data: unknown;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* Where a history `store` keeps what memory let go of. blits decides what is kept and when it is
|
|
760
|
-
* read back; the store decides where it lives.
|
|
761
|
-
*
|
|
762
|
-
* @category mix
|
|
763
|
-
*/
|
|
764
|
-
export interface HistoryStore {
|
|
765
|
-
/** Records leaving memory. One brought back by a seek may be paged again: keep one per key and `at`. */
|
|
766
|
-
page(out: readonly Paged[]): void;
|
|
767
|
-
/**
|
|
768
|
-
* What a restore to mix time `t` needs, for every mix: from each stream, per voice and subject,
|
|
769
|
-
* the latest record at or before `t` and every record after it. Returning everything is fine.
|
|
770
|
-
*/
|
|
771
|
-
load(t: number): Promise<readonly Paged[]>;
|
|
772
|
-
/** A seek went back to `t`: every record after it is from a future the tape makes again. Forget them. */
|
|
773
|
-
cut(t: number): void;
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* What a history record holds: a voice's `controls`, a stateful record's `snap`, an `input`
|
|
777
|
-
* signal's reading, a subject's record when it `left` a voice, a motion subject's `released` run
|
|
778
|
-
* or older `stretch`, the `host` fields patches read, or a whole `voice` that has left.
|
|
779
|
-
*
|
|
780
|
-
* @category mix
|
|
781
|
-
*/
|
|
782
|
-
export type PagedStream = 'voice' | 'snap' | 'input' | 'left' | 'released' | 'stretch' | 'host' | 'controls';
|
|
783
|
-
/**
|
|
784
|
-
* One history record leaving memory, as plain data.
|
|
785
|
-
*
|
|
786
|
-
* @category mix
|
|
787
|
-
*/
|
|
788
|
-
export interface Paged {
|
|
789
|
-
/** The mix's `name`; '' for a mix made alone without one. */
|
|
790
|
-
mix: string;
|
|
791
|
-
stream: PagedStream;
|
|
792
|
-
/** The voice's id, for every stream but `host`. */
|
|
793
|
-
voice?: number;
|
|
794
|
-
/** The subject's key, for a record of one subject. */
|
|
795
|
-
subject?: string | number;
|
|
796
|
-
/** Mix time. */
|
|
797
|
-
at: number;
|
|
798
|
-
data: unknown;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* How a transport is made: what history it keeps for every mix on it.
|
|
802
|
-
*
|
|
803
|
-
* @category mix
|
|
804
|
-
*/
|
|
805
|
-
export interface TransportOptions {
|
|
806
|
-
history?: MixOptions['history'];
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Every mix on a transport read at another mix time, with nothing live moved: `of` gives one mix's
|
|
810
|
-
* reading. Valid until the transport is next synced or a mix on it cued.
|
|
811
|
-
*
|
|
812
|
-
* @category mix
|
|
813
|
-
*/
|
|
814
|
-
export interface TransportProjection {
|
|
815
|
-
readonly timestamp: number;
|
|
816
|
-
of<I, O, H>(mix: Mix<I, O, H>): Projection<I, O>;
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* One clock several mixes play on, each over its own kit: one sync, one rate, one seek and one
|
|
820
|
-
* tape for all of them, and a score that spans them, so an anchor in one mix waits on a voice in
|
|
821
|
-
* another by naming the score they share. A query naming no score stays in its own mix.
|
|
822
|
-
*
|
|
823
|
-
* @category mix
|
|
824
|
-
*/
|
|
825
|
-
export interface Transport {
|
|
826
|
-
/** The host reports the clock once a frame, after the frame's cues, as `Mix.sync` does. */
|
|
827
|
-
sync(timestamp: number): void;
|
|
828
|
-
/** As `Mix.rebase`, for every mix on it. */
|
|
829
|
-
rebase(): void;
|
|
830
|
-
/** As `Mix.rate`, multiplied into every voice of every mix on it. */
|
|
831
|
-
rate: number;
|
|
832
|
-
ramp(rate: number, over: number): void;
|
|
833
|
-
/**
|
|
834
|
-
* As `Mix.seek`, for every mix on it at once: back, each mix restores itself; forward, the one
|
|
835
|
-
* tape plays every mix's calls again in the order they were made, so an anchor across mixes
|
|
836
|
-
* answers as it did. A mix dropped after the moment sought is back on the transport.
|
|
837
|
-
*/
|
|
838
|
-
seek(time: number): void;
|
|
839
|
-
/**
|
|
840
|
-
* Loads from the history `store` what `seek(time)` and `project(time)` will need, where that
|
|
841
|
-
* reaches past memory. Without a store, or within memory, it loads nothing.
|
|
842
|
-
*/
|
|
843
|
-
prepare(time: number): Promise<void>;
|
|
844
|
-
readonly now: number;
|
|
845
|
-
readonly tape: Tape | undefined;
|
|
846
|
-
/** Puts a named mark on a score every mix on it sees. Throws without a `score`. */
|
|
847
|
-
announce(name: string, opts: {
|
|
848
|
-
at?: number;
|
|
849
|
-
score: string;
|
|
850
|
-
tags?: readonly string[];
|
|
851
|
-
}): void;
|
|
852
|
-
/** Every mark of every mix on it, and every mark announced on it, earliest first. */
|
|
853
|
-
marks(from: number, to: number): Marked[];
|
|
854
|
-
/** Every mix on it read at mix time `time`, together, so anchors across them answer. */
|
|
855
|
-
project(time: number): TransportProjection;
|
|
856
|
-
/** Any mix on it live. */
|
|
857
|
-
readonly live: boolean;
|
|
858
|
-
/** Every mix on it inert. */
|
|
859
|
-
readonly inert: boolean;
|
|
860
|
-
/** Calls `fn` when any mix on it needs frames again after a sync, once until the next sync. */
|
|
861
|
-
onWake(fn: () => void): () => void;
|
|
862
|
-
/**
|
|
863
|
-
* Takes a mix off: it is no longer synced and takes no more calls. With history, a seek back
|
|
864
|
-
* before the drop puts it back as it was then; without, it is let go.
|
|
865
|
-
*/
|
|
866
|
-
drop<I, O, H>(mix: Mix<I, O, H>): void;
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* One host call a mix recorded on its tape: `apply` makes it again, and `invert` does nothing,
|
|
870
|
-
* since a mix goes back by restoring what it kept rather than by undoing calls.
|
|
871
|
-
*
|
|
872
|
-
* @category mix
|
|
873
|
-
*/
|
|
874
|
-
export interface TapeOp {
|
|
875
|
-
apply(adapter: unknown): void;
|
|
876
|
-
invert(): TapeOp;
|
|
877
|
-
label?: string;
|
|
878
|
-
}
|
|
879
|
-
/**
|
|
880
|
-
* One future a tape keeps at its current entry: the calls the host made after the mix last went
|
|
881
|
-
* back here, before it made new ones.
|
|
882
|
-
*
|
|
883
|
-
* @category mix
|
|
884
|
-
*/
|
|
885
|
-
export interface TapeBranch {
|
|
886
|
-
/** Its first entry's id, which `switchBranch` takes. */
|
|
887
|
-
id: number;
|
|
888
|
-
label: string;
|
|
889
|
-
timestamp: number;
|
|
890
|
-
/** How many entries run along it from here. */
|
|
891
|
-
length: number;
|
|
892
|
-
/** Whether the mix plays it on from here. */
|
|
893
|
-
current: boolean;
|
|
894
|
-
}
|
|
895
|
-
/**
|
|
896
|
-
* Where a mix keeps the host's calls, by mix time, for `seek`. weasel-history's `History`
|
|
897
|
-
* (`@weasel-js/history`) has this shape. A host reads `branches` and calls `switchBranch` to pick
|
|
898
|
-
* which recorded future plays on; moving it any other way is the mix's job.
|
|
899
|
-
*
|
|
900
|
-
* @category mix
|
|
901
|
-
*/
|
|
902
|
-
export interface Tape {
|
|
903
|
-
recordEntry(ops: TapeOp[], label: string): void;
|
|
904
|
-
undoDepth(): number;
|
|
905
|
-
timestampAt(i: number): number | undefined;
|
|
906
|
-
depthAt(t: number): number;
|
|
907
|
-
goto(n: number): void;
|
|
908
|
-
redo(): void;
|
|
909
|
-
prune(t: number): void;
|
|
910
|
-
branches(): readonly TapeBranch[];
|
|
911
|
-
switchBranch(id: number): void;
|
|
912
|
-
}
|
|
913
|
-
/**
|
|
914
|
-
* Makes a mix's tape: weasel-history's `createHistory` is one. The mix passes the clock it stamps
|
|
915
|
-
* calls with, branching on, so a call made after going back keeps the old future as a branch, and
|
|
916
|
-
* coalescing off.
|
|
917
|
-
*
|
|
918
|
-
* @category mix
|
|
919
|
-
*/
|
|
920
|
-
export type TapeMaker = (adapter: unknown, opts: {
|
|
921
|
-
now: () => number;
|
|
922
|
-
branching: boolean;
|
|
923
|
-
coalesceWindowMs: number;
|
|
924
|
-
}) => Tape;
|
|
925
|
-
/**
|
|
926
|
-
* How sure a projection is of one channel: `exact` where only the clock and known changes drove
|
|
927
|
-
* it; `stepped` where state was advanced across a gap in one go, which is as good as the patch's
|
|
928
|
-
* step makes it; `held` where it depends on input from outside the clock, whose value at that time
|
|
929
|
-
* is not known, so the value it had is held.
|
|
930
|
-
*
|
|
931
|
-
* @category mix
|
|
932
|
-
*/
|
|
933
|
-
export type Doubt = 'exact' | 'stepped' | 'held';
|
|
934
|
-
/**
|
|
935
|
-
* The mix read at another time: what `probe` would give at that timestamp, with nothing in the
|
|
936
|
-
* live mix moved. Valid until the mix is next synced or cued.
|
|
937
|
-
*
|
|
938
|
-
* @category mix
|
|
939
|
-
*/
|
|
940
|
-
export interface Projection<I, O> {
|
|
941
|
-
/** The mix time it reads at. */
|
|
942
|
-
readonly timestamp: number;
|
|
943
|
-
/** The merged pose for one subject at this projection's timestamp. */
|
|
944
|
-
probe(subject: I, out?: O): O;
|
|
945
|
-
/** Per channel, how sure that pose is; the least sure voice that fed a channel decides. */
|
|
946
|
-
assess(subject: I): {
|
|
947
|
-
[K in keyof O]-?: Doubt;
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* Arrays for `pull` to write, one per channel it reads: any channel whose value is a number or an
|
|
952
|
-
* array of numbers.
|
|
953
|
-
*
|
|
954
|
-
* @category mix
|
|
955
|
-
*/
|
|
956
|
-
export type Columns<O> = {
|
|
957
|
-
[K in keyof O as NonNullable<O[K]> extends number | readonly number[] ? K : never]?: Float64Array;
|
|
958
|
-
};
|
|
959
|
-
/**
|
|
960
|
-
* The live voices over one kit, folded into one pose per subject per frame.
|
|
961
|
-
*
|
|
962
|
-
* @category mix
|
|
963
|
-
*/
|
|
964
|
-
export interface Mix<I, O, H = unknown> {
|
|
965
|
-
/** Cues a voice. Throws when the engine cannot run the patch's form, or the kit lacks a channel. */
|
|
966
|
-
cue(spec: VoiceSpec<I, O, H>): Handle<I>;
|
|
967
|
-
/**
|
|
968
|
-
* N voices whose weights split one signal, cued into one locus so they fold as alternatives. The
|
|
969
|
-
* signal is read once per subject per frame, with the first member's setting, and every member
|
|
970
|
-
* takes its share of that one reading; a signal keeping state keeps it once, not per member.
|
|
971
|
-
*/
|
|
972
|
-
blend(patches: readonly Patch<I, O, unknown, H>[], by: Signal<I, H>, spec?: Omit<VoiceSpec<I, O, H>, 'patch' | 'weight' | 'locus'>): Handle<I>[];
|
|
973
|
-
/**
|
|
974
|
-
* Cues an owner: a voice with no patch that holds the voices cued with `owner` set to its handle,
|
|
975
|
-
* and plays them on its own clock, so they can be placed, timed and faded as one. Its handle acts
|
|
976
|
-
* on all of them: `rate` and `ramp` multiply into theirs, `seek` moves their clocks with its own
|
|
977
|
-
* and leaves their state where it is, and `weight` and `fade()` multiply into their weights, by
|
|
978
|
-
* what its `weightOf` reports; it fades as a whole, not by subject or at rest. It is
|
|
979
|
-
* `played` once every voice it held has finished its passes, and leaves, `done`, with its last; a
|
|
980
|
-
* fade that ends takes the rest with it. One that never holds a voice stays until faded. Owners
|
|
981
|
-
* nest. Throws for a `loop`: a pass would have to restart its children.
|
|
982
|
-
*/
|
|
983
|
-
owns(spec: OwnerSpec<I, H>): Handle<I>;
|
|
984
|
-
/**
|
|
985
|
-
* Cues a span: an owner that lays out the voices it holds in `order` and fits them into its
|
|
986
|
-
* `duration`, again each time one joins or leaves early. A child's start and rate are the
|
|
987
|
-
* span's to set, so it takes neither `start` nor an anchored start; its `SpanHints` say how it
|
|
988
|
-
* may give way. A span with a budget stays until the budget has passed, though its children
|
|
989
|
-
* finish sooner, so late ones can still join, and its `end` mark is where its children end or
|
|
990
|
-
* its budget does, whichever is later. A voice that loops for good cannot join one.
|
|
991
|
-
*/
|
|
992
|
-
span(spec: SpanSpec<I, H>): SpanHandle<I>;
|
|
993
|
-
/**
|
|
994
|
-
* The host reports the clock, once a frame. Nothing advances at the call. Throws for a timestamp
|
|
995
|
-
* earlier than the last sync's, short of a `rebase`: the host's clock only goes forward, and
|
|
996
|
-
* `seek` moves the mix.
|
|
997
|
-
*/
|
|
998
|
-
sync(timestamp: number): void;
|
|
999
|
-
/**
|
|
1000
|
-
* The time between the last sync and the next one is not to count: a host calls it when a
|
|
1001
|
-
* hidden tab comes back. Every voice, fade and subject resumes where it was left.
|
|
1002
|
-
*/
|
|
1003
|
-
rebase(): void;
|
|
1004
|
-
/**
|
|
1005
|
-
* The mix's own playback rate, multiplied into every voice's: 1 is real time and 0 pauses the
|
|
1006
|
-
* whole mix. A negative rate throws: the mix plays only forward, and `seek` moves it back. Setting it changes speed at
|
|
1007
|
-
* once; `ramp` eases into a new one. It scales mix time, which everything a voice owns runs on:
|
|
1008
|
-
* its clock, its fades and a handle's ramp, `stagger`, an anchor's `by`, `stepMs`, `maxDt`,
|
|
1009
|
-
* `history.ms`, every `dt`, and `setting.timestamp`. Timestamps on the host's clock name the same
|
|
1010
|
-
* moment whatever the rate does: a `start`, an anchor given as a number, an announced mark, what
|
|
1011
|
-
* `marks` reports and the time `project` reads, so a start ahead of a paused mix waits for the
|
|
1012
|
-
* host's clock to reach it. A weight signal is still asked at every probe, so one reading host
|
|
1013
|
-
* input follows it while the mix is paused.
|
|
1014
|
-
*/
|
|
1015
|
-
rate: number;
|
|
1016
|
-
/**
|
|
1017
|
-
* Moves the mix's rate to `rate` linearly over `over` ms of the host's clock, as `Handle.ramp`
|
|
1018
|
-
* moves a voice's. Mix time integrates the ramp and a voice's clock integrates mix time, so a ramp
|
|
1019
|
-
* on both multiplies and every position stays continuous. A later `rate` write or `ramp` replaces
|
|
1020
|
-
* it.
|
|
1021
|
-
*/
|
|
1022
|
-
ramp(rate: number, over: number): void;
|
|
1023
|
-
/**
|
|
1024
|
-
* The merged pose for one subject at the synced frame, written into `out` when given. Without
|
|
1025
|
-
* it, each call makes a new object, so a host reading every subject every frame passes `out` or
|
|
1026
|
-
* reads by `pull`.
|
|
1027
|
-
*/
|
|
1028
|
-
probe(subject: I, out?: O): O;
|
|
1029
|
-
/**
|
|
1030
|
-
* Writes each subject's pose into arrays, one per channel, subject by subject in the order given:
|
|
1031
|
-
* what `probe(subject, out)` gives, without a pose object per subject. A channel of `n` numbers
|
|
1032
|
-
* takes `n` places per subject, side by side; one with no value for a subject writes NaN there.
|
|
1033
|
-
* Fastest while every voice runs on a lane, and when `subjects` is an array read again in the
|
|
1034
|
-
* same order: the mix remembers the last array's subjects by position, holding them until the
|
|
1035
|
-
* next `pull`, and skips looking up any still in its place. Throws when an array is too short for
|
|
1036
|
-
* the subjects.
|
|
1037
|
-
*/
|
|
1038
|
-
pull(subjects: Iterable<I>, into: Columns<O>): void;
|
|
1039
|
-
/**
|
|
1040
|
-
* Reads the mix at another mix time, without moving it. Ahead of the mix it plays what is cued
|
|
1041
|
-
* forward, and throws for a time past a call the tape will play again after a `seek` back, which
|
|
1042
|
-
* only a seek there makes; behind it, it needs `history`, and throws for a time older than the
|
|
1043
|
-
* history reaches. On a transport it reads every mix on it together, so anchors across them
|
|
1044
|
-
* answer.
|
|
1045
|
-
*/
|
|
1046
|
-
project(time: number): Projection<I, O>;
|
|
1047
|
-
/**
|
|
1048
|
-
* Moves the mix to mix time `time`, as it stood at the end of that frame, and plays on from
|
|
1049
|
-
* there. Needs `history` with a `tape`, which records the host's calls by mix time.
|
|
1050
|
-
*
|
|
1051
|
-
* Back, the mix restores itself: controls, records, voices and marks as they stood then. Voices
|
|
1052
|
-
* that left after it are back on the handles the host holds, their `done` and `played` starting
|
|
1053
|
-
* over where they had settled since. Voices cued after it wait as `pending` until the mix plays
|
|
1054
|
-
* their cue again. Stateful voices restart from the copy `history` kept nearest before it and
|
|
1055
|
-
* step once to it, exact under `stepMs`. A subject faded out of a voice or dropped after it comes
|
|
1056
|
-
* back with the record it had, a motion patch's state included. Recorded input and host fields
|
|
1057
|
-
* after it are let go: after a seek back, signals and host fields read live again, and `assess`
|
|
1058
|
-
* reports what they fed as `held`.
|
|
1059
|
-
*
|
|
1060
|
-
* Forward, through a sync or a later seek, the mix plays the recorded calls again at the mix
|
|
1061
|
-
* times they were made: cues, handle writes, fades, retargets and pushes, its rate, marks,
|
|
1062
|
-
* `mute` and `drop`. A call the host makes while there are recorded calls ahead starts a new
|
|
1063
|
-
* branch, and the tape keeps the old future beside it; `tape.switchBranch` picks one back.
|
|
1064
|
-
* Playing past a time again sends its events and books its marks and hits again.
|
|
1065
|
-
*
|
|
1066
|
-
* The host goes on passing its own clock: the next `sync` reads the moment sought plus the
|
|
1067
|
-
* host's time since its last sync. Throws for a time older than history reaches, and before
|
|
1068
|
-
* the first sync. With a history `store`, a time older than memory needs `prepare` first, or
|
|
1069
|
-
* throws `HistoryMiss` before anything moves.
|
|
1070
|
-
*/
|
|
1071
|
-
seek(time: number): void;
|
|
1072
|
-
/** As `Transport.prepare`, for a mix made alone. */
|
|
1073
|
-
prepare(time: number): Promise<void>;
|
|
1074
|
-
/**
|
|
1075
|
-
* The mix clock at the last sync or seek, which `seek` and `project` take; NaN before the first
|
|
1076
|
-
* sync. Host time at the mix's rate, less what `rebase` took out and `seek` moved.
|
|
1077
|
-
*/
|
|
1078
|
-
readonly now: number;
|
|
1079
|
-
/** The tape `history.tape` made, undefined without one. */
|
|
1080
|
-
readonly tape: Tape | undefined;
|
|
1081
|
-
/**
|
|
1082
|
-
* Every channel at rest for this subject this frame, so a host can skip the write. After a probe
|
|
1083
|
-
* of the subject this frame, it answers for the pose that probe gave, without folding again.
|
|
1084
|
-
*/
|
|
1085
|
-
atRest(subject: I): boolean;
|
|
1086
|
-
/**
|
|
1087
|
-
* A handle on every voice still in the mix, pending, live, frozen or fading, in the order they were
|
|
1088
|
-
* cued; given a tag, only the voices whose `tags` carry it. Each is the handle `cue` returned for
|
|
1089
|
-
* that voice, so a listed handle is `===` the cued one.
|
|
1090
|
-
*/
|
|
1091
|
-
voices(tag?: string): Handle<I>[];
|
|
1092
|
-
/** Anything still contributing, fading, or pending. */
|
|
1093
|
-
readonly live: boolean;
|
|
1094
|
-
/**
|
|
1095
|
-
* Another frame would change no pose, so a host's frame loop may sleep: every voice is done, frozen
|
|
1096
|
-
* at a plain weight, or a motion whose every subject has landed on its target. At rate 0 it is
|
|
1097
|
-
* enough that every voice not done has started, at a plain weight, with no anchor. A change made
|
|
1098
|
-
* since the last sync, a retarget or a rate included, makes it false until the next.
|
|
1099
|
-
*/
|
|
1100
|
-
readonly inert: boolean;
|
|
1101
|
-
/**
|
|
1102
|
-
* Calls `fn` when a host call makes the mix need frames again after a sync: a cue, a fade, a
|
|
1103
|
-
* handle's or the mix's rate, a seek, a `drop`, a motion retargeted. It fires once until the next
|
|
1104
|
-
* sync clears the change, and never during `sync`. Returns a function that unsubscribes `fn`.
|
|
1105
|
-
* A frame loop sleeping on `inert` subscribes here to wake.
|
|
1106
|
-
*/
|
|
1107
|
-
onWake(fn: () => void): () => void;
|
|
1108
|
-
/** Fades every voice out: over `over` when given, over each voice's own `fade.out` otherwise. */
|
|
1109
|
-
mute(opts?: {
|
|
1110
|
-
over?: number;
|
|
1111
|
-
}): void;
|
|
1112
|
-
/** Forgets per-subject state, a motion patch's for the subject included. */
|
|
1113
|
-
drop(subject: I): void;
|
|
1114
|
-
/**
|
|
1115
|
-
* Puts a named mark on a score, for anchors to target as they target a voice's marks: a voice
|
|
1116
|
-
* placed `{ with: 'reply' }` waits until the host announces `reply`. `at` is a timestamp on the
|
|
1117
|
-
* host's clock, default now, and may lie ahead, so a read ahead sees it. A mark stays while it is
|
|
1118
|
-
* ahead or while the mix's history reaches it.
|
|
1119
|
-
*/
|
|
1120
|
-
announce(name: string, opts?: {
|
|
1121
|
-
at?: number;
|
|
1122
|
-
score?: string;
|
|
1123
|
-
tags?: readonly string[];
|
|
1124
|
-
}): void;
|
|
1125
|
-
/**
|
|
1126
|
-
* Every mark the plan knows between two timestamps on the host's clock, earliest first: when
|
|
1127
|
-
* voices start, are fully in, begin to fade and are gone, and what the host announced. A mark
|
|
1128
|
-
* nothing has fixed yet, such as the out of a voice that loops for good, is not listed.
|
|
1129
|
-
*/
|
|
1130
|
-
marks(from: number, to: number): Marked[];
|
|
1131
|
-
/**
|
|
1132
|
-
* Every event patches have sent since the last drain, earliest first, in the order they were sent
|
|
1133
|
-
* where two share a timestamp. A subject's events are made while it catches up, which is when it is
|
|
1134
|
-
* probed, so one nobody probes has sent nothing yet: promptness is the host's, by probing. A
|
|
1135
|
-
* stateless patch's `at` on a lane is the exception: it runs at the frame's first probe for every
|
|
1136
|
-
* subject probed that frame or the last. Under `stepMs` each carries the end of the interval it happened in, so
|
|
1137
|
-
* what is sent and when does not depend on how the host spaces its probes. Time `rebase` took out
|
|
1138
|
-
* sends nothing. Given a tag, it takes only the events of voices carrying it and leaves the rest for
|
|
1139
|
-
* whoever drains them.
|
|
1140
|
-
*/
|
|
1141
|
-
drain<E = unknown>(tag?: string): Sent<I, E>[];
|
|
1142
|
-
/**
|
|
1143
|
-
* Hands the host each mark and hit before it comes, against a clock of its own, so it can schedule
|
|
1144
|
-
* the thing itself: a sound on an `AudioContext`, a MIDI message with a timestamp, a video loaded
|
|
1145
|
-
* before the voice that shows it starts. Booking runs at each `sync`, `ahead` ms out, and a
|
|
1146
|
-
* booking whose time moves is stopped and taken again. Nothing is booked twice: a mark is known by
|
|
1147
|
-
* its voice and which mark, a hit by its voice, index and pass. `project` books nothing, and
|
|
1148
|
-
* nothing about booking is replayed under `history`. A mix with no booker pays nothing for it.
|
|
1149
|
-
*/
|
|
1150
|
-
book<E = unknown>(opts: BookOptions<E>): Booker;
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* The implementation behind a mix: which patch forms it runs, and how it makes one.
|
|
1154
|
-
*
|
|
1155
|
-
* @category engine
|
|
1156
|
-
*/
|
|
1157
|
-
export interface Engine {
|
|
1158
|
-
readonly name: string;
|
|
1159
|
-
/** Which patch forms this engine can run. A voice it cannot run is refused at `cue`, by name. */
|
|
1160
|
-
readonly runs: ReadonlySet<'fn' | 'keys' | 'motion'>;
|
|
1161
|
-
create<I, O, H = unknown>(kit: Kit<O>, opts: MixOptions<H>): Mix<I, O, H>;
|
|
1162
|
-
}
|
|
1
|
+
export type * from './types/channel.js';
|
|
2
|
+
export type * from './types/history.js';
|
|
3
|
+
export type * from './types/mix.js';
|
|
4
|
+
export type * from './types/patch.js';
|
|
5
|
+
export type * from './types/place.js';
|
|
6
|
+
export type * from './types/transport.js';
|
|
7
|
+
export type * from './types/voice.js';
|