@sudobility/music_types 0.11.20 → 0.11.21
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/dist/domain/commands/edit-commands.d.ts +66 -0
- package/dist/domain/commands/edit-commands.d.ts.map +1 -0
- package/dist/domain/commands/edit-commands.js +185 -0
- package/dist/domain/commands/edit-commands.js.map +1 -0
- package/dist/domain/commands/note-commands.d.ts +73 -0
- package/dist/domain/commands/note-commands.d.ts.map +1 -0
- package/dist/domain/commands/note-commands.js +292 -0
- package/dist/domain/commands/note-commands.js.map +1 -0
- package/dist/domain/commands/reflow.d.ts +69 -0
- package/dist/domain/commands/reflow.d.ts.map +1 -0
- package/dist/domain/commands/reflow.js +395 -0
- package/dist/domain/commands/reflow.js.map +1 -0
- package/dist/domain/commands/region-commands.d.ts +21 -0
- package/dist/domain/commands/region-commands.d.ts.map +1 -0
- package/dist/domain/commands/region-commands.js +47 -0
- package/dist/domain/commands/region-commands.js.map +1 -0
- package/dist/domain/commands/relocate-commands.d.ts +18 -0
- package/dist/domain/commands/relocate-commands.d.ts.map +1 -0
- package/dist/domain/commands/relocate-commands.js +108 -0
- package/dist/domain/commands/relocate-commands.js.map +1 -0
- package/dist/domain/commands/ripple-commands.d.ts +44 -0
- package/dist/domain/commands/ripple-commands.d.ts.map +1 -0
- package/dist/domain/commands/ripple-commands.js +104 -0
- package/dist/domain/commands/ripple-commands.js.map +1 -0
- package/dist/domain/commands/snapshot.d.ts +38 -0
- package/dist/domain/commands/snapshot.d.ts.map +1 -0
- package/dist/domain/commands/snapshot.js +44 -0
- package/dist/domain/commands/snapshot.js.map +1 -0
- package/dist/domain/commands/structure-commands.d.ts +38 -0
- package/dist/domain/commands/structure-commands.d.ts.map +1 -0
- package/dist/domain/commands/structure-commands.js +220 -0
- package/dist/domain/commands/structure-commands.js.map +1 -0
- package/dist/domain/commands/track-commands.d.ts +15 -0
- package/dist/domain/commands/track-commands.d.ts.map +1 -0
- package/dist/domain/commands/track-commands.js +56 -0
- package/dist/domain/commands/track-commands.js.map +1 -0
- package/dist/domain/commands/types.d.ts +31 -0
- package/dist/domain/commands/types.d.ts.map +1 -0
- package/dist/domain/commands/types.js +2 -0
- package/dist/domain/commands/types.js.map +1 -0
- package/dist/domain/instruments/gm-kit.d.ts +45 -0
- package/dist/domain/instruments/gm-kit.d.ts.map +1 -0
- package/dist/domain/instruments/gm-kit.js +59 -0
- package/dist/domain/instruments/gm-kit.js.map +1 -0
- package/dist/domain/instruments/gm-percussion.d.ts +42 -0
- package/dist/domain/instruments/gm-percussion.d.ts.map +1 -0
- package/dist/domain/instruments/gm-percussion.js +85 -0
- package/dist/domain/instruments/gm-percussion.js.map +1 -0
- package/dist/domain/instruments/gm-polyphony.d.ts +13 -0
- package/dist/domain/instruments/gm-polyphony.d.ts.map +1 -0
- package/dist/domain/instruments/gm-polyphony.js +76 -0
- package/dist/domain/instruments/gm-polyphony.js.map +1 -0
- package/dist/domain/instruments/gm-range.d.ts +15 -0
- package/dist/domain/instruments/gm-range.d.ts.map +1 -0
- package/dist/domain/instruments/gm-range.js +97 -0
- package/dist/domain/instruments/gm-range.js.map +1 -0
- package/dist/domain/instruments/gm-transposition.d.ts +11 -0
- package/dist/domain/instruments/gm-transposition.d.ts.map +1 -0
- package/dist/domain/instruments/gm-transposition.js +69 -0
- package/dist/domain/instruments/gm-transposition.js.map +1 -0
- package/dist/domain/instruments/gm.d.ts +28 -0
- package/dist/domain/instruments/gm.d.ts.map +1 -0
- package/dist/domain/instruments/gm.js +217 -0
- package/dist/domain/instruments/gm.js.map +1 -0
- package/dist/domain/pitch/pitch.d.ts +15 -0
- package/dist/domain/pitch/pitch.d.ts.map +1 -0
- package/dist/domain/pitch/pitch.js +81 -0
- package/dist/domain/pitch/pitch.js.map +1 -0
- package/dist/domain/pitch/transpose.d.ts +37 -0
- package/dist/domain/pitch/transpose.d.ts.map +1 -0
- package/dist/domain/pitch/transpose.js +65 -0
- package/dist/domain/pitch/transpose.js.map +1 -0
- package/dist/domain/quantization/options.d.ts +55 -0
- package/dist/domain/quantization/options.d.ts.map +1 -0
- package/dist/domain/quantization/options.js +2 -0
- package/dist/domain/quantization/options.js.map +1 -0
- package/dist/domain/quantization/quantize.d.ts +13 -0
- package/dist/domain/quantization/quantize.d.ts.map +1 -0
- package/dist/domain/quantization/quantize.js +199 -0
- package/dist/domain/quantization/quantize.js.map +1 -0
- package/dist/domain/score/factory.d.ts +39 -0
- package/dist/domain/score/factory.d.ts.map +1 -0
- package/dist/domain/score/factory.js +148 -0
- package/dist/domain/score/factory.js.map +1 -0
- package/dist/domain/score/fragment.d.ts +28 -0
- package/dist/domain/score/fragment.d.ts.map +1 -0
- package/dist/domain/score/fragment.js +68 -0
- package/dist/domain/score/fragment.js.map +1 -0
- package/dist/domain/score/ids.d.ts +8 -0
- package/dist/domain/score/ids.d.ts.map +1 -0
- package/dist/domain/score/ids.js +38 -0
- package/dist/domain/score/ids.js.map +1 -0
- package/dist/domain/score/queries.d.ts +34 -0
- package/dist/domain/score/queries.d.ts.map +1 -0
- package/dist/domain/score/queries.js +132 -0
- package/dist/domain/score/queries.js.map +1 -0
- package/dist/domain/score/ties.d.ts +73 -0
- package/dist/domain/score/ties.d.ts.map +1 -0
- package/dist/domain/score/ties.js +200 -0
- package/dist/domain/score/ties.js.map +1 -0
- package/dist/domain/selection/selection.d.ts +63 -0
- package/dist/domain/selection/selection.d.ts.map +1 -0
- package/dist/domain/selection/selection.js +129 -0
- package/dist/domain/selection/selection.js.map +1 -0
- package/dist/domain/selection/types.d.ts +10 -0
- package/dist/domain/selection/types.d.ts.map +1 -0
- package/dist/domain/selection/types.js +5 -0
- package/dist/domain/selection/types.js.map +1 -0
- package/dist/domain/time/durations.d.ts +21 -0
- package/dist/domain/time/durations.d.ts.map +1 -0
- package/dist/domain/time/durations.js +53 -0
- package/dist/domain/time/durations.js.map +1 -0
- package/dist/domain/time/fraction.d.ts +19 -0
- package/dist/domain/time/fraction.d.ts.map +1 -0
- package/dist/domain/time/fraction.js +60 -0
- package/dist/domain/time/fraction.js.map +1 -0
- package/dist/domain/time/tempo-map.d.ts +24 -0
- package/dist/domain/time/tempo-map.d.ts.map +1 -0
- package/dist/domain/time/tempo-map.js +85 -0
- package/dist/domain/time/tempo-map.js.map +1 -0
- package/dist/domain/time/ticks.d.ts +34 -0
- package/dist/domain/time/ticks.d.ts.map +1 -0
- package/dist/domain/time/ticks.js +93 -0
- package/dist/domain/time/ticks.js.map +1 -0
- package/dist/domain/validation/issues.d.ts +44 -0
- package/dist/domain/validation/issues.d.ts.map +1 -0
- package/dist/domain/validation/issues.js +34 -0
- package/dist/domain/validation/issues.js.map +1 -0
- package/dist/domain/validation/validator.d.ts +11 -0
- package/dist/domain/validation/validator.d.ts.map +1 -0
- package/dist/domain/validation/validator.js +375 -0
- package/dist/domain/validation/validator.js.map +1 -0
- package/dist/domain/voicing/allocate.d.ts +19 -0
- package/dist/domain/voicing/allocate.d.ts.map +1 -0
- package/dist/domain/voicing/allocate.js +100 -0
- package/dist/domain/voicing/allocate.js.map +1 -0
- package/dist/index.d.ts +46 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/dist/services/regeneration/controller.d.ts +60 -0
- package/dist/services/regeneration/controller.d.ts.map +1 -0
- package/dist/services/regeneration/controller.js +202 -0
- package/dist/services/regeneration/controller.js.map +1 -0
- package/dist/test/fixtures.d.ts +45 -0
- package/dist/test/fixtures.d.ts.map +1 -0
- package/dist/test/fixtures.js +420 -0
- package/dist/test/fixtures.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"note-commands.js","sourceRoot":"","sources":["../../../src/domain/commands/note-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Measure, NoteEvent, Score, ScoreMetadata, Track, UUID } from '../../index.js';
|
|
2
|
+
/** Returns `metadata` with `updatedAt` refreshed to now. */
|
|
3
|
+
export declare function touchMetadata(metadata: ScoreMetadata): ScoreMetadata;
|
|
4
|
+
/**
|
|
5
|
+
* Returns `{ ...score, tracks }` with `metadata.updatedAt` refreshed, but
|
|
6
|
+
* only if `tracks` actually differs from `score.tracks` (checked
|
|
7
|
+
* per-element by reference — every helper in this module returns an
|
|
8
|
+
* unchanged track/measure/voice by reference when it made no edit, so this
|
|
9
|
+
* is an exact "did anything really change" test). A true no-op command
|
|
10
|
+
* (e.g. deleting an id that doesn't exist) therefore returns `score`
|
|
11
|
+
* itself, not just a structurally-equal copy with a bumped timestamp.
|
|
12
|
+
*/
|
|
13
|
+
export declare function withTracks(score: Score, tracks: Track[]): Score;
|
|
14
|
+
/**
|
|
15
|
+
* Clears the matching tie flag on the immediate tie-chain partner(s) of
|
|
16
|
+
* every note in `eventIds` that is *not itself* also in `eventIds` — so a
|
|
17
|
+
* note about to be moved or deleted never leaves a dangling `tieStart`/
|
|
18
|
+
* `tieStop` on a partner left behind. Must be called on `score` *before*
|
|
19
|
+
* the notes in `eventIds` are actually removed/relocated, since it relies
|
|
20
|
+
* on `tieChainFor`'s search of the note's current position; the notes in
|
|
21
|
+
* `eventIds` themselves are expected to have their own tie flags cleared
|
|
22
|
+
* separately by the caller (they're leaving their old position entirely).
|
|
23
|
+
* Returns `score` unchanged (referentially) if nothing needed clearing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function clearDanglingTies(score: Score, eventIds: ReadonlySet<UUID>): Score;
|
|
26
|
+
/**
|
|
27
|
+
* Rebuilds the voice at `voiceId` within `measure` so its note content is
|
|
28
|
+
* exactly what was already there — minus overlap resolution (see
|
|
29
|
+
* `resolveOverlaps`) — but gap-filled with fresh rests and trimmed to fit
|
|
30
|
+
* the measure: notes are grouped into non-overlapping (chord-aware)
|
|
31
|
+
* placements, clipped to the measure's span, and any silent gap
|
|
32
|
+
* between/after them (up to the measure's end) is filled with a new
|
|
33
|
+
* `RestEvent`. Existing `RestEvent`s are discarded and regenerated from
|
|
34
|
+
* scratch. Returns `measure` unchanged (referentially) if it has no voice
|
|
35
|
+
* with `voiceId`.
|
|
36
|
+
*
|
|
37
|
+
* `trackId` is taken as an explicit parameter (rather than read off an
|
|
38
|
+
* existing event) so this still works when the voice's note content is
|
|
39
|
+
* completely empty (e.g. after deleting every note in it).
|
|
40
|
+
*/
|
|
41
|
+
export declare function reflowVoice(measure: Measure, voiceId: UUID, trackId: UUID): Measure;
|
|
42
|
+
/**
|
|
43
|
+
* Returns `measure` with a voice guaranteed to exist at ordinal position
|
|
44
|
+
* `voiceIndex` in `measure.voices` (per the Task 3 voice-identity
|
|
45
|
+
* convention: voices correlate across measures by ordinal index, not id).
|
|
46
|
+
* Missing intermediate voices (and `voiceIndex` itself, if absent) are
|
|
47
|
+
* created as fresh, fully-rested voices. Returns `measure` unchanged
|
|
48
|
+
* (referentially) if a voice already exists at that index.
|
|
49
|
+
*/
|
|
50
|
+
export declare function ensureVoiceAtIndex(measure: Measure, voiceIndex: number, trackId: UUID): Measure;
|
|
51
|
+
/**
|
|
52
|
+
* Removes every note event whose id is in `eventIds` from `track`,
|
|
53
|
+
* reflowing (rest-backfilling) each voice that actually lost a note.
|
|
54
|
+
* Measures/voices with nothing removed are returned unchanged
|
|
55
|
+
* (referentially), so unaffected structure is preserved.
|
|
56
|
+
*/
|
|
57
|
+
export declare function removeNotesFromTrack(track: Track, eventIds: ReadonlySet<UUID>): Track;
|
|
58
|
+
/**
|
|
59
|
+
* Inserts `note` into `track` at the measure whose span contains
|
|
60
|
+
* `note.startTick`, in the voice at ordinal position `voiceIndex`
|
|
61
|
+
* (created if necessary via `ensureVoiceAtIndex`), then reflows that
|
|
62
|
+
* voice. `note` is expected to already fit entirely within one measure's
|
|
63
|
+
* span (the caller — e.g. a note-move that crosses a measure boundary —
|
|
64
|
+
* is responsible for splitting it first, per Task 3's
|
|
65
|
+
* `splitNoteAcrossMeasures`). If no measure contains `note.startTick`,
|
|
66
|
+
* `track` is returned unchanged.
|
|
67
|
+
*/
|
|
68
|
+
export declare function insertNoteIntoTrack(track: Track, note: NoteEvent, voiceIndex: number): Track;
|
|
69
|
+
//# sourceMappingURL=reflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflow.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/reflow.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,OAAO,EAEP,SAAS,EACT,KAAK,EACL,aAAa,EACb,KAAK,EACL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAIxB,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAEpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAO/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,GAC1B,KAAK,CA2DP;AAkJD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,IAAI,GACZ,OAAO,CA0ET;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,IAAI,GACZ,OAAO,CAqBT;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,GAC1B,KAAK,CAyBP;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,GACjB,KAAK,CA+BP"}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared low-level, pure Measure/Track mutation helpers used by the note-
|
|
3
|
+
* and structure-editing command factories (Task 5 brief). Every function
|
|
4
|
+
* here returns new objects; none mutate their inputs.
|
|
5
|
+
*/
|
|
6
|
+
import { createId } from '../score/ids.js';
|
|
7
|
+
import { findEvent } from '../score/queries.js';
|
|
8
|
+
import { tieChainFor } from '../score/ties.js';
|
|
9
|
+
import { isNoteEvent } from '../../index.js';
|
|
10
|
+
import { pitchToMidi } from '../pitch/pitch.js';
|
|
11
|
+
/** Returns `metadata` with `updatedAt` refreshed to now. */
|
|
12
|
+
export function touchMetadata(metadata) {
|
|
13
|
+
return { ...metadata, updatedAt: new Date().toISOString() };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns `{ ...score, tracks }` with `metadata.updatedAt` refreshed, but
|
|
17
|
+
* only if `tracks` actually differs from `score.tracks` (checked
|
|
18
|
+
* per-element by reference — every helper in this module returns an
|
|
19
|
+
* unchanged track/measure/voice by reference when it made no edit, so this
|
|
20
|
+
* is an exact "did anything really change" test). A true no-op command
|
|
21
|
+
* (e.g. deleting an id that doesn't exist) therefore returns `score`
|
|
22
|
+
* itself, not just a structurally-equal copy with a bumped timestamp.
|
|
23
|
+
*/
|
|
24
|
+
export function withTracks(score, tracks) {
|
|
25
|
+
const changed = tracks.length !== score.tracks.length ||
|
|
26
|
+
tracks.some((t, i) => t !== score.tracks[i]);
|
|
27
|
+
return changed
|
|
28
|
+
? { ...score, tracks, metadata: touchMetadata(score.metadata) }
|
|
29
|
+
: score;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Clears the matching tie flag on the immediate tie-chain partner(s) of
|
|
33
|
+
* every note in `eventIds` that is *not itself* also in `eventIds` — so a
|
|
34
|
+
* note about to be moved or deleted never leaves a dangling `tieStart`/
|
|
35
|
+
* `tieStop` on a partner left behind. Must be called on `score` *before*
|
|
36
|
+
* the notes in `eventIds` are actually removed/relocated, since it relies
|
|
37
|
+
* on `tieChainFor`'s search of the note's current position; the notes in
|
|
38
|
+
* `eventIds` themselves are expected to have their own tie flags cleared
|
|
39
|
+
* separately by the caller (they're leaving their old position entirely).
|
|
40
|
+
* Returns `score` unchanged (referentially) if nothing needed clearing.
|
|
41
|
+
*/
|
|
42
|
+
export function clearDanglingTies(score, eventIds) {
|
|
43
|
+
const clears = new Map();
|
|
44
|
+
for (const id of eventIds) {
|
|
45
|
+
const note = findEvent(score, id);
|
|
46
|
+
if (!note || !isNoteEvent(note) || (!note.tieStart && !note.tieStop))
|
|
47
|
+
continue;
|
|
48
|
+
const chain = tieChainFor(score, id);
|
|
49
|
+
const index = chain.findIndex(n => n.id === id);
|
|
50
|
+
if (index === -1)
|
|
51
|
+
continue;
|
|
52
|
+
if (note.tieStop && index > 0) {
|
|
53
|
+
const partner = chain[index - 1];
|
|
54
|
+
if (!eventIds.has(partner.id)) {
|
|
55
|
+
clears.set(partner.id, {
|
|
56
|
+
...clears.get(partner.id),
|
|
57
|
+
clearTieStart: true,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (note.tieStart && index < chain.length - 1) {
|
|
62
|
+
const partner = chain[index + 1];
|
|
63
|
+
if (!eventIds.has(partner.id)) {
|
|
64
|
+
clears.set(partner.id, {
|
|
65
|
+
...clears.get(partner.id),
|
|
66
|
+
clearTieStop: true,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (clears.size === 0)
|
|
72
|
+
return score;
|
|
73
|
+
const tracks = score.tracks.map(track => {
|
|
74
|
+
const measures = track.measures.map(measure => {
|
|
75
|
+
const voices = measure.voices.map(voice => {
|
|
76
|
+
const events = voice.events.map(event => {
|
|
77
|
+
const clear = clears.get(event.id);
|
|
78
|
+
if (!clear || !isNoteEvent(event))
|
|
79
|
+
return event;
|
|
80
|
+
const updated = { ...event };
|
|
81
|
+
if (clear.clearTieStart)
|
|
82
|
+
delete updated.tieStart;
|
|
83
|
+
if (clear.clearTieStop)
|
|
84
|
+
delete updated.tieStop;
|
|
85
|
+
return updated;
|
|
86
|
+
});
|
|
87
|
+
const changed = events.some((e, i) => e !== voice.events[i]);
|
|
88
|
+
return changed ? { ...voice, events } : voice;
|
|
89
|
+
});
|
|
90
|
+
const changed = voices.some((v, i) => v !== measure.voices[i]);
|
|
91
|
+
return changed ? { ...measure, voices } : measure;
|
|
92
|
+
});
|
|
93
|
+
const changed = measures.some((m, i) => m !== track.measures[i]);
|
|
94
|
+
return changed ? { ...track, measures } : track;
|
|
95
|
+
});
|
|
96
|
+
return withTracks(score, tracks);
|
|
97
|
+
}
|
|
98
|
+
/** `target` minus every interval in `claimed` (assumed pairwise disjoint), as the remaining disjoint pieces. */
|
|
99
|
+
function subtractIntervals(target, claimed) {
|
|
100
|
+
let pieces = [target];
|
|
101
|
+
for (const c of claimed) {
|
|
102
|
+
const next = [];
|
|
103
|
+
for (const p of pieces) {
|
|
104
|
+
if (c.end <= p.start || c.start >= p.end) {
|
|
105
|
+
next.push(p); // no overlap with this claimed interval
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (c.start > p.start)
|
|
109
|
+
next.push({ start: p.start, end: Math.min(c.start, p.end) });
|
|
110
|
+
if (c.end < p.end)
|
|
111
|
+
next.push({ start: Math.max(c.end, p.start), end: p.end });
|
|
112
|
+
}
|
|
113
|
+
pieces = next.filter(iv => iv.end > iv.start);
|
|
114
|
+
}
|
|
115
|
+
return pieces;
|
|
116
|
+
}
|
|
117
|
+
/** The longest of `pieces` (ties broken by earliest start), or `null` for an empty list. */
|
|
118
|
+
function largestPiece(pieces) {
|
|
119
|
+
return pieces.reduce((best, p) => {
|
|
120
|
+
if (!best)
|
|
121
|
+
return p;
|
|
122
|
+
const bestLen = best.end - best.start;
|
|
123
|
+
const pLen = p.end - p.start;
|
|
124
|
+
if (pLen > bestLen || (pLen === bestLen && p.start < best.start))
|
|
125
|
+
return p;
|
|
126
|
+
return best;
|
|
127
|
+
}, null);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Within notes that all share one identical span (a same-span cluster —
|
|
131
|
+
* see `resolveOverlaps`), keeps only the last (highest original-array-
|
|
132
|
+
* index) note per pitch (compared by MIDI, so enharmonic respellings of
|
|
133
|
+
* the same physical pitch also dedupe), dropping earlier same-pitch
|
|
134
|
+
* duplicates. Different-pitch notes at the identical span are unaffected
|
|
135
|
+
* and all survive — that's the real, legitimate chord case. This exists
|
|
136
|
+
* because "same span" alone isn't sufficient to call two notes a chord:
|
|
137
|
+
* two *same-pitch* notes at the identical span are a genuine duplicate/
|
|
138
|
+
* conflicting edit (e.g. a note dropped exactly onto an existing note of
|
|
139
|
+
* the same pitch), and `validateScore`'s `checkOverlappingSamePitch`
|
|
140
|
+
* correctly flags that as an error — silently keeping both would produce
|
|
141
|
+
* an invalid score.
|
|
142
|
+
*/
|
|
143
|
+
function dedupeSamePitch(notes) {
|
|
144
|
+
const byMidi = new Map();
|
|
145
|
+
for (const note of notes) {
|
|
146
|
+
// A later entry for the same pitch overwrites an earlier one, so the
|
|
147
|
+
// last (highest-priority) note of that pitch wins — consistent with
|
|
148
|
+
// resolveOverlaps's documented last-in-array-wins rule.
|
|
149
|
+
byMidi.set(pitchToMidi(note.pitch), note);
|
|
150
|
+
}
|
|
151
|
+
return [...byMidi.values()];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Resolves overlapping notes within one voice's note list into a set of
|
|
155
|
+
* pairwise-disjoint placements (chords aside — see below), deterministically:
|
|
156
|
+
*
|
|
157
|
+
* - Notes sharing the *exact* same `(startTick, durationTicks)` are
|
|
158
|
+
* candidate chord members (per `allocateVoices`'s `groupChordClusters`/
|
|
159
|
+
* spec §25). Among same-span notes, only *different-pitch* ones form a
|
|
160
|
+
* real chord and all survive; same-pitch duplicates at that span are
|
|
161
|
+
* deduped down to the last one (see `dedupeSamePitch`) rather than kept
|
|
162
|
+
* as "overlapping."
|
|
163
|
+
* - Between genuinely different spans that overlap, **last-in-array
|
|
164
|
+
* wins**: every command in this module that inserts/moves/resizes a
|
|
165
|
+
* note builds its voice's event list as `[...existingNotes, editedOrNewNote]`,
|
|
166
|
+
* so "last" always means "the note this edit just touched." The
|
|
167
|
+
* winning note keeps its full span; whatever it overlaps is trimmed
|
|
168
|
+
* down to its own remaining (non-overlapping) piece, or dropped
|
|
169
|
+
* entirely if fully covered. If trimming would leave a note with two
|
|
170
|
+
* disjoint remaining pieces (a higher-priority note punched a hole in
|
|
171
|
+
* its middle), only the longer piece survives — a note can't be split
|
|
172
|
+
* into two fragments by this step (Task 3's `splitNoteAcrossMeasures`
|
|
173
|
+
* is the tool for genuine multi-segment splitting, at measure
|
|
174
|
+
* boundaries; mid-note deletion-by-overlap is a deliberately simpler,
|
|
175
|
+
* documented edge case here).
|
|
176
|
+
*
|
|
177
|
+
* This is "replace-on-overlap" by design: it's what lets a piano-roll
|
|
178
|
+
* drag/insert land a new note and have it take precedence over whatever
|
|
179
|
+
* it's dropped onto, matching common DAW behavior, while still keeping
|
|
180
|
+
* `reflowVoice`'s output well-formed (no silently-overlapping, no
|
|
181
|
+
* silently-duplicate-pitch notes).
|
|
182
|
+
*/
|
|
183
|
+
function resolveOverlaps(originalNotes) {
|
|
184
|
+
const clusters = new Map();
|
|
185
|
+
originalNotes.forEach((note, priority) => {
|
|
186
|
+
const key = `${note.startTick}:${note.durationTicks}`;
|
|
187
|
+
const existing = clusters.get(key);
|
|
188
|
+
if (existing) {
|
|
189
|
+
existing.notes.push(note);
|
|
190
|
+
existing.priority = Math.max(existing.priority, priority);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
clusters.set(key, {
|
|
194
|
+
startTick: note.startTick,
|
|
195
|
+
durationTicks: note.durationTicks,
|
|
196
|
+
notes: [note],
|
|
197
|
+
priority,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
const orderedByPriorityDesc = [...clusters.values()].sort((a, b) => b.priority - a.priority);
|
|
202
|
+
const claimed = [];
|
|
203
|
+
const placed = [];
|
|
204
|
+
for (const cluster of orderedByPriorityDesc) {
|
|
205
|
+
const target = {
|
|
206
|
+
start: cluster.startTick,
|
|
207
|
+
end: cluster.startTick + cluster.durationTicks,
|
|
208
|
+
};
|
|
209
|
+
const chosen = largestPiece(subtractIntervals(target, claimed));
|
|
210
|
+
if (!chosen)
|
|
211
|
+
continue; // fully covered by a higher-priority note/chord; drop this cluster entirely
|
|
212
|
+
const survivors = dedupeSamePitch(cluster.notes);
|
|
213
|
+
for (const note of survivors) {
|
|
214
|
+
placed.push({
|
|
215
|
+
...note,
|
|
216
|
+
startTick: chosen.start,
|
|
217
|
+
durationTicks: chosen.end - chosen.start,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
claimed.push(chosen);
|
|
221
|
+
}
|
|
222
|
+
return placed;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Rebuilds the voice at `voiceId` within `measure` so its note content is
|
|
226
|
+
* exactly what was already there — minus overlap resolution (see
|
|
227
|
+
* `resolveOverlaps`) — but gap-filled with fresh rests and trimmed to fit
|
|
228
|
+
* the measure: notes are grouped into non-overlapping (chord-aware)
|
|
229
|
+
* placements, clipped to the measure's span, and any silent gap
|
|
230
|
+
* between/after them (up to the measure's end) is filled with a new
|
|
231
|
+
* `RestEvent`. Existing `RestEvent`s are discarded and regenerated from
|
|
232
|
+
* scratch. Returns `measure` unchanged (referentially) if it has no voice
|
|
233
|
+
* with `voiceId`.
|
|
234
|
+
*
|
|
235
|
+
* `trackId` is taken as an explicit parameter (rather than read off an
|
|
236
|
+
* existing event) so this still works when the voice's note content is
|
|
237
|
+
* completely empty (e.g. after deleting every note in it).
|
|
238
|
+
*/
|
|
239
|
+
export function reflowVoice(measure, voiceId, trackId) {
|
|
240
|
+
const voiceIndex = measure.voices.findIndex(v => v.id === voiceId);
|
|
241
|
+
if (voiceIndex === -1)
|
|
242
|
+
return measure;
|
|
243
|
+
const voice = measure.voices[voiceIndex];
|
|
244
|
+
const measureStart = measure.startTick;
|
|
245
|
+
const measureEnd = measure.startTick + measure.durationTicks;
|
|
246
|
+
const originalNotes = voice.events.filter(isNoteEvent);
|
|
247
|
+
const resolved = resolveOverlaps(originalNotes);
|
|
248
|
+
const groupsByKey = new Map();
|
|
249
|
+
for (const note of resolved) {
|
|
250
|
+
const key = `${note.startTick}:${note.durationTicks}`;
|
|
251
|
+
const group = groupsByKey.get(key);
|
|
252
|
+
if (group)
|
|
253
|
+
group.notes.push(note);
|
|
254
|
+
else
|
|
255
|
+
groupsByKey.set(key, {
|
|
256
|
+
startTick: note.startTick,
|
|
257
|
+
durationTicks: note.durationTicks,
|
|
258
|
+
notes: [note],
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
const groups = [...groupsByKey.values()].sort((a, b) => a.startTick - b.startTick);
|
|
262
|
+
const events = [];
|
|
263
|
+
let cursor = measureStart;
|
|
264
|
+
for (const group of groups) {
|
|
265
|
+
const start = Math.max(group.startTick, cursor, measureStart);
|
|
266
|
+
const end = Math.min(group.startTick + group.durationTicks, measureEnd);
|
|
267
|
+
if (end <= start)
|
|
268
|
+
continue;
|
|
269
|
+
if (start > cursor) {
|
|
270
|
+
events.push({
|
|
271
|
+
id: createId(),
|
|
272
|
+
startTick: cursor,
|
|
273
|
+
durationTicks: start - cursor,
|
|
274
|
+
voiceId,
|
|
275
|
+
trackId,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
for (const note of group.notes) {
|
|
279
|
+
events.push({
|
|
280
|
+
...note,
|
|
281
|
+
startTick: start,
|
|
282
|
+
durationTicks: end - start,
|
|
283
|
+
voiceId,
|
|
284
|
+
trackId,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
cursor = end;
|
|
288
|
+
}
|
|
289
|
+
if (cursor < measureEnd) {
|
|
290
|
+
events.push({
|
|
291
|
+
id: createId(),
|
|
292
|
+
startTick: cursor,
|
|
293
|
+
durationTicks: measureEnd - cursor,
|
|
294
|
+
voiceId,
|
|
295
|
+
trackId,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
const voices = measure.voices.map((v, i) => i === voiceIndex ? { ...v, events } : v);
|
|
299
|
+
return { ...measure, voices };
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Returns `measure` with a voice guaranteed to exist at ordinal position
|
|
303
|
+
* `voiceIndex` in `measure.voices` (per the Task 3 voice-identity
|
|
304
|
+
* convention: voices correlate across measures by ordinal index, not id).
|
|
305
|
+
* Missing intermediate voices (and `voiceIndex` itself, if absent) are
|
|
306
|
+
* created as fresh, fully-rested voices. Returns `measure` unchanged
|
|
307
|
+
* (referentially) if a voice already exists at that index.
|
|
308
|
+
*/
|
|
309
|
+
export function ensureVoiceAtIndex(measure, voiceIndex, trackId) {
|
|
310
|
+
if (measure.voices[voiceIndex])
|
|
311
|
+
return measure;
|
|
312
|
+
const voices = measure.voices.slice();
|
|
313
|
+
while (voices.length <= voiceIndex) {
|
|
314
|
+
const voiceId = createId();
|
|
315
|
+
voices.push({
|
|
316
|
+
id: voiceId,
|
|
317
|
+
name: `Voice ${voices.length + 1}`,
|
|
318
|
+
events: [
|
|
319
|
+
{
|
|
320
|
+
id: createId(),
|
|
321
|
+
startTick: measure.startTick,
|
|
322
|
+
durationTicks: measure.durationTicks,
|
|
323
|
+
voiceId,
|
|
324
|
+
trackId,
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return { ...measure, voices };
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Removes every note event whose id is in `eventIds` from `track`,
|
|
333
|
+
* reflowing (rest-backfilling) each voice that actually lost a note.
|
|
334
|
+
* Measures/voices with nothing removed are returned unchanged
|
|
335
|
+
* (referentially), so unaffected structure is preserved.
|
|
336
|
+
*/
|
|
337
|
+
export function removeNotesFromTrack(track, eventIds) {
|
|
338
|
+
const measures = track.measures.map(measure => {
|
|
339
|
+
let nextMeasure = measure;
|
|
340
|
+
let changed = false;
|
|
341
|
+
for (const voice of measure.voices) {
|
|
342
|
+
if (!voice.events.some(e => eventIds.has(e.id)))
|
|
343
|
+
continue;
|
|
344
|
+
changed = true;
|
|
345
|
+
const remainingNotes = voice.events
|
|
346
|
+
.filter(isNoteEvent)
|
|
347
|
+
.filter(e => !eventIds.has(e.id));
|
|
348
|
+
const withRemoved = {
|
|
349
|
+
...nextMeasure,
|
|
350
|
+
voices: nextMeasure.voices.map(v => v.id === voice.id ? { ...v, events: remainingNotes } : v),
|
|
351
|
+
};
|
|
352
|
+
nextMeasure = reflowVoice(withRemoved, voice.id, track.id);
|
|
353
|
+
}
|
|
354
|
+
return changed ? nextMeasure : measure;
|
|
355
|
+
});
|
|
356
|
+
const trackChanged = measures.some((m, i) => m !== track.measures[i]);
|
|
357
|
+
return trackChanged ? { ...track, measures } : track;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Inserts `note` into `track` at the measure whose span contains
|
|
361
|
+
* `note.startTick`, in the voice at ordinal position `voiceIndex`
|
|
362
|
+
* (created if necessary via `ensureVoiceAtIndex`), then reflows that
|
|
363
|
+
* voice. `note` is expected to already fit entirely within one measure's
|
|
364
|
+
* span (the caller — e.g. a note-move that crosses a measure boundary —
|
|
365
|
+
* is responsible for splitting it first, per Task 3's
|
|
366
|
+
* `splitNoteAcrossMeasures`). If no measure contains `note.startTick`,
|
|
367
|
+
* `track` is returned unchanged.
|
|
368
|
+
*/
|
|
369
|
+
export function insertNoteIntoTrack(track, note, voiceIndex) {
|
|
370
|
+
const measures = track.measures.map(measure => {
|
|
371
|
+
if (note.startTick < measure.startTick ||
|
|
372
|
+
note.startTick >= measure.startTick + measure.durationTicks) {
|
|
373
|
+
return measure;
|
|
374
|
+
}
|
|
375
|
+
const ensured = ensureVoiceAtIndex(measure, voiceIndex, track.id);
|
|
376
|
+
const voice = ensured.voices[voiceIndex];
|
|
377
|
+
const existingNotes = voice.events.filter(isNoteEvent);
|
|
378
|
+
const withInserted = {
|
|
379
|
+
...ensured,
|
|
380
|
+
voices: ensured.voices.map((v, i) => i === voiceIndex
|
|
381
|
+
? {
|
|
382
|
+
...v,
|
|
383
|
+
events: [
|
|
384
|
+
...existingNotes,
|
|
385
|
+
{ ...note, voiceId: v.id, trackId: track.id },
|
|
386
|
+
],
|
|
387
|
+
}
|
|
388
|
+
: v),
|
|
389
|
+
};
|
|
390
|
+
return reflowVoice(withInserted, voice.id, track.id);
|
|
391
|
+
});
|
|
392
|
+
const trackChanged = measures.some((m, i) => m !== track.measures[i]);
|
|
393
|
+
return trackChanged ? { ...track, measures } : track;
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=reflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflow.js","sourceRoot":"","sources":["../../../src/domain/commands/reflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ScoreFragment } from '../score/fragment.js';
|
|
2
|
+
import type { ScoreRange } from '../selection/types.js';
|
|
3
|
+
import type { Score } from '../../index.js';
|
|
4
|
+
import type { ScoreCommand } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Replaces the measures overlapping `range` with `newFragment`'s content
|
|
7
|
+
* (Task 3's `replaceFragment`), the single undoable command behind
|
|
8
|
+
* accepting an AI-regenerated candidate (spec §12). `range` is the
|
|
9
|
+
* authoritative target location (overriding `newFragment.range`, in case
|
|
10
|
+
* a provider-returned fragment's own `range` is only a placeholder). The
|
|
11
|
+
* label is derived from the fragment's own measure indices, so no `Score`
|
|
12
|
+
* needs to be passed in at construction time.
|
|
13
|
+
*/
|
|
14
|
+
export declare function replaceRegionCommand(range: ScoreRange, newFragment: ScoreFragment): ScoreCommand;
|
|
15
|
+
/**
|
|
16
|
+
* Wholesale-replaces the current score with `newScore` (e.g. a freshly
|
|
17
|
+
* imported MIDI/MusicXML file), as a single undoable command per spec
|
|
18
|
+
* §15/§17.
|
|
19
|
+
*/
|
|
20
|
+
export declare function importScoreCommand(newScore: Score, label: string): ScoreCommand;
|
|
21
|
+
//# sourceMappingURL=region-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-commands.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/region-commands.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY/C;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,aAAa,GACzB,YAAY,CAWd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,KAAK,EACf,KAAK,EAAE,MAAM,GACZ,YAAY,CAId"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Region-replacement command factories (spec §12, §14): used by AI
|
|
3
|
+
* regeneration acceptance (`replaceRegionCommand`) and by MIDI/MusicXML
|
|
4
|
+
* import (`importScoreCommand`), both as a single undoable command per
|
|
5
|
+
* spec §12 item 13 / §15.
|
|
6
|
+
*/
|
|
7
|
+
import { current } from 'immer';
|
|
8
|
+
import { replaceFragment } from '../score/fragment.js';
|
|
9
|
+
import { snapshotCommand } from './snapshot.js';
|
|
10
|
+
/** 1-based inclusive [min, max] measure index label span across every track in `fragment`, or `null` if it has no measures. */
|
|
11
|
+
function measureIndexSpan(fragment) {
|
|
12
|
+
const indices = fragment.tracks.flatMap(t => t.measures.map(m => m.index));
|
|
13
|
+
if (indices.length === 0)
|
|
14
|
+
return null;
|
|
15
|
+
return { first: Math.min(...indices) + 1, last: Math.max(...indices) + 1 };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Replaces the measures overlapping `range` with `newFragment`'s content
|
|
19
|
+
* (Task 3's `replaceFragment`), the single undoable command behind
|
|
20
|
+
* accepting an AI-regenerated candidate (spec §12). `range` is the
|
|
21
|
+
* authoritative target location (overriding `newFragment.range`, in case
|
|
22
|
+
* a provider-returned fragment's own `range` is only a placeholder). The
|
|
23
|
+
* label is derived from the fragment's own measure indices, so no `Score`
|
|
24
|
+
* needs to be passed in at construction time.
|
|
25
|
+
*/
|
|
26
|
+
export function replaceRegionCommand(range, newFragment) {
|
|
27
|
+
const fragment = { ...newFragment, range };
|
|
28
|
+
const span = measureIndexSpan(fragment);
|
|
29
|
+
const label = span
|
|
30
|
+
? `Regenerate measures ${span.first}–${span.last}`
|
|
31
|
+
: 'Regenerate measures';
|
|
32
|
+
return snapshotCommand(label, draft => {
|
|
33
|
+
const next = replaceFragment(current(draft), fragment);
|
|
34
|
+
Object.assign(draft, next);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Wholesale-replaces the current score with `newScore` (e.g. a freshly
|
|
39
|
+
* imported MIDI/MusicXML file), as a single undoable command per spec
|
|
40
|
+
* §15/§17.
|
|
41
|
+
*/
|
|
42
|
+
export function importScoreCommand(newScore, label) {
|
|
43
|
+
return snapshotCommand(label, draft => {
|
|
44
|
+
Object.assign(draft, newScore);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=region-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-commands.js","sourceRoot":"","sources":["../../../src/domain/commands/region-commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,+HAA+H;AAC/H,SAAS,gBAAgB,CACvB,QAAuB;IAEvB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAiB,EACjB,WAA0B;IAE1B,MAAM,QAAQ,GAAkB,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI;QAChB,CAAC,CAAC,uBAAuB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE;QAClD,CAAC,CAAC,qBAAqB,CAAC;IAE1B,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QACpC,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAU,EAAE,QAAQ,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAe,EACf,KAAa;IAEb,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QACpC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UUID } from '../../index.js';
|
|
2
|
+
import type { ScoreCommand } from './types.js';
|
|
3
|
+
/** What happens to music already at the destination. Mirrors the editor's edit mode. */
|
|
4
|
+
export type CollisionMode = 'stack' | 'replace' | 'ripple';
|
|
5
|
+
export type RelocateNotesParams = {
|
|
6
|
+
targetTrackId: UUID;
|
|
7
|
+
deltaTicks: number;
|
|
8
|
+
collision: CollisionMode;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Moves `eventIds` onto `params.targetTrackId`, shifted by `params.deltaTicks`.
|
|
12
|
+
*
|
|
13
|
+
* Pitch is untouched: a note dragged from flute to cello sounds identical, and
|
|
14
|
+
* only its player changes. Notes are clamped into the target track rather than
|
|
15
|
+
* dropped when the shift runs past its end.
|
|
16
|
+
*/
|
|
17
|
+
export declare function relocateNotesCommand(eventIds: UUID[], params: RelocateNotesParams, label: string): ScoreCommand;
|
|
18
|
+
//# sourceMappingURL=relocate-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relocate-commands.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/relocate-commands.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAA2B,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C,wFAAwF;AACxF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3D,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;CAC1B,CAAC;AA+HF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,IAAI,EAAE,EAChB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,MAAM,GACZ,YAAY,CAId"}
|