linked-rolls 0.5.0 → 0.5.1
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/lib/Agent.d.ts +59 -0
- package/lib/Agent.js +1 -0
- package/lib/Assumption.d.ts +19 -1
- package/lib/Collation.d.ts +19 -0
- package/lib/Collation.js +25 -1
- package/lib/Edit.d.ts +1 -8
- package/lib/Edition.d.ts +4 -77
- package/lib/Edition.js +1 -1
- package/lib/EditionView.d.ts +0 -7
- package/lib/EditionView.js +0 -50
- package/lib/ReproducingSystem.d.ts +23 -1
- package/lib/RollCopy.d.ts +2 -68
- package/lib/RollCopy.js +2 -303
- package/lib/TrackerBar.d.ts +16 -14
- package/lib/TrackerBar.js +1 -56
- package/lib/alignment.d.ts +21 -0
- package/lib/alignment.js +117 -0
- package/lib/constraints.d.ts +27 -0
- package/lib/constraints.js +61 -0
- package/lib/editionOps.js +7 -10
- package/lib/index.d.ts +18 -13
- package/lib/index.js +18 -13
- package/lib/migrate.js +2 -1
- package/lib/readers/spencerMidi.d.ts +26 -0
- package/lib/readers/spencerMidi.js +58 -0
- package/lib/readers/stanfordAton.d.ts +18 -0
- package/lib/readers/stanfordAton.js +158 -0
- package/lib/systems/welteT100/bar.d.ts +14 -0
- package/lib/systems/welteT100/bar.js +56 -0
- package/lib/systems/{welteT100.d.ts → welteT100/system.d.ts} +1 -1
- package/lib/systems/{welteT100.js → welteT100/system.js} +1 -1
- package/lib/utils.d.ts +0 -8
- package/lib/validate.d.ts +0 -27
- package/lib/validate.js +0 -61
- package/package.json +3 -3
- package/lib/alignFeatures.d.ts +0 -12
- package/lib/alignFeatures.js +0 -55
- /package/lib/{aton → readers}/AtonParser.d.ts +0 -0
- /package/lib/{aton → readers}/AtonParser.js +0 -0
- /package/lib/{asMIDISpans.d.ts → readers/midiSpans.d.ts} +0 -0
- /package/lib/{asMIDISpans.js → readers/midiSpans.js} +0 -0
package/lib/alignFeatures.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { welteT100 } from "./TrackerBar";
|
|
2
|
-
const isNoteOn = (bar) => (feature) => {
|
|
3
|
-
return feature.type === 'Hole' && bar.meaningOf(feature.vertical.from)?.type === 'note';
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* Fit a line: position = alpha * index + beta via least squares.
|
|
7
|
-
*/
|
|
8
|
-
function fitIndexToPosition(indices, positions) {
|
|
9
|
-
const n = indices.length;
|
|
10
|
-
const meanIdx = indices.reduce((s, i) => s + i, 0) / n;
|
|
11
|
-
const meanPos = positions.reduce((s, p) => s + p, 0) / n;
|
|
12
|
-
let num = 0;
|
|
13
|
-
let den = 0;
|
|
14
|
-
for (let i = 0; i < n; i++) {
|
|
15
|
-
const d = indices[i] - meanIdx;
|
|
16
|
-
num += d * (positions[i] - meanPos);
|
|
17
|
-
den += d * d;
|
|
18
|
-
}
|
|
19
|
-
const alpha = den === 0 ? 1 : num / den;
|
|
20
|
-
const beta = meanPos - alpha * meanIdx;
|
|
21
|
-
return { alpha, beta };
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Selects the first and last N elements of an array (or fewer if length is smaller).
|
|
25
|
-
*/
|
|
26
|
-
function selectEnds(arr, count) {
|
|
27
|
-
const n = arr.length;
|
|
28
|
-
if (count * 2 >= n)
|
|
29
|
-
return arr.slice();
|
|
30
|
-
return arr.slice(0, count).concat(arr.slice(n - count, n));
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Align two rolls by computing independent linear fits of each roll's note-onset positions
|
|
34
|
-
* using only the first and last segments, then deriving a transform x2 = (x1 + shift) * stretch.
|
|
35
|
-
*/
|
|
36
|
-
export function alignFeatures(rollA, rollB, bar = welteT100) {
|
|
37
|
-
// 1. Extract note-onset positions
|
|
38
|
-
const isNote = isNoteOn(bar);
|
|
39
|
-
const allXA = rollA.filter(isNote).map(f => f.horizontal.from);
|
|
40
|
-
const allXB = rollB.filter(isNote).map(f => f.horizontal.from);
|
|
41
|
-
// 2. Determine segment size (e.g. 10% of notes, min 5)
|
|
42
|
-
const segCount = Math.max(5, Math.floor(allXA.length * 0.1));
|
|
43
|
-
// 3. Select only first and last segments
|
|
44
|
-
const XA = selectEnds(allXA, segCount);
|
|
45
|
-
const idxA = XA.map((_, i) => i);
|
|
46
|
-
const XB = selectEnds(allXB, segCount);
|
|
47
|
-
const idxB = XB.map((_, i) => i);
|
|
48
|
-
// 4. Fit index->position for each roll on selected ends
|
|
49
|
-
const { alpha: alphaA, beta: betaA } = fitIndexToPosition(idxA, XA);
|
|
50
|
-
const { alpha: alphaB, beta: betaB } = fitIndexToPosition(idxB, XB);
|
|
51
|
-
// 5. Derive stretch and shift such that x2 = (x1 + shift) * stretch
|
|
52
|
-
const stretch = alphaB / alphaA;
|
|
53
|
-
const shift = betaB / stretch - betaA;
|
|
54
|
-
return { stretch, shift };
|
|
55
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|