@msb235/blits 0.2.0 → 0.3.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 +96 -0
- package/README.md +9 -2
- package/dist/channels.d.ts +41 -7
- package/dist/channels.js +184 -29
- package/dist/clock.d.ts +19 -0
- package/dist/clock.js +44 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/lanes.d.ts +207 -0
- package/dist/lanes.js +928 -0
- package/dist/mixer.d.ts +185 -2
- package/dist/mixer.js +1264 -139
- package/dist/motion.d.ts +169 -9
- package/dist/motion.js +564 -112
- package/dist/numbers.d.ts +22 -0
- package/dist/numbers.js +64 -0
- package/dist/patch.d.ts +13 -2
- package/dist/patch.js +44 -18
- package/dist/reading.d.ts +23 -0
- package/dist/reading.js +23 -0
- package/dist/types.d.ts +242 -11
- package/docs/schema.html +119 -24
- package/package.json +3 -6
package/dist/lanes.d.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { Subject, Voice } from './mixer.js';
|
|
2
|
+
import type { Channel } from './types.js';
|
|
3
|
+
/** What qualifying needs of one voice: whether its patch and spec can run on a lane, and its channels. */
|
|
4
|
+
export interface Candidate {
|
|
5
|
+
readonly id: number;
|
|
6
|
+
readonly fits: boolean;
|
|
7
|
+
readonly slots: readonly number[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Which channels run as lanes and which voices run on them: the fixed point where every voice
|
|
11
|
+
* writing a laned channel fits and writes only laned channels. Only channels some laned voice
|
|
12
|
+
* writes are laned.
|
|
13
|
+
*/
|
|
14
|
+
export declare function qualify(numeric: readonly boolean[], voices: readonly Candidate[]): {
|
|
15
|
+
channels: boolean[];
|
|
16
|
+
voices: Set<number>;
|
|
17
|
+
};
|
|
18
|
+
/** What a lane fill asks of the mix it belongs to. */
|
|
19
|
+
export interface LaneHost<I, O> {
|
|
20
|
+
readonly voices: readonly Voice<I, O>[];
|
|
21
|
+
readonly channels: readonly Channel<unknown>[];
|
|
22
|
+
readonly names: readonly string[];
|
|
23
|
+
/** Whether a voice's patch and spec can run on a lane, its channels aside. */
|
|
24
|
+
fits(voice: Voice<I, O>): boolean;
|
|
25
|
+
/** The voice's record for a subject this probe has already linked it to. */
|
|
26
|
+
meet(voice: Voice<I, O>, subject: I): Subject<unknown>;
|
|
27
|
+
/** The voices whose `subjects` name the subject, in voice order. */
|
|
28
|
+
naming(subject: I): readonly Voice<I, O>[] | undefined;
|
|
29
|
+
/** The voice's own fade for a subject whose delay ran out at `since`. */
|
|
30
|
+
envelope(voice: Voice<I, O>, since: number): number;
|
|
31
|
+
/** Fills the voice's setting and the send target for a call to its patch. */
|
|
32
|
+
ready(voice: Voice<I, O>, subject: I, held: Subject<unknown>, elapsed: number, pass: number, weight: number): void;
|
|
33
|
+
/** Sets `reading.horizon` for the voice and a subject delayed `delay` voice ms. */
|
|
34
|
+
horizon(voice: Voice<I, O>, delay: number): void;
|
|
35
|
+
/** Whether the mix keeps history, so a record a patch call changed may need a copy kept. */
|
|
36
|
+
readonly keeps: boolean;
|
|
37
|
+
/** After a patch call, keeps history of a record that grew kept state. */
|
|
38
|
+
after(voice: Voice<I, O>, held: Subject<unknown>): void;
|
|
39
|
+
/** A patch call left kept state on a record: the voice is stateful from now on. */
|
|
40
|
+
kept(voice: Voice<I, O>): void;
|
|
41
|
+
}
|
|
42
|
+
/** One channel `pull` writes: where in the kit, how many numbers a subject, and its rest. */
|
|
43
|
+
export interface Column {
|
|
44
|
+
key: string;
|
|
45
|
+
slot: number;
|
|
46
|
+
axes: number;
|
|
47
|
+
out: Float64Array;
|
|
48
|
+
/** The rest, clamped, or NaN for a channel with none. */
|
|
49
|
+
rest: Float64Array;
|
|
50
|
+
bounds: readonly [number, number] | undefined;
|
|
51
|
+
}
|
|
52
|
+
export declare function clampRun(out: Float64Array, at: number, n: number, [lo, hi]: readonly [number, number]): void;
|
|
53
|
+
/**
|
|
54
|
+
* The lanes of one mix: subject numbers, which channels and voices run on lanes, and the values a
|
|
55
|
+
* frame's fill leaves for probes to copy.
|
|
56
|
+
*/
|
|
57
|
+
export declare class Lanes<I, O> {
|
|
58
|
+
private readonly host;
|
|
59
|
+
private readonly numbers;
|
|
60
|
+
private lanes;
|
|
61
|
+
/** The lanes a fill visits: every lane but the solo ones. */
|
|
62
|
+
private runs;
|
|
63
|
+
/** The lanes over every subject that have started playing, by epoch. */
|
|
64
|
+
private dense;
|
|
65
|
+
private readonly byId;
|
|
66
|
+
private laned;
|
|
67
|
+
/** By kit slot, the laned channel there. */
|
|
68
|
+
private bySlot;
|
|
69
|
+
/** By kit slot, whether a fill leaves the channel's values for probes to copy. */
|
|
70
|
+
readonly copies: boolean[];
|
|
71
|
+
/** Whether every voice in the mix is on a lane, so a filled subject has nothing left to fold. */
|
|
72
|
+
whole: boolean;
|
|
73
|
+
private cap;
|
|
74
|
+
private epochs;
|
|
75
|
+
/**
|
|
76
|
+
* Per subject number, `SLOT` numbers side by side, so a probe reads one place in memory: which
|
|
77
|
+
* fill last wrote it (0 for none); the latest lane epoch a probe of it has checked it against;
|
|
78
|
+
* how many idle lanes reach it, since a probe reads lanes only where none do; and the probe count
|
|
79
|
+
* at its last probe read from the lanes and at its last probe folded by the general path, with
|
|
80
|
+
* the fill the former read, which say whether a lane or a record holds what `weightOf` reports.
|
|
81
|
+
*/
|
|
82
|
+
private per;
|
|
83
|
+
private fills;
|
|
84
|
+
private probes;
|
|
85
|
+
/**
|
|
86
|
+
* Each subject by number as last probed, held from that probe until the next fill uses it, so a
|
|
87
|
+
* fill rarely looks one up through its weak reference, which costs on every look. A host that
|
|
88
|
+
* stops syncing keeps at most one frame's probed subjects alive until its next fill, and none
|
|
89
|
+
* once no lane remains.
|
|
90
|
+
*/
|
|
91
|
+
private subjects;
|
|
92
|
+
/** Whether a probe has held a subject since the last fill let them go. */
|
|
93
|
+
private holding;
|
|
94
|
+
/** While a fill runs, so a probe a patch makes from inside it takes the general path. */
|
|
95
|
+
private filling;
|
|
96
|
+
/**
|
|
97
|
+
* Numbers a fill left to the general path: handed out while it ran, or with a voice whose call
|
|
98
|
+
* the general path has to make.
|
|
99
|
+
*/
|
|
100
|
+
private readonly late;
|
|
101
|
+
private keeps;
|
|
102
|
+
private now;
|
|
103
|
+
private filledAt;
|
|
104
|
+
/** `reading.moved` at the last fill, so a retarget or push between two probes refills. */
|
|
105
|
+
private moved;
|
|
106
|
+
/** The `now` of the latest probe, and the probe count before its first, to tell a probe this frame. */
|
|
107
|
+
private frameAt;
|
|
108
|
+
private frameProbes;
|
|
109
|
+
/** The probe counts the last frame with a probe began and ended at, which lanes go idle by. */
|
|
110
|
+
private lastFrom;
|
|
111
|
+
private lastTo;
|
|
112
|
+
/** Set when a frame's first probe arrives, so its first fill decides which lanes go idle. */
|
|
113
|
+
private fresh;
|
|
114
|
+
/** Subjects probed this frame and in the last frame with a probe, counted once each. */
|
|
115
|
+
private distinct;
|
|
116
|
+
private lastDistinct;
|
|
117
|
+
/** Numbered subjects alive. */
|
|
118
|
+
private live;
|
|
119
|
+
private filledVersion;
|
|
120
|
+
private qualifiedVersion;
|
|
121
|
+
constructor(host: LaneHost<I, O>);
|
|
122
|
+
/** A change that may move a voice on or off its lane: qualify again, then fill again. */
|
|
123
|
+
invalidate(): void;
|
|
124
|
+
/** A change to a laned voice's weight or clock between probes: fill again. */
|
|
125
|
+
refill(): void;
|
|
126
|
+
/** Numbers a subject the mix sees for the first time. */
|
|
127
|
+
number(subject: I): number;
|
|
128
|
+
release(slot: number): void;
|
|
129
|
+
/**
|
|
130
|
+
* A laned voice's weight for a subject at the last frame a probe read it from the lane; undefined
|
|
131
|
+
* where the subject's record holds it instead, because its last probe took the general path or
|
|
132
|
+
* the voice is not on a lane.
|
|
133
|
+
*/
|
|
134
|
+
weightOf(id: number, slot: number): number | undefined;
|
|
135
|
+
private reported;
|
|
136
|
+
/**
|
|
137
|
+
* Fills the lanes once a frame, and says whether this probe of a subject reads its values from
|
|
138
|
+
* them. One that a lane has not met yet, newly numbered or newly reached, takes the general path
|
|
139
|
+
* this frame, which is where it is first seen; so does one probed from inside a fill.
|
|
140
|
+
*/
|
|
141
|
+
prepare(slot: number, subject: I, now: number, version: number): boolean;
|
|
142
|
+
private general;
|
|
143
|
+
/** Whether a probe has read the subject since the frame began, on either path. */
|
|
144
|
+
private probedThisFrame;
|
|
145
|
+
/**
|
|
146
|
+
* Writes a subject's values into each column at subject `n`'s places, for a probe that reads from
|
|
147
|
+
* the lanes while every voice is on one: a channel no lane holds is at rest.
|
|
148
|
+
*/
|
|
149
|
+
write(slot: number, columns: readonly Column[], n: number): void;
|
|
150
|
+
/** Writes a subject's laned values into a pose, each array channel into a new array. */
|
|
151
|
+
copy(slot: number, pose: Record<string, unknown>): void;
|
|
152
|
+
/**
|
|
153
|
+
* Gives a probed subject a position on every lane that started playing since the subject was last
|
|
154
|
+
* checked and that reaches it. True when any did, so the probe takes the general path.
|
|
155
|
+
*/
|
|
156
|
+
private meet;
|
|
157
|
+
/** Counts an idle lane more or fewer reaching a subject. */
|
|
158
|
+
private reach;
|
|
159
|
+
private forget;
|
|
160
|
+
private grow;
|
|
161
|
+
private requalify;
|
|
162
|
+
/** Hands a voice back to the general path, with the weights `weightOf` reports kept on its records. */
|
|
163
|
+
private leave;
|
|
164
|
+
private fillAll;
|
|
165
|
+
/**
|
|
166
|
+
* Sets a lane idle or busy by the share of its subjects probed in the last frame that had a probe,
|
|
167
|
+
* read from about 256 of them a prime stride apart, from an offset that moves each frame, so a host
|
|
168
|
+
* probing every second or third subject is not read as probing all or none. Both paths give the
|
|
169
|
+
* same values, so this only picks the cheaper.
|
|
170
|
+
*/
|
|
171
|
+
private pace;
|
|
172
|
+
private flip;
|
|
173
|
+
/** Leaves a lane's subjects to the general path until it wakes, keeping what `weightOf` reports. */
|
|
174
|
+
private rest;
|
|
175
|
+
private wake;
|
|
176
|
+
private subjectAt;
|
|
177
|
+
/** One voice's contribution to every subject it plays on. */
|
|
178
|
+
private run;
|
|
179
|
+
private one;
|
|
180
|
+
/**
|
|
181
|
+
* A motion voice's value for a subject, sampled from the patch's state as its `at` would, but only
|
|
182
|
+
* where that sample changes nothing: one with a change to stamp, commit or let go of goes to the
|
|
183
|
+
* general path, which samples it if and when a probe asks, as it would with no lanes. A probe
|
|
184
|
+
* this frame already read keeps the value it read, as the general path's record would.
|
|
185
|
+
*/
|
|
186
|
+
private move;
|
|
187
|
+
/** The delta a motion voice's last sample for position `p` made, built from `samples`. */
|
|
188
|
+
private sampled;
|
|
189
|
+
/**
|
|
190
|
+
* A probe this frame read a motion voice's value for the subject from an earlier fill: write onto
|
|
191
|
+
* its record what the general path's sample would have, so a later read this frame reuses it.
|
|
192
|
+
*/
|
|
193
|
+
private settle;
|
|
194
|
+
/** For a keys voice: the delta's value for each channel it writes, read once per phase. */
|
|
195
|
+
private gather;
|
|
196
|
+
/** Folds what `gather` read into a subject's laned values. */
|
|
197
|
+
private fold;
|
|
198
|
+
/**
|
|
199
|
+
* Folds a delta a patch returned into a subject's laned values. The first few channels are read
|
|
200
|
+
* at a site of their own, which in most mixes sees one channel name and stays fast, where one
|
|
201
|
+
* site reading every name in turn slows every read.
|
|
202
|
+
*/
|
|
203
|
+
private foldDelta;
|
|
204
|
+
/** Folds a motion sample's axes, kept apart from `foldInto` so neither reads two array kinds. */
|
|
205
|
+
private foldRun;
|
|
206
|
+
private foldInto;
|
|
207
|
+
}
|