linked-rolls 0.1.0 → 0.1.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/RollCopy.d.ts +7 -1
- package/lib/RollCopy.js +49 -5
- package/package.json +1 -1
package/lib/RollCopy.d.ts
CHANGED
|
@@ -284,8 +284,14 @@ export interface StanfordAtonOptions {
|
|
|
284
284
|
*/
|
|
285
285
|
trackShift?: number;
|
|
286
286
|
bar?: TrackerBar;
|
|
287
|
+
/**
|
|
288
|
+
* Where the scan the analysis was made from can be seen. Stanford's
|
|
289
|
+
* files name their scan by DRUID, so this is only needed for an
|
|
290
|
+
* analysis of a scan hosted elsewhere.
|
|
291
|
+
*/
|
|
292
|
+
scan?: string;
|
|
287
293
|
}
|
|
288
|
-
export declare function readFromStanfordAton(atonString: string, { trackShift, bar }?: StanfordAtonOptions): RollCopy;
|
|
294
|
+
export declare function readFromStanfordAton(atonString: string, { trackShift, bar, scan }?: StanfordAtonOptions): RollCopy;
|
|
289
295
|
/**
|
|
290
296
|
* How a MIDI key number in one of Spencer Chase's roll files names a
|
|
291
297
|
* tracker bar track.
|
package/lib/RollCopy.js
CHANGED
|
@@ -100,6 +100,21 @@ export const calibrationOf = (copy) => {
|
|
|
100
100
|
};
|
|
101
101
|
/** Values in these files carry their unit as a suffix, e.g. "37.7646px". */
|
|
102
102
|
const px = (value) => parseFloat(value);
|
|
103
|
+
/** The parser writes one record as an object and several as an array. */
|
|
104
|
+
const listOf = (value) => value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
105
|
+
/**
|
|
106
|
+
* Holes the parser set aside as suspicious after it had already chained
|
|
107
|
+
* them into a note: the head of such a chain is usually a punch that
|
|
108
|
+
* came out a little short, and leaving it out would lose the whole
|
|
109
|
+
* chain. They carry no track number of their own, so the column says
|
|
110
|
+
* which track they sit on.
|
|
111
|
+
*/
|
|
112
|
+
const chainedBadHoles = (holes, calibration) => holes
|
|
113
|
+
.filter(hole => hole.NOTE_ATTACK && hole.OFF_TIME)
|
|
114
|
+
.map(hole => ({
|
|
115
|
+
...hole,
|
|
116
|
+
TRACKER_HOLE: `${Math.round((px(hole.CENTROID_COL) - calibration.offset) / calibration.separation)}`
|
|
117
|
+
}));
|
|
103
118
|
const millimeters = (pixels, dpi) => pixels / dpi * 25.4;
|
|
104
119
|
const median = (values) => {
|
|
105
120
|
const sorted = [...values].sort((a, b) => a - b);
|
|
@@ -139,13 +154,37 @@ const punchDiameterOf = (holes, dpi) => {
|
|
|
139
154
|
return undefined;
|
|
140
155
|
return circular.reduce((sum, diameter) => sum + diameter, 0) / circular.length;
|
|
141
156
|
};
|
|
142
|
-
|
|
157
|
+
/**
|
|
158
|
+
* The image service Stanford keeps for a scan, and a crop of a
|
|
159
|
+
* feature from it.
|
|
160
|
+
*/
|
|
161
|
+
const stanfordScan = (druid) => ({
|
|
162
|
+
scan: `https://stacks.stanford.edu/image/iiif/${druid}%2F${druid}_0001/`,
|
|
163
|
+
depictionOf: (column, row, width, height) => `https://stacks.stanford.edu/image/iiif/${druid}/${druid}_0001/${column},${row},${width},${height}/128,/270/default.jpg`
|
|
164
|
+
});
|
|
165
|
+
/**
|
|
166
|
+
* The software behind an analysis and when it was run, as the
|
|
167
|
+
* analysis file states them.
|
|
168
|
+
*/
|
|
169
|
+
const measuredByOf = (rollinfo) => {
|
|
170
|
+
const date = new Date(rollinfo.ANALYSIS_DATE);
|
|
171
|
+
if (!rollinfo.HOLE_SOFTWARE || isNaN(date.getTime()))
|
|
172
|
+
return undefined;
|
|
173
|
+
return {
|
|
174
|
+
software: rollinfo.HOLE_SOFTWARE,
|
|
175
|
+
version: rollinfo.SOFTWARE_DATE ?? '',
|
|
176
|
+
date
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
export function readFromStanfordAton(atonString, { trackShift, bar = welteT100, scan } = {}) {
|
|
143
180
|
const parser = new AtonParser();
|
|
144
181
|
const json = parser.parse(atonString);
|
|
145
182
|
const holes = json.ROLLINFO.HOLES.HOLE;
|
|
146
183
|
const druid = json.ROLLINFO.DRUID;
|
|
184
|
+
const stanford = druid ? stanfordScan(druid) : undefined;
|
|
147
185
|
const separation = px(json.ROLLINFO.HOLE_SEPARATION);
|
|
148
186
|
const dpi = parseFloat(json.ROLLINFO.LENGTH_DPI);
|
|
187
|
+
const measuredBy = measuredByOf(json.ROLLINFO);
|
|
149
188
|
const rewindTrack = rewindTrackIn(holes);
|
|
150
189
|
const shift = trackShift
|
|
151
190
|
?? (rewindTrack === undefined ? 0 : bar.rewindTrack - rewindTrack);
|
|
@@ -156,8 +195,10 @@ export function readFromStanfordAton(atonString, { trackShift, bar = welteT100 }
|
|
|
156
195
|
shift
|
|
157
196
|
};
|
|
158
197
|
const punchDiameter = punchDiameterOf(holes, dpi);
|
|
159
|
-
const
|
|
198
|
+
const chains = [...holes, ...chainedBadHoles(listOf(json.ROLLINFO.BADHOLES?.HOLE), calibration)]
|
|
160
199
|
.filter(hole => hole.NOTE_ATTACK && hole.OFF_TIME)
|
|
200
|
+
.sort((a, b) => px(a.NOTE_ATTACK) - px(b.NOTE_ATTACK));
|
|
201
|
+
const features = chains
|
|
161
202
|
.map((hole) => {
|
|
162
203
|
const attack = px(hole.NOTE_ATTACK);
|
|
163
204
|
const release = px(hole.OFF_TIME);
|
|
@@ -166,7 +207,9 @@ export function readFromStanfordAton(atonString, { trackShift, bar = welteT100 }
|
|
|
166
207
|
return {
|
|
167
208
|
type: 'Hole',
|
|
168
209
|
id: v4(),
|
|
169
|
-
|
|
210
|
+
...(stanford && {
|
|
211
|
+
depiction: stanford.depictionOf(column, attack, columnWidth, release - attack)
|
|
212
|
+
}),
|
|
170
213
|
vertical: {
|
|
171
214
|
from: +hole.TRACKER_HOLE + shift,
|
|
172
215
|
unit: 'track'
|
|
@@ -185,7 +228,7 @@ export function readFromStanfordAton(atonString, { trackShift, bar = welteT100 }
|
|
|
185
228
|
conditions: [],
|
|
186
229
|
location: '',
|
|
187
230
|
modifications: [],
|
|
188
|
-
scan:
|
|
231
|
+
...((scan ?? stanford) && { scan: scan ?? stanford?.scan }),
|
|
189
232
|
measurements: {
|
|
190
233
|
dimensions: {
|
|
191
234
|
width: millimeters(px(json.ROLLINFO.ROLL_WIDTH), dpi),
|
|
@@ -204,7 +247,8 @@ export function readFromStanfordAton(atonString, { trackShift, bar = welteT100 }
|
|
|
204
247
|
bass: px(json.ROLLINFO.HARD_MARGIN_BASS),
|
|
205
248
|
unit: 'px'
|
|
206
249
|
},
|
|
207
|
-
trackCalibration: calibration
|
|
250
|
+
trackCalibration: calibration,
|
|
251
|
+
...(measuredBy && { measuredBy })
|
|
208
252
|
},
|
|
209
253
|
features
|
|
210
254
|
};
|
package/package.json
CHANGED