@sudobility/music_types 0.13.3 → 0.13.5
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 +4 -0
- package/dist/bytes/base64.js +6 -6
- package/dist/domain/generation/replacement-region.d.ts +10 -0
- package/dist/domain/generation/replacement-region.d.ts.map +1 -1
- package/dist/domain/generation/replacement-region.js +22 -0
- package/dist/domain/generation/replacement-region.js.map +1 -1
- package/dist/domain/instruments/midi-protocol.d.ts +24 -0
- package/dist/domain/instruments/midi-protocol.d.ts.map +1 -0
- package/dist/domain/instruments/midi-protocol.js +24 -0
- package/dist/domain/instruments/midi-protocol.js.map +1 -0
- package/dist/domain/instruments/track-instrument.d.ts +17 -1
- package/dist/domain/instruments/track-instrument.d.ts.map +1 -1
- package/dist/domain/instruments/track-instrument.js +37 -0
- package/dist/domain/instruments/track-instrument.js.map +1 -1
- package/dist/domain/notation/display-lens.d.ts +32 -0
- package/dist/domain/notation/display-lens.d.ts.map +1 -0
- package/dist/domain/notation/display-lens.js +41 -0
- package/dist/domain/notation/display-lens.js.map +1 -0
- package/dist/domain/score/defaults.d.ts +21 -0
- package/dist/domain/score/defaults.d.ts.map +1 -0
- package/dist/domain/score/defaults.js +9 -0
- package/dist/domain/score/defaults.js.map +1 -0
- package/dist/domain/score/factory.d.ts.map +1 -1
- package/dist/domain/score/factory.js +2 -7
- package/dist/domain/score/factory.js.map +1 -1
- package/dist/domain/score/queries.d.ts +46 -0
- package/dist/domain/score/queries.d.ts.map +1 -1
- package/dist/domain/score/queries.js +94 -0
- package/dist/domain/score/queries.js.map +1 -1
- package/dist/domain/selection/clipboard-prompts.d.ts +34 -0
- package/dist/domain/selection/clipboard-prompts.d.ts.map +1 -0
- package/dist/domain/selection/clipboard-prompts.js +74 -0
- package/dist/domain/selection/clipboard-prompts.js.map +1 -0
- package/dist/domain/time/tempo-map.d.ts.map +1 -1
- package/dist/domain/time/tempo-map.js +1 -1
- package/dist/domain/time/tempo-map.js.map +1 -1
- package/dist/domain/time/tuplets.d.ts +3 -0
- package/dist/domain/time/tuplets.d.ts.map +1 -1
- package/dist/domain/time/tuplets.js +2 -2
- package/dist/domain/time/tuplets.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/model/generation.d.ts +335 -0
- package/dist/model/generation.d.ts.map +1 -1
- package/dist/model/generation.js +7 -0
- package/dist/model/generation.js.map +1 -1
- package/dist/model/score.d.ts +32 -14
- package/dist/model/score.d.ts.map +1 -1
- package/dist/model/score.js +104 -1
- package/dist/model/score.js.map +1 -1
- package/dist/platform/playback.d.ts.map +1 -1
- package/dist/position/singleton.d.ts +1 -1
- package/dist/position/singleton.js +1 -1
- package/dist/services/regeneration/controller.d.ts.map +1 -1
- package/dist/services/regeneration/controller.js +33 -0
- package/dist/services/regeneration/controller.js.map +1 -1
- package/dist/test/fixtures.d.ts +27 -1
- package/dist/test/fixtures.d.ts.map +1 -1
- package/dist/test/fixtures.js +25 -6
- package/dist/test/fixtures.js.map +1 -1
- package/package.json +6 -1
package/CLAUDE.md
CHANGED
|
@@ -39,6 +39,10 @@ Everything exports from a single sectioned `src/index.ts`:
|
|
|
39
39
|
|
|
40
40
|
## Gotchas
|
|
41
41
|
|
|
42
|
+
- **A regeneration request says who is playing, and a kit gets told how a kit is written.** A `ScoreFragment` is measures and nothing else — no name, no clef, no program — so "Replace Track" used to hand the model anonymous bars and let it infer the instrument from the notes in front of it. On a drum track there is nothing to infer from: the pitches are drum numbers, not notes. Measured on a real Power Kit regeneration, the result was the kick on every eighth of all 118 bars at a constant velocity 100, the snare on all four beats instead of the backbeat, and five of the 47 drums used — a metronome, not a groove. `RegenerateRegionRequest.tracks` now carries a `GenerateScoreRequestTrack` per fragment track, built by `describeTrackForGeneration` in music_types so whole-score generation and regeneration describe a track the *same* way; the range and polyphony come from `trackKeyboardRange`/`trackMaxPolyphony`, which answer about the **kit** on a percussion track rather than about whatever melodic program shares its number. The roster is matched to the fragment **by position**, so `buildRegeneratePrompt` emits it only when the lengths agree — a roster of a different length is not partial information but wrong information, naming the kit as the cello. And `percussionRules()` — previously generate-only, and previously just the GM map — now travels on both paths and states the two Expression rules that **invert** for percussion: an accent is the rule rather than the exception (velocity variation between accented and ghost notes *is* the groove), and a kit does play continuously even though each individual drum still rests. The map alone is not enough, which is the thing that had to be measured to be believed.
|
|
43
|
+
|
|
44
|
+
- **One fact, one declaration — and `src/__single-source.test.ts` enforces it.** A constant restated in a second package agrees with the first right up until one of them is edited, and nothing fails when they part: the build is clean, the types match, and the only symptom is a wrong sound or a picker quietly missing an entry. Measured across the family, 23 UPPER_CASE constants were declared in more than one repo — `CC_VOLUME` three times, `DYNAMICS` four, `C_MAJOR` five, and `DEFAULT_TIME_SIGNATURE` in four places under two names. The guard reads the list of names **from music_types at runtime** rather than restating it, because a check against duplication that duplicates what it checks would drift like everything else; its `ALLOWED` list is empty on purpose, so an exemption is a decision somebody writes down. Two shapes matter beyond the constants themselves. **A closed vocabulary is declared as an array and the type read off it** (`export const DYNAMICS = [...] as const; export type Dynamic = (typeof DYNAMICS)[number];`) — a TypeScript union has no runtime form, so anything that must *validate* a value has to write the list out again, which is exactly how music_api's decoder came to check generated music against its own private copy. **A label or option list keyed by the vocabulary is a `Record<T, ...>`, never a parallel array** — a record fails to compile when a member is added, an array silently goes on offering the old set; that is why the inspector's picker lists are `ACCIDENTAL_OPTIONS`/`ARTICULATION_OPTIONS` built from the vocabulary rather than `ACCIDENTALS`/`ARTICULATIONS` retyped. Test fixtures follow the same rule: the score fixtures live once, in `@sudobility/music_types/test`, and a package that needs a rendering fixture of its own re-exports them and adds to them.
|
|
45
|
+
|
|
42
46
|
- **The playhead is the one stateful service in this package, and that is a
|
|
43
47
|
deliberate precedent.** `MusicPosition` and its singleton live in
|
|
44
48
|
`src/position/`. Everything else here is model and primitives; the playhead
|
package/dist/bytes/base64.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* no JIT. The obvious implementations of each were measured at 77ms and 580ms
|
|
26
26
|
* for those sizes on a laptop; these are 9ms and 303ms.
|
|
27
27
|
*/
|
|
28
|
-
const ALPHABET =
|
|
28
|
+
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
29
29
|
/**
|
|
30
30
|
* Character code to sextet, -1 for anything else.
|
|
31
31
|
*
|
|
@@ -48,7 +48,7 @@ const ENCODE_CHUNK_CHARS = 8192;
|
|
|
48
48
|
/** Bytes to base64, padded. */
|
|
49
49
|
export function bytesToBase64(bytes) {
|
|
50
50
|
const chunks = [];
|
|
51
|
-
let piece =
|
|
51
|
+
let piece = "";
|
|
52
52
|
for (let i = 0; i < bytes.length; i += 3) {
|
|
53
53
|
const a = bytes[i];
|
|
54
54
|
const b = bytes[i + 1];
|
|
@@ -56,16 +56,16 @@ export function bytesToBase64(bytes) {
|
|
|
56
56
|
piece +=
|
|
57
57
|
ALPHABET[a >> 2] +
|
|
58
58
|
ALPHABET[((a & 0x03) << 4) | ((b ?? 0) >> 4)] +
|
|
59
|
-
(b === undefined ?
|
|
60
|
-
(c === undefined ?
|
|
59
|
+
(b === undefined ? "=" : ALPHABET[((b & 0x0f) << 2) | ((c ?? 0) >> 6)]) +
|
|
60
|
+
(c === undefined ? "=" : ALPHABET[c & 0x3f]);
|
|
61
61
|
if (piece.length >= ENCODE_CHUNK_CHARS) {
|
|
62
62
|
chunks.push(piece);
|
|
63
|
-
piece =
|
|
63
|
+
piece = "";
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
if (piece)
|
|
67
67
|
chunks.push(piece);
|
|
68
|
-
return chunks.join(
|
|
68
|
+
return chunks.join("");
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* Base64 to bytes. Anything outside the alphabet — padding, newlines a data URI
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* discovered afterwards.
|
|
15
15
|
*/
|
|
16
16
|
import type { Score, ScoreRange, ScoreSelection } from "../../index.js";
|
|
17
|
+
import type { GenerateScoreRequest } from "../../index.js";
|
|
17
18
|
export type ReplaceScope = "notes" | "measures" | "track";
|
|
18
19
|
export type ReplacementRegion = {
|
|
19
20
|
range: ScoreRange;
|
|
@@ -29,4 +30,13 @@ export type ReplacementRegion = {
|
|
|
29
30
|
* nothing to work on — which is what disables its button.
|
|
30
31
|
*/
|
|
31
32
|
export declare function replacementRegion(score: Score, selection: ScoreSelection, activeTrackId: string | null, scope: ReplaceScope): ReplacementRegion | null;
|
|
33
|
+
/**
|
|
34
|
+
* The placeholder score a generation request implies.
|
|
35
|
+
*
|
|
36
|
+
* Created up front rather than on completion so a generating project appears
|
|
37
|
+
* in the list with its badge from the first second, instead of materialising
|
|
38
|
+
* minutes later out of nowhere — and shaped like what was asked for, so the
|
|
39
|
+
* editor can open it meaningfully mid-generation.
|
|
40
|
+
*/
|
|
41
|
+
export declare function emptyScoreForRequest(request: GenerateScoreRequest): Score;
|
|
32
42
|
//# sourceMappingURL=replacement-region.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replacement-region.d.ts","sourceRoot":"","sources":["../../../src/domain/generation/replacement-region.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"replacement-region.d.ts","sourceRoot":"","sources":["../../../src/domain/generation/replacement-region.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAI3D,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAC;IACxB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAoCF;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,cAAc,EACzB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,KAAK,EAAE,YAAY,GAClB,iBAAiB,GAAG,IAAI,CAkE1B;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,KAAK,CAYzE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createEmptyScore } from "../score/factory.js";
|
|
1
2
|
import { isNoteEvent } from "../../index.js";
|
|
2
3
|
import { findEvent, findMeasure, findTrack } from "../score/queries.js";
|
|
3
4
|
/** Ids of every note overlapping `range` on its tracks. Overlap, not containment: a note straddling the boundary is replaced too. */
|
|
@@ -76,4 +77,25 @@ export function replacementRegion(score, selection, activeTrackId, scope) {
|
|
|
76
77
|
trackIds: [...new Set(notes.map((n) => n.trackId))],
|
|
77
78
|
}, false, new Set(notes.map((n) => n.id)));
|
|
78
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* The placeholder score a generation request implies.
|
|
82
|
+
*
|
|
83
|
+
* Created up front rather than on completion so a generating project appears
|
|
84
|
+
* in the list with its badge from the first second, instead of materialising
|
|
85
|
+
* minutes later out of nowhere — and shaped like what was asked for, so the
|
|
86
|
+
* editor can open it meaningfully mid-generation.
|
|
87
|
+
*/
|
|
88
|
+
export function emptyScoreForRequest(request) {
|
|
89
|
+
return createEmptyScore({
|
|
90
|
+
title: request.title?.trim() || "Untitled",
|
|
91
|
+
measures: request.durationMeasures,
|
|
92
|
+
tracks: request.tracks.map((t) => ({
|
|
93
|
+
name: t.name,
|
|
94
|
+
instrumentName: t.instrumentName,
|
|
95
|
+
clef: t.clef,
|
|
96
|
+
})),
|
|
97
|
+
...(request.timeSignature ? { timeSignature: request.timeSignature } : {}),
|
|
98
|
+
...(request.keySignature ? { keySignature: request.keySignature } : {}),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
79
101
|
//# sourceMappingURL=replacement-region.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replacement-region.js","sourceRoot":"","sources":["../../../src/domain/generation/replacement-region.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"replacement-region.js","sourceRoot":"","sources":["../../../src/domain/generation/replacement-region.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAcxE,qIAAqI;AACrI,SAAS,cAAc,CAAC,KAAY,EAAE,KAAiB;IACrD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ;YAClC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM;gBAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM;oBAC9B,IACE,WAAW,CAAC,KAAK,CAAC;wBAClB,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO;wBAC/B,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,SAAS;wBAEvD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CACjB,KAAY,EACZ,KAAiB,EACjB,cAAuB,EACvB,WAAwB;IAExB,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC7C,OAAO;QACL,KAAK;QACL,cAAc;QACd,SAAS,EAAE,OAAO,CAAC,MAAM;QACzB,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;KACzE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAY,EACZ,SAAyB,EACzB,aAA4B,EAC5B,KAAmB;IAEnB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,yEAAyE;QACzE,qEAAqE;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,UAAU,CACf,KAAK,EACL;YACE,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa;YAC5C,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;SACrB,EACD,IAAI,EACJ,IAAI,GAAG,EAAE,CACV,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU;aAClC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,4EAA4E;QAC5E,yDAAyD;QACzD,MAAM,QAAQ,GAAG;YACf,GAAG,IAAI,GAAG,CACR,SAAS,CAAC,UAAU;iBACjB,GAAG,CACF,CAAC,EAAE,EAAE,EAAE,CACL,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACpE;iBACA,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CACpC;SACF,CAAC;QACF,OAAO,UAAU,CACf,KAAK,EACL;YACE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACxD,OAAO,EAAE,IAAI,CAAC,GAAG,CACf,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,aAAa,CAAC,CACtD;YACD,QAAQ;SACT,EACD,IAAI,EACJ,IAAI,GAAG,EAAE,CACV,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ;SAC7B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,OAAO,UAAU,CACf,KAAK,EACL;QACE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC;QACrE,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;KACpD,EACD,KAAK,EACL,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAChC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA6B;IAChE,OAAO,gBAAgB,CAAC;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,UAAU;QAC1C,QAAQ,EAAE,OAAO,CAAC,gBAAgB;QAClC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,cAAc,EAAE,CAAC,CAAC,cAAc;YAChC,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC,CAAC;QACH,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The General MIDI numbers that are the protocol itself, not our choices.
|
|
3
|
+
*
|
|
4
|
+
* A controller number and a reserved channel are facts about MIDI: the file
|
|
5
|
+
* writer and the synth host have to agree about them or a track exported at
|
|
6
|
+
* half volume comes back panned. They agreed by coincidence — each declared
|
|
7
|
+
* its own `CC_VOLUME = 7` — which is exactly the shape of duplication that
|
|
8
|
+
* only shows up as a wrong sound rather than as a failing build.
|
|
9
|
+
*
|
|
10
|
+
* `MIDI_CHANNEL_COUNT` sits here for the same reason it caused a bug: a
|
|
11
|
+
* second drum track was allocated channel 25 while fluidsynth had been given
|
|
12
|
+
* 16, so the track existed, drew, and made no sound.
|
|
13
|
+
*/
|
|
14
|
+
/** Channel volume (coarse). */
|
|
15
|
+
export declare const CC_VOLUME = 7;
|
|
16
|
+
/** Channel pan (coarse), 0 hard left, 64 centre, 127 hard right. */
|
|
17
|
+
export declare const CC_PAN = 10;
|
|
18
|
+
/** Channel 10 in the spec's 1-based numbering; the one channel reserved for drums. */
|
|
19
|
+
export declare const PERCUSSION_CHANNEL = 9;
|
|
20
|
+
/** Channels per MIDI port. Anything above this must open another synth instance. */
|
|
21
|
+
export declare const MIDI_CHANNELS_PER_PORT = 16;
|
|
22
|
+
/** The bank General MIDI keeps its drum kits in. */
|
|
23
|
+
export declare const DRUM_BANK = 128;
|
|
24
|
+
//# sourceMappingURL=midi-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midi-protocol.d.ts","sourceRoot":"","sources":["../../../src/domain/instruments/midi-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+BAA+B;AAC/B,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B,oEAAoE;AACpE,eAAO,MAAM,MAAM,KAAK,CAAC;AAEzB,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,oDAAoD;AACpD,eAAO,MAAM,SAAS,MAAM,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The General MIDI numbers that are the protocol itself, not our choices.
|
|
3
|
+
*
|
|
4
|
+
* A controller number and a reserved channel are facts about MIDI: the file
|
|
5
|
+
* writer and the synth host have to agree about them or a track exported at
|
|
6
|
+
* half volume comes back panned. They agreed by coincidence — each declared
|
|
7
|
+
* its own `CC_VOLUME = 7` — which is exactly the shape of duplication that
|
|
8
|
+
* only shows up as a wrong sound rather than as a failing build.
|
|
9
|
+
*
|
|
10
|
+
* `MIDI_CHANNEL_COUNT` sits here for the same reason it caused a bug: a
|
|
11
|
+
* second drum track was allocated channel 25 while fluidsynth had been given
|
|
12
|
+
* 16, so the track existed, drew, and made no sound.
|
|
13
|
+
*/
|
|
14
|
+
/** Channel volume (coarse). */
|
|
15
|
+
export const CC_VOLUME = 7;
|
|
16
|
+
/** Channel pan (coarse), 0 hard left, 64 centre, 127 hard right. */
|
|
17
|
+
export const CC_PAN = 10;
|
|
18
|
+
/** Channel 10 in the spec's 1-based numbering; the one channel reserved for drums. */
|
|
19
|
+
export const PERCUSSION_CHANNEL = 9;
|
|
20
|
+
/** Channels per MIDI port. Anything above this must open another synth instance. */
|
|
21
|
+
export const MIDI_CHANNELS_PER_PORT = 16;
|
|
22
|
+
/** The bank General MIDI keeps its drum kits in. */
|
|
23
|
+
export const DRUM_BANK = 128;
|
|
24
|
+
//# sourceMappingURL=midi-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midi-protocol.js","sourceRoot":"","sources":["../../../src/domain/instruments/midi-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+BAA+B;AAC/B,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAE3B,oEAAoE;AACpE,MAAM,CAAC,MAAM,MAAM,GAAG,EAAE,CAAC;AAEzB,sFAAsF;AACtF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC"}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* These wrappers are the single place that distinction is encoded. Call them
|
|
20
20
|
* instead of the program-keyed tables anywhere a `Track` is in hand.
|
|
21
21
|
*/
|
|
22
|
-
import type { Score, Track } from "../../index.js";
|
|
22
|
+
import type { GenerateScoreRequestTrack, Score, Track } from "../../index.js";
|
|
23
23
|
import { type MidiRange } from "./gm-range.js";
|
|
24
24
|
import type { InstrumentIconArt } from "./icon-art.js";
|
|
25
25
|
/** Whether `track`'s `midiProgram` addresses a drum kit rather than an instrument. */
|
|
@@ -77,4 +77,20 @@ export declare function trackInstrumentLabel(track: Pick<Track, "clef" | "midiPr
|
|
|
77
77
|
* on every load would also read as a change to the autosaver.
|
|
78
78
|
*/
|
|
79
79
|
export declare function scoreWithResolvedKits(score: Score): Score;
|
|
80
|
+
/**
|
|
81
|
+
* How a track is described to the generation model.
|
|
82
|
+
*
|
|
83
|
+
* One function for both paths, because the two used to disagree by omission:
|
|
84
|
+
* whole-score generation named each track's instrument, and regeneration named
|
|
85
|
+
* nothing at all — a `ScoreFragment` carries measures and no identity, so
|
|
86
|
+
* "Replace Track" handed the model anonymous bars and let it infer the
|
|
87
|
+
* instrument from the notes. On a kit there is nothing to infer from, since
|
|
88
|
+
* the pitches are drum numbers rather than notes, and the result was a part
|
|
89
|
+
* that treated the kick as a metronome.
|
|
90
|
+
*
|
|
91
|
+
* Range and polyphony come from the track's own program through
|
|
92
|
+
* `trackKeyboardRange`/`trackMaxPolyphony`, so a drum track answers about its
|
|
93
|
+
* kit rather than about whatever melodic instrument shares its program number.
|
|
94
|
+
*/
|
|
95
|
+
export declare function describeTrackForGeneration(track: Track): GenerateScoreRequestTrack;
|
|
80
96
|
//# sourceMappingURL=track-instrument.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-instrument.d.ts","sourceRoot":"","sources":["../../../src/domain/instruments/track-instrument.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"track-instrument.d.ts","sourceRoot":"","sources":["../../../src/domain/instruments/track-instrument.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EACV,yBAAyB,EACzB,KAAK,EACL,KAAK,EACN,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAMlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAErE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,SAAS,CAGX;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,MAAM,CAGR;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,MAAM,CAIR;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,iBAAiB,CAInB;AAED,sGAAsG;AACtG,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GACzC,MAAM,CAGR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAezD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,GACX,yBAAyB,CAqB3B"}
|
|
@@ -99,4 +99,41 @@ export function scoreWithResolvedKits(score) {
|
|
|
99
99
|
}),
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* How a track is described to the generation model.
|
|
104
|
+
*
|
|
105
|
+
* One function for both paths, because the two used to disagree by omission:
|
|
106
|
+
* whole-score generation named each track's instrument, and regeneration named
|
|
107
|
+
* nothing at all — a `ScoreFragment` carries measures and no identity, so
|
|
108
|
+
* "Replace Track" handed the model anonymous bars and let it infer the
|
|
109
|
+
* instrument from the notes. On a kit there is nothing to infer from, since
|
|
110
|
+
* the pitches are drum numbers rather than notes, and the result was a part
|
|
111
|
+
* that treated the kick as a metronome.
|
|
112
|
+
*
|
|
113
|
+
* Range and polyphony come from the track's own program through
|
|
114
|
+
* `trackKeyboardRange`/`trackMaxPolyphony`, so a drum track answers about its
|
|
115
|
+
* kit rather than about whatever melodic instrument shares its program number.
|
|
116
|
+
*/
|
|
117
|
+
export function describeTrackForGeneration(track) {
|
|
118
|
+
// `MidiRange` is {min,max} and the wire's `range` is
|
|
119
|
+
// {lowestMidi,highestMidi} — the same fact under two names, mapped here
|
|
120
|
+
// rather than left for each call site to get right.
|
|
121
|
+
const range = trackKeyboardRange(track);
|
|
122
|
+
const polyphony = trackMaxPolyphony(track);
|
|
123
|
+
return {
|
|
124
|
+
name: track.name,
|
|
125
|
+
// `trackInstrumentLabel`, not the stored `instrumentName`: on a drum
|
|
126
|
+
// track the two disagree, because program 16 names the Power kit there
|
|
127
|
+
// and a Drawbar Organ everywhere else. Telling the model it is writing
|
|
128
|
+
// for an organ while handing it the drum map is worse than saying
|
|
129
|
+
// nothing.
|
|
130
|
+
instrumentName: trackInstrumentLabel(track),
|
|
131
|
+
midiProgram: track.midiProgram,
|
|
132
|
+
clef: track.clef,
|
|
133
|
+
range: { lowestMidi: range.min, highestMidi: range.max },
|
|
134
|
+
// A keyboard's ceiling is `UNLIMITED_POLYPHONY` (Infinity), which is not a
|
|
135
|
+
// number the wire can carry; omitting it says the same thing.
|
|
136
|
+
...(Number.isFinite(polyphony) ? { maximumPolyphony: polyphony } : {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
102
139
|
//# sourceMappingURL=track-instrument.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-instrument.js","sourceRoot":"","sources":["../../../src/domain/instruments/track-instrument.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"track-instrument.js","sourceRoot":"","sources":["../../../src/domain/instruments/track-instrument.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undoing the display lenses, so what is stored is what will sound.
|
|
3
|
+
*
|
|
4
|
+
* Pure model work despite being reached from a pointer: it takes a pitch and
|
|
5
|
+
* answers a pitch, and knows nothing about coordinates. It lived beside the
|
|
6
|
+
* hit-testing in the app for that reason alone, which made it a rule a second
|
|
7
|
+
* app would have had to rediscover — and getting it wrong is invisible, since
|
|
8
|
+
* the note then draws exactly where it was clicked and only sounds wrong.
|
|
9
|
+
*/
|
|
10
|
+
import type { Pitch, Score, UUID } from "../../index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Turns a pitch read off the *drawn* staff into the pitch to store.
|
|
13
|
+
*
|
|
14
|
+
* `pitchAtStavePoint` answers in the coordinate space the notation is drawn
|
|
15
|
+
* in, and that space has been through up to two display lenses:
|
|
16
|
+
* `ottavaScore` moves bracketed noteheads to where they are written, and
|
|
17
|
+
* `writtenScore` transposes a transposing instrument into its written key.
|
|
18
|
+
* The model stores **sounding** pitch, so writing a clicked position straight
|
|
19
|
+
* back in stores whatever was on screen as though it were the sound.
|
|
20
|
+
*
|
|
21
|
+
* That was silently wrong in two ways. A click inside an `8va` stored the note
|
|
22
|
+
* an octave from where it will sound — in *every* mode, since a bracket is
|
|
23
|
+
* part of the notation rather than a way of reading it — and a click on a
|
|
24
|
+
* transposing part in written mode stored it by that instrument's interval
|
|
25
|
+
* (a whole tone on a B-flat clarinet).
|
|
26
|
+
*
|
|
27
|
+
* The lenses are undone in the reverse of the order they were applied:
|
|
28
|
+
* `displayScore` is `writtenScore(ottavaScore(score))`, so the transposition
|
|
29
|
+
* comes off first and the bracket second.
|
|
30
|
+
*/
|
|
31
|
+
export declare function soundingPitchForDrawn(score: Score, trackId: UUID, tick: number, drawn: Pitch, pitchDisplay: "concert" | "written"): Pitch;
|
|
32
|
+
//# sourceMappingURL=display-lens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-lens.d.ts","sourceRoot":"","sources":["../../../src/domain/notation/display-lens.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAIzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,IAAI,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,SAAS,GAAG,SAAS,GAClC,KAAK,CAsBP"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { soundingPitchForTrack } from "../../index.js";
|
|
2
|
+
import { ottavaShiftAt } from "../../index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Turns a pitch read off the *drawn* staff into the pitch to store.
|
|
5
|
+
*
|
|
6
|
+
* `pitchAtStavePoint` answers in the coordinate space the notation is drawn
|
|
7
|
+
* in, and that space has been through up to two display lenses:
|
|
8
|
+
* `ottavaScore` moves bracketed noteheads to where they are written, and
|
|
9
|
+
* `writtenScore` transposes a transposing instrument into its written key.
|
|
10
|
+
* The model stores **sounding** pitch, so writing a clicked position straight
|
|
11
|
+
* back in stores whatever was on screen as though it were the sound.
|
|
12
|
+
*
|
|
13
|
+
* That was silently wrong in two ways. A click inside an `8va` stored the note
|
|
14
|
+
* an octave from where it will sound — in *every* mode, since a bracket is
|
|
15
|
+
* part of the notation rather than a way of reading it — and a click on a
|
|
16
|
+
* transposing part in written mode stored it by that instrument's interval
|
|
17
|
+
* (a whole tone on a B-flat clarinet).
|
|
18
|
+
*
|
|
19
|
+
* The lenses are undone in the reverse of the order they were applied:
|
|
20
|
+
* `displayScore` is `writtenScore(ottavaScore(score))`, so the transposition
|
|
21
|
+
* comes off first and the bracket second.
|
|
22
|
+
*/
|
|
23
|
+
export function soundingPitchForDrawn(score, trackId, tick, drawn, pitchDisplay) {
|
|
24
|
+
const track = score.tracks.find((t) => t.id === trackId);
|
|
25
|
+
if (!track)
|
|
26
|
+
return drawn;
|
|
27
|
+
// The **sounding** key, which is what is stored — `soundingPitchForTrack`
|
|
28
|
+
// reads the key the note will sound in, not the one it is drawn in.
|
|
29
|
+
const measure = track.measures.find((m) => tick >= m.startTick && tick < m.startTick + m.durationTicks);
|
|
30
|
+
// Same fallback the inspector uses: a measure carries the key in force.
|
|
31
|
+
const key = measure?.keySignature ?? { fifths: 0, mode: "major" };
|
|
32
|
+
const untransposed = pitchDisplay === "written"
|
|
33
|
+
? soundingPitchForTrack(drawn, track, key)
|
|
34
|
+
: drawn;
|
|
35
|
+
// `ottavaScore` draws at `octave - shift`, so the inverse adds it back.
|
|
36
|
+
const shift = ottavaShiftAt(score, trackId, tick);
|
|
37
|
+
return shift === 0
|
|
38
|
+
? untransposed
|
|
39
|
+
: { ...untransposed, octave: untransposed.octave + shift };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=display-lens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-lens.js","sourceRoot":"","sources":["../../../src/domain/notation/display-lens.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAY,EACZ,OAAa,EACb,IAAY,EACZ,KAAY,EACZ,YAAmC;IAEnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,aAAa,CACnE,CAAC;IACF,wEAAwE;IACxE,MAAM,GAAG,GAAG,OAAO,EAAE,YAAY,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAElE,MAAM,YAAY,GAChB,YAAY,KAAK,SAAS;QACxB,CAAC,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC;QAC1C,CAAC,CAAC,KAAK,CAAC;IAEZ,wEAAwE;IACxE,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,CAAC;QAChB,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a score is when nobody has said otherwise.
|
|
3
|
+
*
|
|
4
|
+
* These four numbers are read by every decoder: a MIDI file states its tempo
|
|
5
|
+
* only if it wants to, MusicXML may omit the key, and a generated fragment
|
|
6
|
+
* carries neither. Each of those readers used to declare its own copy, so
|
|
7
|
+
* "the default" was six declarations that happened to agree — `factory.ts`
|
|
8
|
+
* alone held `DEFAULT_TEMPO_BPM` one line away from `tempo-map.ts`'s
|
|
9
|
+
* `DEFAULT_BPM`, the same fact under two names in one package.
|
|
10
|
+
*
|
|
11
|
+
* A tracker module's 125 BPM is deliberately NOT here: that is the MOD/XM
|
|
12
|
+
* format's own default, not ours, and folding it in would make one constant
|
|
13
|
+
* mean two things.
|
|
14
|
+
*/
|
|
15
|
+
import type { KeySignature, TimeSignature } from "../../index.js";
|
|
16
|
+
/** Ticks per quarter note. Every tick in the model is against this. */
|
|
17
|
+
export declare const DEFAULT_PPQ = 480;
|
|
18
|
+
export declare const DEFAULT_BPM = 120;
|
|
19
|
+
export declare const DEFAULT_TIME_SIGNATURE: TimeSignature;
|
|
20
|
+
export declare const DEFAULT_KEY_SIGNATURE: KeySignature;
|
|
21
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/domain/score/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAElE,uEAAuE;AACvE,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B,eAAO,MAAM,sBAAsB,EAAE,aAGpC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,YAA2C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Ticks per quarter note. Every tick in the model is against this. */
|
|
2
|
+
export const DEFAULT_PPQ = 480;
|
|
3
|
+
export const DEFAULT_BPM = 120;
|
|
4
|
+
export const DEFAULT_TIME_SIGNATURE = {
|
|
5
|
+
numerator: 4,
|
|
6
|
+
denominator: 4,
|
|
7
|
+
};
|
|
8
|
+
export const DEFAULT_KEY_SIGNATURE = { fifths: 0, mode: "major" };
|
|
9
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../src/domain/score/defaults.ts"],"names":[],"mappings":"AAgBA,uEAAuE;AACvE,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAE/B,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAE/B,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,SAAS,EAAE,CAAC;IACZ,WAAW,EAAE,CAAC;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAiB,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/domain/score/factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAEZ,KAAK,EAEL,aAAa,EACb,KAAK,EACN,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/domain/score/factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAEZ,KAAK,EAEL,aAAa,EACb,KAAK,EACN,MAAM,gBAAgB,CAAC;AAYxB,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,KAAK,CAc3D;AAwDD,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,KAAK,CAsCrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CA0BjD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CA6BvD"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { createId } from "./ids.js";
|
|
2
2
|
import { measureDurationTicks } from "../time/ticks.js";
|
|
3
|
-
|
|
4
|
-
const DEFAULT_TEMPO_BPM = 120;
|
|
5
|
-
const DEFAULT_TIME_SIGNATURE = { numerator: 4, denominator: 4 };
|
|
6
|
-
const DEFAULT_KEY_SIGNATURE = { fifths: 0, mode: "major" };
|
|
3
|
+
import { DEFAULT_BPM, DEFAULT_KEY_SIGNATURE, DEFAULT_PPQ, DEFAULT_TIME_SIGNATURE, } from "./defaults.js";
|
|
7
4
|
const DEFAULT_MEASURE_COUNT = 1;
|
|
8
5
|
const DEFAULT_VOICE_NAME = "Voice 1";
|
|
9
6
|
/** Builds a `Track` with sensible defaults, overridden by any fields in `opts`. */
|
|
@@ -83,9 +80,7 @@ export function createEmptyScore(opts) {
|
|
|
83
80
|
version: 1,
|
|
84
81
|
ppq,
|
|
85
82
|
metadata,
|
|
86
|
-
tempoMap: [
|
|
87
|
-
{ id: createId(), tick: 0, bpm: opts.tempo ?? DEFAULT_TEMPO_BPM },
|
|
88
|
-
],
|
|
83
|
+
tempoMap: [{ id: createId(), tick: 0, bpm: opts.tempo ?? DEFAULT_BPM }],
|
|
89
84
|
tracks,
|
|
90
85
|
};
|
|
91
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/domain/score/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AASpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/domain/score/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,4 +31,50 @@ export declare function allNotes(score: Score): NoteEvent[];
|
|
|
31
31
|
* reference — this filters, it never rewrites the music.
|
|
32
32
|
*/
|
|
33
33
|
export declare function scoreWithTracks(score: Score, trackIds: string[]): Score;
|
|
34
|
+
/**
|
|
35
|
+
* A track's notes in tick order.
|
|
36
|
+
*
|
|
37
|
+
* Lyric entry walks these, and so does anything that means "the next note
|
|
38
|
+
* after here" — so the sort is part of the answer rather than something each
|
|
39
|
+
* caller remembers. Rests are dropped: they carry no syllable and nothing that
|
|
40
|
+
* steps through notes wants to stop on one.
|
|
41
|
+
*/
|
|
42
|
+
export declare function trackNotesInOrder(score: Score, trackId: UUID): NoteEvent[];
|
|
43
|
+
/**
|
|
44
|
+
* The index of the first note at or after `tick`, or 0 when the tick is past
|
|
45
|
+
* every note.
|
|
46
|
+
*
|
|
47
|
+
* Falling back to the start rather than to -1: "begin here" with the caret
|
|
48
|
+
* past the end means begin at the beginning, which is what a writer expects
|
|
49
|
+
* from a command that has to start somewhere.
|
|
50
|
+
*/
|
|
51
|
+
export declare function noteIndexAtOrAfter(notes: readonly NoteEvent[], tick: number): number;
|
|
52
|
+
/**
|
|
53
|
+
* Which voice a note is in, counted from 1.
|
|
54
|
+
*
|
|
55
|
+
* From 1 because that is what the toolbar's own Voice 1 / Voice 2 buttons say;
|
|
56
|
+
* the same note used to read as "Voice 1" on the bar and `0` in the panel.
|
|
57
|
+
*/
|
|
58
|
+
export declare function voiceNumberOf(score: Score, note: NoteEvent): number;
|
|
59
|
+
/** The position of a measure in its own track, or `null` if it is not in the score. */
|
|
60
|
+
export declare function measureIndexOf(score: Score, measureId: UUID): number | null;
|
|
61
|
+
/** The measure holding `tick` on `trackId`, clamped to the last one past the end. */
|
|
62
|
+
export declare function measureAtTick(score: Score, trackId: UUID, tick: number): Measure | null;
|
|
63
|
+
/**
|
|
64
|
+
* The ids of notes whose sound overlaps `range` on the range's own tracks.
|
|
65
|
+
*
|
|
66
|
+
* Overlap, not containment: a note that starts before the range and is still
|
|
67
|
+
* sounding inside it was replaced by whatever was written there, so it is part
|
|
68
|
+
* of what changed.
|
|
69
|
+
*/
|
|
70
|
+
export declare function noteIdsOverlappingRange(score: Score, range: ScoreRange): UUID[];
|
|
71
|
+
/** The track a measure belongs to, or `null` if it is not in the score. */
|
|
72
|
+
export declare function trackOfMeasure(score: Score, measureId: UUID): Track | null;
|
|
73
|
+
/**
|
|
74
|
+
* How many bars the score has.
|
|
75
|
+
*
|
|
76
|
+
* Off track 0, because every track shares the measure grid — the convention
|
|
77
|
+
* the layout, the gutter and `measureIndexOf` all already rely on.
|
|
78
|
+
*/
|
|
79
|
+
export declare function barCount(score: Score | null): number;
|
|
34
80
|
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/domain/score/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,SAAS,EACT,KAAK,EACL,KAAK,EACL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAIxB,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,CAEnE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAMzE;AAED,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,YAAY,GAAG,IAAI,CAU1E;AAkBD,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,CAkB1E;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAC7B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,UAAU,GAChB,KAAK,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAU/C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,IAAI,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,GAAG,IAAI,CAmBlB;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CASjD;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,CAYlD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,CAKvE"}
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/domain/score/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,SAAS,EACT,KAAK,EACL,KAAK,EACL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAIxB,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,CAEnE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAMzE;AAED,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,YAAY,GAAG,IAAI,CAU1E;AAkBD,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,CAkB1E;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAC7B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,UAAU,GAChB,KAAK,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAU/C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,IAAI,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,GAAG,IAAI,CAmBlB;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CASjD;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,CAYlD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,CAKvE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,CAY1E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAQnE;AAED,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAM3E;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,IAAI,EACb,IAAI,EAAE,MAAM,GACX,OAAO,GAAG,IAAI,CAQhB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,UAAU,GAChB,IAAI,EAAE,CASR;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,CAI1E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,CAEpD"}
|