@sudobility/music_types 0.12.1 → 0.13.2
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/CLAUDE.md +20 -0
- package/dist/bytes/base64.d.ts +40 -0
- package/dist/bytes/base64.d.ts.map +1 -0
- package/dist/bytes/base64.js +101 -0
- package/dist/bytes/base64.js.map +1 -0
- package/dist/bytes/index.d.ts +2 -0
- package/dist/bytes/index.d.ts.map +1 -0
- package/dist/bytes/index.js +2 -0
- package/dist/bytes/index.js.map +1 -0
- package/dist/domain/commands/repair-commands.d.ts +10 -0
- package/dist/domain/commands/repair-commands.d.ts.map +1 -0
- package/dist/domain/commands/repair-commands.js +25 -0
- package/dist/domain/commands/repair-commands.js.map +1 -0
- package/dist/domain/validation/limits.d.ts +32 -0
- package/dist/domain/validation/limits.d.ts.map +1 -0
- package/dist/domain/validation/limits.js +32 -0
- package/dist/domain/validation/limits.js.map +1 -0
- package/dist/domain/validation/repair.d.ts +48 -0
- package/dist/domain/validation/repair.d.ts.map +1 -0
- package/dist/domain/validation/repair.js +389 -0
- package/dist/domain/validation/repair.js.map +1 -0
- package/dist/domain/validation/validator.d.ts.map +1 -1
- package/dist/domain/validation/validator.js +1 -22
- package/dist/domain/validation/validator.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/model/api.d.ts +16 -0
- package/dist/model/api.d.ts.map +1 -1
- package/dist/model/api.js +6 -0
- package/dist/model/api.js.map +1 -1
- package/dist/model/position.d.ts +16 -0
- package/dist/model/position.d.ts.map +1 -1
- package/dist/platform/playback.d.ts +9 -90
- package/dist/platform/playback.d.ts.map +1 -1
- package/dist/position/index.d.ts +3 -0
- package/dist/position/index.d.ts.map +1 -0
- package/dist/position/index.js +3 -0
- package/dist/position/index.js.map +1 -0
- package/dist/position/music-position.d.ts +69 -0
- package/dist/position/music-position.d.ts.map +1 -0
- package/dist/position/music-position.js +99 -0
- package/dist/position/music-position.js.map +1 -0
- package/dist/position/singleton.d.ts +34 -0
- package/dist/position/singleton.d.ts.map +1 -0
- package/dist/position/singleton.js +33 -0
- package/dist/position/singleton.js.map +1 -0
- package/package.json +1 -1
package/dist/model/api.d.ts
CHANGED
|
@@ -104,12 +104,23 @@ export type Snapshot = {
|
|
|
104
104
|
publicId?: string;
|
|
105
105
|
/** Shown on the Community list. Never the account email. */
|
|
106
106
|
publisherName?: string;
|
|
107
|
+
/**
|
|
108
|
+
* The title a stranger sees, set when published.
|
|
109
|
+
*
|
|
110
|
+
* Kept apart from `name`, which is the version label this project's own
|
|
111
|
+
* picker draws: "Version 1" is what the tree needs and not what a public
|
|
112
|
+
* page should be called, and renaming for the public must not rewrite the
|
|
113
|
+
* history's labels.
|
|
114
|
+
*/
|
|
115
|
+
publicName?: string;
|
|
107
116
|
createdAt: string;
|
|
108
117
|
};
|
|
109
118
|
/** What an anonymous visitor receives. Carries no owner identity, by construction. */
|
|
110
119
|
export type PublishedSnapshot = {
|
|
111
120
|
publicId: string;
|
|
112
121
|
name: string;
|
|
122
|
+
/** The public title. Falls back to `name` for anything published before it existed. */
|
|
123
|
+
publicName: string;
|
|
113
124
|
publisherName: string;
|
|
114
125
|
score: Score;
|
|
115
126
|
createdAt: string;
|
|
@@ -473,6 +484,7 @@ export declare const snapshotSummarySchema: z.ZodObject<{
|
|
|
473
484
|
createdAt: z.ZodString;
|
|
474
485
|
publicId: z.ZodOptional<z.ZodString>;
|
|
475
486
|
publisherName: z.ZodOptional<z.ZodString>;
|
|
487
|
+
publicName: z.ZodOptional<z.ZodString>;
|
|
476
488
|
}, z.core.$strip>;
|
|
477
489
|
export declare const snapshotSchema: z.ZodObject<{
|
|
478
490
|
id: z.ZodString;
|
|
@@ -482,6 +494,7 @@ export declare const snapshotSchema: z.ZodObject<{
|
|
|
482
494
|
createdAt: z.ZodString;
|
|
483
495
|
publicId: z.ZodOptional<z.ZodString>;
|
|
484
496
|
publisherName: z.ZodOptional<z.ZodString>;
|
|
497
|
+
publicName: z.ZodOptional<z.ZodString>;
|
|
485
498
|
score: z.ZodObject<{
|
|
486
499
|
id: z.ZodString;
|
|
487
500
|
version: z.ZodNumber;
|
|
@@ -781,6 +794,7 @@ export declare const snapshotSchema: z.ZodObject<{
|
|
|
781
794
|
export declare const publishedSnapshotSchema: z.ZodObject<{
|
|
782
795
|
publicId: z.ZodString;
|
|
783
796
|
name: z.ZodString;
|
|
797
|
+
publicName: z.ZodString;
|
|
784
798
|
publisherName: z.ZodString;
|
|
785
799
|
score: z.ZodObject<{
|
|
786
800
|
id: z.ZodString;
|
|
@@ -1079,10 +1093,12 @@ export declare const communityItemSchema: z.ZodObject<{
|
|
|
1079
1093
|
name: z.ZodString;
|
|
1080
1094
|
createdAt: z.ZodString;
|
|
1081
1095
|
publicId: z.ZodString;
|
|
1096
|
+
publicName: z.ZodString;
|
|
1082
1097
|
publisherName: z.ZodString;
|
|
1083
1098
|
}, z.core.$strip>;
|
|
1084
1099
|
export declare const publishRequestSchema: z.ZodObject<{
|
|
1085
1100
|
publisherName: z.ZodString;
|
|
1101
|
+
publicName: z.ZodString;
|
|
1086
1102
|
}, z.core.$strip>;
|
|
1087
1103
|
export declare const snapshotCreateRequestSchema: z.ZodObject<{
|
|
1088
1104
|
name: z.ZodString;
|
package/dist/model/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAM9C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,uGAAuG;IACvG,MAAM,EAAE,aAAa,CAAC;IACtB,qGAAqG;IACrG,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAE7D;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,IAAI,CAAC;IAChB,wEAAwE;IACxE,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAE7D,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC7B,CAAC;AAMF,eAAO,MAAM,oBAAoB;;;iBAG/B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;iBAM/B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAIlC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;iBAWhC,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGzB,CAAC;AAEH,sFAAsF;AACtF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOlC,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB;;;;;;iBAE9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;iBAM/B,CAAC;AAEH,eAAO,MAAM,2BAA2B;;iBAEtC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;iBAGjC,CAAC;AAMH,eAAO,MAAM,eAAe;;;;;;IAM1B;;;;;OAKG;;IAEH;;;;;OAKG;;IAEH;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,YAAY,GACtB,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEzD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAE1D;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,YAAY,GAClB,WAAW,CAAC,KAAK,CAAC,CAIpB"}
|
package/dist/model/api.js
CHANGED
|
@@ -38,6 +38,7 @@ export const snapshotSummarySchema = z.object({
|
|
|
38
38
|
// picker badges from, and it is also all a publish response needs to return.
|
|
39
39
|
publicId: z.string().min(1).optional(),
|
|
40
40
|
publisherName: z.string().min(1).optional(),
|
|
41
|
+
publicName: z.string().min(1).optional(),
|
|
41
42
|
});
|
|
42
43
|
export const snapshotSchema = snapshotSummarySchema.extend({
|
|
43
44
|
score: scoreSchema,
|
|
@@ -47,6 +48,7 @@ export const snapshotSchema = snapshotSummarySchema.extend({
|
|
|
47
48
|
export const publishedSnapshotSchema = z.object({
|
|
48
49
|
publicId: z.string().min(1),
|
|
49
50
|
name: z.string().min(1),
|
|
51
|
+
publicName: z.string().min(1),
|
|
50
52
|
publisherName: z.string().min(1),
|
|
51
53
|
score: scoreSchema,
|
|
52
54
|
createdAt: z.string().min(1),
|
|
@@ -57,6 +59,10 @@ export const communityItemSchema = publishedSnapshotSchema.omit({
|
|
|
57
59
|
});
|
|
58
60
|
export const publishRequestSchema = z.object({
|
|
59
61
|
publisherName: z.string().min(1).max(80),
|
|
62
|
+
// Required: publishing without a public title would put "Version 1" on a
|
|
63
|
+
// page strangers read. Re-publishing an already-public snapshot is how a
|
|
64
|
+
// title is changed, so this arrives on every publish, not only the first.
|
|
65
|
+
publicName: z.string().min(1).max(200),
|
|
60
66
|
});
|
|
61
67
|
export const snapshotCreateRequestSchema = z.object({
|
|
62
68
|
name: z.string().min(1).max(200),
|
package/dist/model/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"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"}
|
package/dist/model/position.d.ts
CHANGED
|
@@ -39,6 +39,22 @@ export interface IMusicPosition {
|
|
|
39
39
|
* fresher than the last event and is the number the caret should draw at.
|
|
40
40
|
*/
|
|
41
41
|
readonly tick: number;
|
|
42
|
+
/**
|
|
43
|
+
* The last position the transport actually vouched for.
|
|
44
|
+
*
|
|
45
|
+
* Exposed beside {@link tick} deliberately: a smoothed playhead and the
|
|
46
|
+
* report it was projected from are both wanted — a caret glides, while a
|
|
47
|
+
* scrubber, a bar/beat readout or a scroll that follows the music wants the
|
|
48
|
+
* position something corroborated. Keeping the pair on one implementation is
|
|
49
|
+
* what stops them drifting; when the bus kept its own copy of the report and
|
|
50
|
+
* the playhead projected from another, a producer that stopped reporting
|
|
51
|
+
* left the caret gliding the length of the score while everything reading
|
|
52
|
+
* the copy sat at bar one.
|
|
53
|
+
*
|
|
54
|
+
* "Vouched for" rather than "reported": the transport also banks a position
|
|
55
|
+
* when it starts or stops, and that is equally authoritative.
|
|
56
|
+
*/
|
|
57
|
+
readonly reportedTick: number;
|
|
42
58
|
/** Whether the transport is advancing, which is when smoothing applies. */
|
|
43
59
|
readonly isPlaying: boolean;
|
|
44
60
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../src/model/position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,mBAAmB,CAAC;CAClE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/C,kEAAkE;IAClE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5D;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC"}
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../src/model/position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,mBAAmB,CAAC;CAClE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/C,kEAAkE;IAClE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5D;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC"}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* things that import an audio library; everything that depends on playback
|
|
8
8
|
* depends on this file instead, so the engine stays swappable and mockable.
|
|
9
9
|
*/
|
|
10
|
-
import type { ScoreRange } from "../index.js";
|
|
11
10
|
import type { RenderTrack } from "./audio.js";
|
|
12
11
|
export type TransportPlaybackState = "stopped" | "playing" | "paused";
|
|
13
12
|
/**
|
|
@@ -24,29 +23,6 @@ export type SoundingNote = {
|
|
|
24
23
|
/** Its sounding MIDI pitch, so a keyboard can light a key without resolving the event. */
|
|
25
24
|
midi: number;
|
|
26
25
|
};
|
|
27
|
-
export type PlaybackObserver = {
|
|
28
|
-
onPositionTick(tick: number): void;
|
|
29
|
-
/**
|
|
30
|
-
* The notes currently sounding, whenever that set changes.
|
|
31
|
-
*
|
|
32
|
-
* Resolved rather than bare ids. The scheduler already knows each note's
|
|
33
|
-
* track and pitch — it scheduled them — and emitting only the id forced every
|
|
34
|
-
* consumer to search the whole score to get it back: `playingPitchesForTrack`
|
|
35
|
-
* was an O(score) scan per sounding note, twenty times a second.
|
|
36
|
-
*/
|
|
37
|
-
onActiveNotes(notes: SoundingNote[]): void;
|
|
38
|
-
onStateChange(state: TransportPlaybackState): void;
|
|
39
|
-
/**
|
|
40
|
-
* How far along the engine is in becoming able to make a sound.
|
|
41
|
-
*
|
|
42
|
-
* Optional because not every engine has anything to load. The soundfont
|
|
43
|
-
* engine does: tens of megabytes to fetch and several seconds for the synth
|
|
44
|
-
* to digest, all on the first press of Play. Without this the transport
|
|
45
|
-
* simply looks broken for that whole time — which is exactly how it read
|
|
46
|
-
* before there was anywhere to report it.
|
|
47
|
-
*/
|
|
48
|
-
onLoadStateChange?(state: PlaybackLoadState): void;
|
|
49
|
-
};
|
|
50
26
|
/**
|
|
51
27
|
* The engine's readiness to play, for a progress indicator.
|
|
52
28
|
*
|
|
@@ -77,20 +53,6 @@ export type PlaybackTrack = RenderTrack & {
|
|
|
77
53
|
muted: boolean;
|
|
78
54
|
solo: boolean;
|
|
79
55
|
};
|
|
80
|
-
/**
|
|
81
|
-
* A voice to audition, resolved from the GM tables **by the caller**.
|
|
82
|
-
*
|
|
83
|
-
* The engine cannot resolve it: a percussion voice's program addresses a drum
|
|
84
|
-
* kit, and only the GM tables know which kit an arbitrary address falls in.
|
|
85
|
-
* Resolving here is what lets the platform layer keep no catalogue of its own.
|
|
86
|
-
*/
|
|
87
|
-
export type AuditionVoice = {
|
|
88
|
-
/** The kit's program on a percussion voice, the instrument's own otherwise. */
|
|
89
|
-
program: number;
|
|
90
|
-
/** The GM catalogue name for `program`. */
|
|
91
|
-
name: string;
|
|
92
|
-
isPercussion: boolean;
|
|
93
|
-
};
|
|
94
56
|
/** One playback-ready note, in score ticks, carrying the ids playback reports back. */
|
|
95
57
|
export type PlaybackNote = {
|
|
96
58
|
tick: number;
|
|
@@ -135,6 +97,15 @@ export type PerformanceTimeline = {
|
|
|
135
97
|
segments: readonly TimelineSegment[];
|
|
136
98
|
durationTicks: number;
|
|
137
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* The engine contract — `PlaybackEngine`, `PlaybackObserver` and
|
|
102
|
+
* `AuditionVoice` — lives in `@sudobility/music_player`, which is the only
|
|
103
|
+
* thing that implements it.
|
|
104
|
+
*
|
|
105
|
+
* The *plan* stays here, and must: `PlaybackPlan` composes `PerformanceTimeline`,
|
|
106
|
+
* which `performanceTimeline()` in `domain/score/` produces. Moving it would
|
|
107
|
+
* make this package import from music_player.
|
|
108
|
+
*/
|
|
138
109
|
export type PlaybackPlan = {
|
|
139
110
|
tracks: readonly PlaybackTrack[];
|
|
140
111
|
notes: readonly PlaybackNote[];
|
|
@@ -156,56 +127,4 @@ export type PlaybackLoadState = {
|
|
|
156
127
|
status: "failed";
|
|
157
128
|
message: string;
|
|
158
129
|
};
|
|
159
|
-
export interface PlaybackEngine {
|
|
160
|
-
initialize(): Promise<void>;
|
|
161
|
-
/** Adopts a plan. The engine is handed music, never a score. */
|
|
162
|
-
load(plan: PlaybackPlan): Promise<void>;
|
|
163
|
-
play(fromTick?: number): Promise<void>;
|
|
164
|
-
pause(): void;
|
|
165
|
-
stop(): void;
|
|
166
|
-
seek(tick: number): void;
|
|
167
|
-
setTempoMultiplier(multiplier: number): void;
|
|
168
|
-
setLoop(range: ScoreRange | null): void;
|
|
169
|
-
setTrackMute(trackId: string, muted: boolean): void;
|
|
170
|
-
setTrackSolo(trackId: string, solo: boolean): void;
|
|
171
|
-
/**
|
|
172
|
-
* Re-reads every track's volume, pan, mute and solo and pushes them,
|
|
173
|
-
* touching nothing that is scheduled.
|
|
174
|
-
*
|
|
175
|
-
* The mixing counterpart to `load`. Mute and solo had setters; volume and pan
|
|
176
|
-
* did not, and a track's volume was only ever read at load time — so once a
|
|
177
|
-
* mix change stopped reloading the score (the playback edit lock, see
|
|
178
|
-
* `music_lib`'s `score-slice`), moving a fader during playback moved the
|
|
179
|
-
* fader and not the sound.
|
|
180
|
-
*
|
|
181
|
-
* Takes only the tracks, so changing a gain does not rebuild every note —
|
|
182
|
-
* which is the whole reason this is separate from `load`. Idempotent, and
|
|
183
|
-
* takes them all rather than one property: the caller says "the mix changed,
|
|
184
|
-
* here it is" and does not work out which property it was.
|
|
185
|
-
*/
|
|
186
|
-
applyMix(tracks: readonly PlaybackTrack[]): void;
|
|
187
|
-
/** Toggles the metronome click. */
|
|
188
|
-
setMetronome(enabled: boolean): void;
|
|
189
|
-
/** Sets overall output level, 0-1 linear gain. */
|
|
190
|
-
setMasterVolume(volume: number): void;
|
|
191
|
-
/**
|
|
192
|
-
* Sounds `midi` immediately on `program`'s voice and holds it, independent of
|
|
193
|
-
* the transport — for auditioning a key while editing.
|
|
194
|
-
*
|
|
195
|
-
* `voice.isPercussion` mirrors what playback does with a percussion-clef
|
|
196
|
-
* track: without it, tapping a note on a drum track auditioned a pitched
|
|
197
|
-
* instrument while the same note played back as a drum.
|
|
198
|
-
*
|
|
199
|
-
* Separate from `play` because the two answer different questions: `play`
|
|
200
|
-
* renders the written score along a timeline, this makes a sound *now*, for
|
|
201
|
-
* as long as the caller holds it, whether or not a score is even loaded.
|
|
202
|
-
* Implementations must not disturb transport state.
|
|
203
|
-
*/
|
|
204
|
-
noteOn(midi: number, voice: AuditionVoice): void;
|
|
205
|
-
/** Releases a pitch started by `noteOn`. Silent no-op if it is not sounding. */
|
|
206
|
-
noteOff(midi: number): void;
|
|
207
|
-
/** Registers (or, with `null`, clears) the single observer receiving position/active-note/state updates. */
|
|
208
|
-
setObserver(observer: PlaybackObserver | null): void;
|
|
209
|
-
dispose(): void;
|
|
210
|
-
}
|
|
211
130
|
//# sourceMappingURL=playback.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/platform/playback.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/platform/playback.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAGF,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/D;;;;;;;GAOG;AACH,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,KAAK,EAAE,eAAe,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/position/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/position/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that knows where playback is.
|
|
3
|
+
*
|
|
4
|
+
* **The first stateful singleton service in music_types, and deliberately so.**
|
|
5
|
+
* This package is otherwise model and primitives. The playhead earns the
|
|
6
|
+
* exception because it has exactly one writer — `@sudobility/music_player` —
|
|
7
|
+
* and readers in every other package: the caret, the note highlighting and the
|
|
8
|
+
* piano keyboard. Any other home creates a dependency edge that exists only to
|
|
9
|
+
* reach it. It still obeys the four rules this package keeps: it works on both
|
|
10
|
+
* the frontend and the backend, adds no dependency, contains no hooks and
|
|
11
|
+
* contains no async code.
|
|
12
|
+
*
|
|
13
|
+
* Implements `IMusicPosition` — see that interface for why this exists at all.
|
|
14
|
+
* The short version: the caret, the note highlighting and the piano keyboard
|
|
15
|
+
* used to derive the playhead three different ways and drifted apart under
|
|
16
|
+
* load. Now they read one number.
|
|
17
|
+
*
|
|
18
|
+
* **The smoothing lives here, not in the caret.** That is the load-bearing
|
|
19
|
+
* decision. The engine reports position about thirty times a second, and those
|
|
20
|
+
* reports arrive in clumps because they come off the audio scheduler's
|
|
21
|
+
* lookahead loop rather than a wall clock — driving anything straight off them
|
|
22
|
+
* leaves it stalled on most frames and jumping when it does move. So the
|
|
23
|
+
* playhead is dead-reckoned forward from the last report, and because that
|
|
24
|
+
* happens *inside the single source of truth*, every consumer that asks gets
|
|
25
|
+
* the same smoothed answer at the same instant. When the caret did its own
|
|
26
|
+
* dead-reckoning, it was smoothing a number nobody else was smoothing.
|
|
27
|
+
*
|
|
28
|
+
* The anchor is the engine's own clock reading, not `performance.now()` at the
|
|
29
|
+
* moment the report was handled. Anchoring on receipt folds event-loop latency
|
|
30
|
+
* into the playhead: under load the anchor is stamped late and everything
|
|
31
|
+
* derived from it lags the audio, which is exactly the drift this replaces.
|
|
32
|
+
*/
|
|
33
|
+
import type { IMusicPositionSource, UnsubscribePosition } from "../model/position.js";
|
|
34
|
+
export declare class MusicPosition implements IMusicPositionSource {
|
|
35
|
+
private readonly listeners;
|
|
36
|
+
/** The last authoritative report, and the clock reading it belongs to. */
|
|
37
|
+
private anchorTick;
|
|
38
|
+
private anchorSeconds;
|
|
39
|
+
private playing;
|
|
40
|
+
private ticksPerSecond;
|
|
41
|
+
get isPlaying(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The playhead now.
|
|
44
|
+
*
|
|
45
|
+
* While stopped this is exactly the last reported tick — a paused caret must
|
|
46
|
+
* not creep. While playing it is the last report projected forward by the
|
|
47
|
+
* time since it was taken, which is what makes motion even however unevenly
|
|
48
|
+
* the reports land.
|
|
49
|
+
*/
|
|
50
|
+
get tick(): number;
|
|
51
|
+
/**
|
|
52
|
+
* The last vouched-for position: the last report, or the position banked
|
|
53
|
+
* when the transport last changed state. `tick` projects from exactly this,
|
|
54
|
+
* so the two cannot describe different moments.
|
|
55
|
+
*/
|
|
56
|
+
get reportedTick(): number;
|
|
57
|
+
report(tick: number, atSeconds?: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Update the tick rate without disturbing the anchor.
|
|
60
|
+
*
|
|
61
|
+
* Deliberately not folded into `report`: re-anchoring is `report`'s job and
|
|
62
|
+
* a rate change must not do it, or a tempo change mid-bar would restart the
|
|
63
|
+
* projection from wherever the last report left off.
|
|
64
|
+
*/
|
|
65
|
+
setRate(ticksPerSecond: number): void;
|
|
66
|
+
setPlaying(playing: boolean, ticksPerSecond?: number): void;
|
|
67
|
+
subscribe(listener: (tick: number) => void): UnsubscribePosition;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=music-position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"music-position.d.ts","sourceRoot":"","sources":["../../src/position/music-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AA8B9B,qBAAa,aAAc,YAAW,oBAAoB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAE/D,0EAA0E;IAC1E,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAgB;IAErC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAK;IAE3B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,MAAM,CAcjB;IAED;;;;OAIG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAM9C;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAIrC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAY3D,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,mBAAmB;CAIjE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far the playhead may be projected past its last report.
|
|
3
|
+
*
|
|
4
|
+
* Dead reckoning is an interpolation between reports, not a substitute for
|
|
5
|
+
* them. Reports arrive about thirty times a second and in clumps, so the bound
|
|
6
|
+
* has to absorb a clump — but past that, continuing to advance is asserting a
|
|
7
|
+
* position nothing has corroborated.
|
|
8
|
+
*
|
|
9
|
+
* That distinction is not academic: when the engine's own report throttle
|
|
10
|
+
* silenced it, this projected on regardless and the caret glided the length of
|
|
11
|
+
* the score while every consumer of the *reported* tick — the scroll, the
|
|
12
|
+
* bar/beat readout, the scrubber — sat at bar one. One writer, but two
|
|
13
|
+
* behaviours, and they disagreed by the whole piece. Bounded, a stalled
|
|
14
|
+
* producer stops the playhead everywhere at once, which reads as the one fault
|
|
15
|
+
* it is instead of as a caret that works and a page that does not.
|
|
16
|
+
*
|
|
17
|
+
* Half a second is roughly fifteen missed reports: far beyond any clump, far
|
|
18
|
+
* short of anything a reader would call motion.
|
|
19
|
+
*/
|
|
20
|
+
const MAX_PROJECTION_SECONDS = 0.5;
|
|
21
|
+
/** Wall-clock seconds, monotonic where the platform offers it. */
|
|
22
|
+
function nowSeconds() {
|
|
23
|
+
return typeof performance !== "undefined"
|
|
24
|
+
? performance.now() / 1000
|
|
25
|
+
: Date.now() / 1000;
|
|
26
|
+
}
|
|
27
|
+
export class MusicPosition {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.listeners = new Set();
|
|
30
|
+
/** The last authoritative report, and the clock reading it belongs to. */
|
|
31
|
+
this.anchorTick = 0;
|
|
32
|
+
this.anchorSeconds = nowSeconds();
|
|
33
|
+
this.playing = false;
|
|
34
|
+
this.ticksPerSecond = 0;
|
|
35
|
+
}
|
|
36
|
+
get isPlaying() {
|
|
37
|
+
return this.playing;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The playhead now.
|
|
41
|
+
*
|
|
42
|
+
* While stopped this is exactly the last reported tick — a paused caret must
|
|
43
|
+
* not creep. While playing it is the last report projected forward by the
|
|
44
|
+
* time since it was taken, which is what makes motion even however unevenly
|
|
45
|
+
* the reports land.
|
|
46
|
+
*/
|
|
47
|
+
get tick() {
|
|
48
|
+
if (!this.playing || this.ticksPerSecond <= 0)
|
|
49
|
+
return this.anchorTick;
|
|
50
|
+
// Capped: see `MAX_PROJECTION_SECONDS`. Past the bound the playhead holds
|
|
51
|
+
// its last corroborated position rather than inventing motion.
|
|
52
|
+
const elapsed = Math.min(nowSeconds() - this.anchorSeconds, MAX_PROJECTION_SECONDS);
|
|
53
|
+
// Never backwards: a report that arrives late would otherwise pull the
|
|
54
|
+
// playhead back a few ticks, which reads as a stutter.
|
|
55
|
+
return Math.max(this.anchorTick, this.anchorTick + elapsed * this.ticksPerSecond);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The last vouched-for position: the last report, or the position banked
|
|
59
|
+
* when the transport last changed state. `tick` projects from exactly this,
|
|
60
|
+
* so the two cannot describe different moments.
|
|
61
|
+
*/
|
|
62
|
+
get reportedTick() {
|
|
63
|
+
return this.anchorTick;
|
|
64
|
+
}
|
|
65
|
+
report(tick, atSeconds) {
|
|
66
|
+
this.anchorTick = tick;
|
|
67
|
+
this.anchorSeconds = atSeconds ?? nowSeconds();
|
|
68
|
+
for (const listener of this.listeners)
|
|
69
|
+
listener(tick);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Update the tick rate without disturbing the anchor.
|
|
73
|
+
*
|
|
74
|
+
* Deliberately not folded into `report`: re-anchoring is `report`'s job and
|
|
75
|
+
* a rate change must not do it, or a tempo change mid-bar would restart the
|
|
76
|
+
* projection from wherever the last report left off.
|
|
77
|
+
*/
|
|
78
|
+
setRate(ticksPerSecond) {
|
|
79
|
+
this.ticksPerSecond = Math.max(0, ticksPerSecond);
|
|
80
|
+
}
|
|
81
|
+
setPlaying(playing, ticksPerSecond) {
|
|
82
|
+
// Re-anchor on the transition, or the first `tick` read after resuming
|
|
83
|
+
// would project forward from however long the transport sat paused.
|
|
84
|
+
if (playing !== this.playing) {
|
|
85
|
+
this.anchorTick = this.tick;
|
|
86
|
+
this.anchorSeconds = nowSeconds();
|
|
87
|
+
}
|
|
88
|
+
this.playing = playing;
|
|
89
|
+
if (ticksPerSecond !== undefined)
|
|
90
|
+
this.ticksPerSecond = ticksPerSecond;
|
|
91
|
+
for (const listener of this.listeners)
|
|
92
|
+
listener(this.anchorTick);
|
|
93
|
+
}
|
|
94
|
+
subscribe(listener) {
|
|
95
|
+
this.listeners.add(listener);
|
|
96
|
+
return () => this.listeners.delete(listener);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=music-position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"music-position.js","sourceRoot":"","sources":["../../src/position/music-position.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,kEAAkE;AAClE,SAAS,UAAU;IACjB,OAAO,OAAO,WAAW,KAAK,WAAW;QACvC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI;QAC1B,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,OAAO,aAAa;IAA1B;QACmB,cAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;QAE/D,0EAA0E;QAClE,eAAU,GAAG,CAAC,CAAC;QACf,kBAAa,GAAG,UAAU,EAAE,CAAC;QAE7B,YAAO,GAAG,KAAK,CAAC;QAChB,mBAAc,GAAG,CAAC,CAAC;IAwE7B,CAAC;IAtEC,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,IAAI;QACN,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACtE,0EAA0E;QAC1E,+DAA+D;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,UAAU,EAAE,GAAG,IAAI,CAAC,aAAa,EACjC,sBAAsB,CACvB,CAAC;QACF,uEAAuE;QACvE,uDAAuD;QACvD,OAAO,IAAI,CAAC,GAAG,CACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,cAAc,CAChD,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,SAAkB;QACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;QAC/C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,cAAsB;QAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,OAAgB,EAAE,cAAuB;QAClD,uEAAuE;QACvE,oEAAoE;QACpE,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,aAAa,GAAG,UAAU,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,cAAc,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACvE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,SAAS,CAAC,QAAgC;QACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The music-position singleton.
|
|
3
|
+
*
|
|
4
|
+
* Same shape as the rest of the family's services (see `@sudobility/di`'s
|
|
5
|
+
* storage and network singletons): initialise once at start-up, read it
|
|
6
|
+
* everywhere, reset it in tests.
|
|
7
|
+
*
|
|
8
|
+
* A singleton because the playhead *is* global to a running transport — there
|
|
9
|
+
* is one piece of music playing, and the whole point of this type is that
|
|
10
|
+
* everything following it reads the same number. Two instances would
|
|
11
|
+
* reintroduce exactly the disagreement it exists to prevent.
|
|
12
|
+
*/
|
|
13
|
+
import type { IMusicPosition, IMusicPositionSource } from '../model/position.js';
|
|
14
|
+
/**
|
|
15
|
+
* Creates the singleton if it does not exist.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent, so a second call from a re-mounting composition root does not
|
|
18
|
+
* silently swap the playhead out from under everything subscribed to it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function initializeMusicPosition(override?: IMusicPositionSource): IMusicPositionSource;
|
|
21
|
+
/**
|
|
22
|
+
* The writable playhead, for whatever is driving the transport.
|
|
23
|
+
*
|
|
24
|
+
* Auto-initialises rather than throwing: unlike a storage service there is no
|
|
25
|
+
* configuration to get wrong, and a playhead that refuses to exist until
|
|
26
|
+
* somebody remembers a start-up call is a worse failure than one that starts
|
|
27
|
+
* at zero.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getMusicPositionSource(): IMusicPositionSource;
|
|
30
|
+
/** The read-only playhead, for anything that follows the music. */
|
|
31
|
+
export declare function getMusicPosition(): IMusicPosition;
|
|
32
|
+
/** Drops the singleton. Tests only — a suite must not inherit the last one's playhead. */
|
|
33
|
+
export declare function resetMusicPosition(): void;
|
|
34
|
+
//# sourceMappingURL=singleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../src/position/singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAK9B;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,oBAAoB,CAGtB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,oBAAoB,CAE7D;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,cAAc,CAEjD;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { MusicPosition } from './music-position.js';
|
|
2
|
+
let instance = null;
|
|
3
|
+
/**
|
|
4
|
+
* Creates the singleton if it does not exist.
|
|
5
|
+
*
|
|
6
|
+
* Idempotent, so a second call from a re-mounting composition root does not
|
|
7
|
+
* silently swap the playhead out from under everything subscribed to it.
|
|
8
|
+
*/
|
|
9
|
+
export function initializeMusicPosition(override) {
|
|
10
|
+
if (!instance)
|
|
11
|
+
instance = override ?? new MusicPosition();
|
|
12
|
+
return instance;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The writable playhead, for whatever is driving the transport.
|
|
16
|
+
*
|
|
17
|
+
* Auto-initialises rather than throwing: unlike a storage service there is no
|
|
18
|
+
* configuration to get wrong, and a playhead that refuses to exist until
|
|
19
|
+
* somebody remembers a start-up call is a worse failure than one that starts
|
|
20
|
+
* at zero.
|
|
21
|
+
*/
|
|
22
|
+
export function getMusicPositionSource() {
|
|
23
|
+
return initializeMusicPosition();
|
|
24
|
+
}
|
|
25
|
+
/** The read-only playhead, for anything that follows the music. */
|
|
26
|
+
export function getMusicPosition() {
|
|
27
|
+
return initializeMusicPosition();
|
|
28
|
+
}
|
|
29
|
+
/** Drops the singleton. Tests only — a suite must not inherit the last one's playhead. */
|
|
30
|
+
export function resetMusicPosition() {
|
|
31
|
+
instance = null;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=singleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../src/position/singleton.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,IAAI,QAAQ,GAAgC,IAAI,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAA+B;IAE/B,IAAI,CAAC,QAAQ;QAAE,QAAQ,GAAG,QAAQ,IAAI,IAAI,aAAa,EAAE,CAAC;IAC1D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,gBAAgB;IAC9B,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB;IAChC,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED