linked-rolls 0.46.0 → 0.47.0
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/README.md +35 -2
- package/lib/RollCopy.d.ts +12 -1
- package/lib/alignment.d.ts +26 -0
- package/lib/alignment.js +41 -1
- package/lib/editionOps.d.ts +24 -8
- package/lib/editionOps.js +42 -14
- package/lib/readers/phillipsEroll.d.ts +29 -11
- package/lib/readers/phillipsEroll.js +21 -12
- package/lib/schema.json +6 -1
- package/lib/spec/context.json +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,17 +143,50 @@ and the onset alone 39, so neither test is idle, but a difference at the
|
|
|
143
143
|
end is as often a punch measured badly as a punch genuinely prolonged,
|
|
144
144
|
and the two are not worth confusing.
|
|
145
145
|
|
|
146
|
+
## What a reader adds to a hole
|
|
147
|
+
|
|
148
|
+
A copy read pneumatically rather than scanned reports how long a valve
|
|
149
|
+
stayed open, and a valve is held on past the perforation that opened it,
|
|
150
|
+
so its holes run longer than the punched slots while their onsets agree.
|
|
151
|
+
Left in, that is not a difference between copies: a collation comparing
|
|
152
|
+
such a copy's hole ends against a scanned copy's compares an on-time
|
|
153
|
+
with a slot, and reads the one as a lengthening of the other.
|
|
154
|
+
|
|
155
|
+
`shortenHoles` takes the extension off and records it on the copy,
|
|
156
|
+
`revertShortening` puts it back, and `readFromPhillipsEroll` will take
|
|
157
|
+
it off at import. Only holes are touched, what a writing spans being no
|
|
158
|
+
valve. The figure is measured against the other copies rather than
|
|
159
|
+
derived from the bar, since Phillips gives only the difference between
|
|
160
|
+
two bars and not the absolute.
|
|
161
|
+
|
|
162
|
+
On welte225.org that figure is about 1.6 mm, and its shape is simple. It
|
|
163
|
+
does not grow with the length of the perforation: the ratio of the read
|
|
164
|
+
length to the true one falls from 1.34 on the shortest punches to 1.01
|
|
165
|
+
on the longest, which is what a constant added to everything does. There
|
|
166
|
+
is no shortest on-time the valve cannot fall below. It shows no run
|
|
167
|
+
along the roll, though one roll's span of paper speed is too narrow to
|
|
168
|
+
tell a constant in millimetres from a constant in time. What it does
|
|
169
|
+
vary with is the port that read it, by about half a millimetre either
|
|
170
|
+
way and with no gradient across the bar, which is measured but too
|
|
171
|
+
coarse to model from a single roll.
|
|
172
|
+
|
|
146
173
|
## Collating a derivation a second time
|
|
147
174
|
|
|
148
175
|
A collated symbol is one symbol carrying every copy that reads it, so a
|
|
149
176
|
collation cannot simply be run again: there is no second symbol left to
|
|
150
|
-
match. `separateReadings` is the inverse. It takes
|
|
151
|
-
back off the symbols it shares, gives them to new symbols of the
|
|
177
|
+
match. `separateReadings` is the inverse. It takes the carriers of one
|
|
178
|
+
side back off the symbols it shares, gives them to new symbols of the
|
|
152
179
|
version's own, and states the exchange, leaving the edition in the state
|
|
153
180
|
a collation would have produced had nothing joined. `connectVersions` at
|
|
154
181
|
a new tolerance then re-collates, joining again whatever the new window
|
|
155
182
|
admits.
|
|
156
183
|
|
|
184
|
+
It takes a side and not a copy, the same side `sidesOf` names and a
|
|
185
|
+
window is measured over. Naming one copy of a side that has several does
|
|
186
|
+
not separate that side: the rest of it stays behind on the other side's
|
|
187
|
+
symbol, and a collation then compares one copy against that mixture
|
|
188
|
+
rather than the two texts against each other.
|
|
189
|
+
|
|
157
190
|
Nothing an editor established is lost by that. `connectVersions`
|
|
158
191
|
rewrites only what a collation wrote (`isCollationsOwn`): a bare
|
|
159
192
|
insertion or deletion, or an equivalence between two systems' spellings.
|
package/lib/RollCopy.d.ts
CHANGED
|
@@ -201,7 +201,7 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
|
201
201
|
* (e.g. 'shifted', 'stretched') to normalize measurements
|
|
202
202
|
* for comparison with other copies. Not exported to RDF.
|
|
203
203
|
*/
|
|
204
|
-
ops: Array<'shifted' | 'stretched'>;
|
|
204
|
+
ops: Array<'shifted' | 'stretched' | 'shortened'>;
|
|
205
205
|
/**
|
|
206
206
|
* Physical measurements of this roll copy, including
|
|
207
207
|
* dimensions, punch diameter, hole separation, margins,
|
|
@@ -258,6 +258,17 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
|
258
258
|
* Not exported to RDF.
|
|
259
259
|
*/
|
|
260
260
|
scale: number;
|
|
261
|
+
/**
|
|
262
|
+
* How much longer this copy's reading of a hole ran than the
|
|
263
|
+
* perforation that caused it, where that was taken off the ends
|
|
264
|
+
* again. A pneumatic reader reports how long a valve stayed
|
|
265
|
+
* open, which exceeds the perforation that opened it, so its
|
|
266
|
+
* holes are overlong by a constant while its onsets agree.
|
|
267
|
+
* Nothing for a copy read by other means, whose holes are the
|
|
268
|
+
* punched slots themselves.
|
|
269
|
+
* Not exported to RDF.
|
|
270
|
+
*/
|
|
271
|
+
readerExtension: Millimeters;
|
|
261
272
|
/**
|
|
262
273
|
* The resolution this copy's scan was read at, along the roll.
|
|
263
274
|
* It is what the measurements given in pixels are to be read
|
package/lib/alignment.d.ts
CHANGED
|
@@ -9,6 +9,32 @@ export declare const applyScale: (factor: number, copy: RollCopy) => void;
|
|
|
9
9
|
export declare const revertShift: (copy: RollCopy) => void;
|
|
10
10
|
/** Takes the scale off the copy's features again, as far as one was applied. */
|
|
11
11
|
export declare const revertScale: (copy: RollCopy) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Takes the extension a pneumatic reader adds off the ends of the
|
|
14
|
+
* copy's holes, and records how much was taken.
|
|
15
|
+
*
|
|
16
|
+
* Such a reader reports how long a valve stayed open, and a valve is
|
|
17
|
+
* held on past the perforation that opened it, so its holes run longer
|
|
18
|
+
* than the punched slots while their onsets agree. Left in, the
|
|
19
|
+
* difference is not a difference between copies at all: a collation
|
|
20
|
+
* comparing this copy's hole ends against a scanned copy's compares a
|
|
21
|
+
* pneumatic on-time with a punched slot, and reads the one as a
|
|
22
|
+
* lengthening of the other.
|
|
23
|
+
*
|
|
24
|
+
* The extension is a property of the reader rather than of the roll,
|
|
25
|
+
* and on the material measured so far it is a constant: it does not
|
|
26
|
+
* grow with the length of the perforation, there is no shortest
|
|
27
|
+
* on-time the valve cannot fall below, and it does not run along the
|
|
28
|
+
* roll with the paper speed as far as one roll can show. What it does
|
|
29
|
+
* vary with is the port that read it, by about half a millimetre either
|
|
30
|
+
* way and without any gradient across the bar, which is measured but
|
|
31
|
+
* too coarse to model from one roll.
|
|
32
|
+
*
|
|
33
|
+
* Only holes are touched. What a writing or a mark spans is no valve.
|
|
34
|
+
*/
|
|
35
|
+
export declare const shortenHoles: (extension: Millimeters, copy: RollCopy) => void;
|
|
36
|
+
/** Puts the reader's extension back on the copy's holes, as far as one was taken off. */
|
|
37
|
+
export declare const revertShortening: (copy: RollCopy) => void;
|
|
12
38
|
/**
|
|
13
39
|
* How a copy's places are carried onto another copy's:
|
|
14
40
|
* `x_other = (x + shift) · scale`.
|
package/lib/alignment.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { featuresOf } from "./RollCopy.js";
|
|
2
2
|
import { welteT100 } from "./systems/welteT100/bar.js";
|
|
3
|
-
import { add, mm, scale } from "./Quantity.js";
|
|
3
|
+
import { add, mm, scale, subtract } from "./Quantity.js";
|
|
4
4
|
/** Moves both ends of a span, the far end only where the span has one. */
|
|
5
5
|
const move = (span, by) => {
|
|
6
6
|
span.from = add(span.from, by);
|
|
@@ -54,6 +54,46 @@ export const revertScale = (copy) => {
|
|
|
54
54
|
copy.ops = copy.ops.filter(op => op !== 'stretched');
|
|
55
55
|
delete copy.measurements.scale;
|
|
56
56
|
};
|
|
57
|
+
const holesOf = (copy) => featuresOf(copy).filter(feature => feature.type === 'Hole');
|
|
58
|
+
/**
|
|
59
|
+
* Takes the extension a pneumatic reader adds off the ends of the
|
|
60
|
+
* copy's holes, and records how much was taken.
|
|
61
|
+
*
|
|
62
|
+
* Such a reader reports how long a valve stayed open, and a valve is
|
|
63
|
+
* held on past the perforation that opened it, so its holes run longer
|
|
64
|
+
* than the punched slots while their onsets agree. Left in, the
|
|
65
|
+
* difference is not a difference between copies at all: a collation
|
|
66
|
+
* comparing this copy's hole ends against a scanned copy's compares a
|
|
67
|
+
* pneumatic on-time with a punched slot, and reads the one as a
|
|
68
|
+
* lengthening of the other.
|
|
69
|
+
*
|
|
70
|
+
* The extension is a property of the reader rather than of the roll,
|
|
71
|
+
* and on the material measured so far it is a constant: it does not
|
|
72
|
+
* grow with the length of the perforation, there is no shortest
|
|
73
|
+
* on-time the valve cannot fall below, and it does not run along the
|
|
74
|
+
* roll with the paper speed as far as one roll can show. What it does
|
|
75
|
+
* vary with is the port that read it, by about half a millimetre either
|
|
76
|
+
* way and without any gradient across the bar, which is measured but
|
|
77
|
+
* too coarse to model from one roll.
|
|
78
|
+
*
|
|
79
|
+
* Only holes are touched. What a writing or a mark spans is no valve.
|
|
80
|
+
*/
|
|
81
|
+
export const shortenHoles = (extension, copy) => {
|
|
82
|
+
if (copy.ops.includes('shortened'))
|
|
83
|
+
return;
|
|
84
|
+
holesOf(copy).forEach(hole => { hole.horizontal.to = subtract(hole.horizontal.to, extension); });
|
|
85
|
+
copy.ops = [...copy.ops, 'shortened'];
|
|
86
|
+
copy.measurements.readerExtension = extension;
|
|
87
|
+
};
|
|
88
|
+
/** Puts the reader's extension back on the copy's holes, as far as one was taken off. */
|
|
89
|
+
export const revertShortening = (copy) => {
|
|
90
|
+
const extension = copy.measurements.readerExtension;
|
|
91
|
+
if (!copy.ops.includes('shortened') || extension === undefined)
|
|
92
|
+
return;
|
|
93
|
+
holesOf(copy).forEach(hole => { hole.horizontal.to = add(hole.horizontal.to, extension); });
|
|
94
|
+
copy.ops = copy.ops.filter(op => op !== 'shortened');
|
|
95
|
+
delete copy.measurements.readerExtension;
|
|
96
|
+
};
|
|
57
97
|
const byPlace = (x, y) => x.at - y.at || x.pitch - y.pitch;
|
|
58
98
|
/** The notes the bar reads off the features, in the order they pass it. */
|
|
59
99
|
const noteOnsets = (features, bar) => features
|
package/lib/editionOps.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { GeneralRollCondition, ModificationPurpose, RollCopy, ScaleReading, Shif
|
|
|
8
8
|
import { FeatureSource } from "./FeatureSource.js";
|
|
9
9
|
import { AnyArgumentation, Belief, Certainty, ObjectAssumption } from "./Assumption.js";
|
|
10
10
|
import { FeatureConditionAssignment, FeatureOrPatch, NestedFeature } from "./Feature.js";
|
|
11
|
+
import { Millimeters } from "./Quantity.js";
|
|
11
12
|
/**
|
|
12
13
|
* A change to an edition, written onto an immer draft of it. One
|
|
13
14
|
* operation is one undo step, so an operation that has to read the
|
|
@@ -40,6 +41,14 @@ export declare const alignCopy: (copyId: string, shift: Shift, scale: number, re
|
|
|
40
41
|
* being a fact about the copy.
|
|
41
42
|
*/
|
|
42
43
|
export declare const unalignCopy: (copyId: string) => EditionOp;
|
|
44
|
+
/**
|
|
45
|
+
* Takes the extension a pneumatic reader adds off the ends of the
|
|
46
|
+
* copy's holes, and records how much was taken, so that its lengths
|
|
47
|
+
* can be compared with a scanned copy's at all.
|
|
48
|
+
*/
|
|
49
|
+
export declare const shortenCopy: (copyId: string, extension: Millimeters) => EditionOp;
|
|
50
|
+
/** Puts the reader's extension back on the copy's holes. */
|
|
51
|
+
export declare const unshortenCopy: (copyId: string) => EditionOp;
|
|
43
52
|
/** States what the copy's features were read from, in place of any earlier statement. */
|
|
44
53
|
export declare const stateSource: (copyId: string, source: FeatureSource) => EditionOp;
|
|
45
54
|
/** Takes back the statement, leaving the copy silent about its source again. */
|
|
@@ -180,9 +189,9 @@ export declare const connectVersions: (view: EditionView, childId: string, paren
|
|
|
180
189
|
*/
|
|
181
190
|
export declare const collateSymbols: (view: EditionView, versionId: string, symbolIds: readonly string[], tolerance?: CollationTolerance) => EditionOp;
|
|
182
191
|
/**
|
|
183
|
-
* Takes the
|
|
184
|
-
* collated into:
|
|
185
|
-
* version's own, the
|
|
192
|
+
* Takes the named copies' reading of a symbol back out of the symbol it
|
|
193
|
+
* was collated into: their carriers pass to a new symbol of the
|
|
194
|
+
* version's own, the remaining copies keep the symbol they had, and the
|
|
186
195
|
* version states the exchange.
|
|
187
196
|
*
|
|
188
197
|
* This is the inverse of the hand-over a collation makes, and it is
|
|
@@ -191,12 +200,19 @@ export declare const collateSymbols: (view: EditionView, versionId: string, symb
|
|
|
191
200
|
* takes the two readings apart again, and without that a tolerance
|
|
192
201
|
* arrived at after the fact could never be applied.
|
|
193
202
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
203
|
+
* The copies named are one **side** of the derivation, the same side a
|
|
204
|
+
* window is measured over, and `sidesOf` is what says which they are.
|
|
205
|
+
* Naming one copy of a side that has several does not separate that
|
|
206
|
+
* side: what stays behind is the rest of it, mixed with the other
|
|
207
|
+
* side's copies, and a collation then compares one copy against that
|
|
208
|
+
* mixture rather than the two texts against each other.
|
|
209
|
+
*
|
|
210
|
+
* Symbols the named copies alone carry are already the version's own
|
|
211
|
+
* and are passed over, so a reading somebody has separated by hand
|
|
212
|
+
* keeps its identifier and the edit that speaks for it. Named symbols
|
|
213
|
+
* narrow the act to those; naming none separates the whole reading.
|
|
198
214
|
*/
|
|
199
|
-
export declare const separateReadings: (view: EditionView, versionId: string,
|
|
215
|
+
export declare const separateReadings: (view: EditionView, versionId: string, copies: ReadonlySet<string>, symbolIds?: readonly string[]) => EditionOp;
|
|
200
216
|
/**
|
|
201
217
|
* Makes the version stand on its own: what it inherited becomes its
|
|
202
218
|
* own insertions, and its derivations go, the hypotheses among them,
|
package/lib/editionOps.js
CHANGED
|
@@ -8,7 +8,7 @@ import { asSymbols, barOf, featuresByAct, featuresOf, isPaperStretch, statesNoth
|
|
|
8
8
|
import { systemOf } from "./TrackerBar.js";
|
|
9
9
|
import { substitutionsBetween } from "./substitution.js";
|
|
10
10
|
import { trackerBarOf } from "./systems/index.js";
|
|
11
|
-
import { applyShift, applyScale, revertShift, revertScale } from "./alignment.js";
|
|
11
|
+
import { applyShift, applyScale, revertShift, revertScale, revertShortening, shortenHoles } from "./alignment.js";
|
|
12
12
|
import { assignReference, idOf } from "./Assumption.js";
|
|
13
13
|
import { conditions as conditionsAllowed, featuresBorneBy, isGluedOn, withBorneFeatures } from "./Feature.js";
|
|
14
14
|
import { distance, mm, subtract } from "./Quantity.js";
|
|
@@ -125,6 +125,14 @@ export const unalignCopy = (copyId) => onCopy(copyId, copy => {
|
|
|
125
125
|
revertShift(copy);
|
|
126
126
|
copy.conditions = without(copy.conditions, isPaperStretch);
|
|
127
127
|
});
|
|
128
|
+
/**
|
|
129
|
+
* Takes the extension a pneumatic reader adds off the ends of the
|
|
130
|
+
* copy's holes, and records how much was taken, so that its lengths
|
|
131
|
+
* can be compared with a scanned copy's at all.
|
|
132
|
+
*/
|
|
133
|
+
export const shortenCopy = (copyId, extension) => onCopy(copyId, copy => shortenHoles(extension, copy));
|
|
134
|
+
/** Puts the reader's extension back on the copy's holes. */
|
|
135
|
+
export const unshortenCopy = (copyId) => onCopy(copyId, copy => revertShortening(copy));
|
|
128
136
|
/** States what the copy's features were read from, in place of any earlier statement. */
|
|
129
137
|
export const stateSource = (copyId, source) => onCopy(copyId, copy => {
|
|
130
138
|
copy.readFrom = source;
|
|
@@ -778,16 +786,29 @@ const readingOf = (symbol, carriers) => {
|
|
|
778
786
|
}
|
|
779
787
|
};
|
|
780
788
|
/** The symbol where the copy and at least one other carry it, with the carriers of each side. */
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
789
|
+
/**
|
|
790
|
+
* The symbol where the named copies and at least one other carry it,
|
|
791
|
+
* with the carriers of each side.
|
|
792
|
+
*
|
|
793
|
+
* A symbol the named copies alone carry has no other side to be
|
|
794
|
+
* separated from and is passed over. That covers the insertions, and it
|
|
795
|
+
* covers a symbol an ancestor holds on one branch's witness alone,
|
|
796
|
+
* where the two versions do not disagree and there is nothing to take
|
|
797
|
+
* apart.
|
|
798
|
+
*/
|
|
799
|
+
const sharedWith = (view, symbol, copies) => {
|
|
800
|
+
const onNamedCopy = (carrier) => {
|
|
801
|
+
const copy = view.copyOf(idOf(carrier));
|
|
802
|
+
return copy !== undefined && copies.has(copy.id);
|
|
803
|
+
};
|
|
804
|
+
const mine = symbol.carriers.filter(onNamedCopy);
|
|
805
|
+
const theirs = symbol.carriers.filter(carrier => !onNamedCopy(carrier));
|
|
785
806
|
return mine.length > 0 && theirs.length > 0 ? [{ symbol, mine, theirs }] : [];
|
|
786
807
|
};
|
|
787
808
|
/**
|
|
788
|
-
* Takes the
|
|
789
|
-
* collated into:
|
|
790
|
-
* version's own, the
|
|
809
|
+
* Takes the named copies' reading of a symbol back out of the symbol it
|
|
810
|
+
* was collated into: their carriers pass to a new symbol of the
|
|
811
|
+
* version's own, the remaining copies keep the symbol they had, and the
|
|
791
812
|
* version states the exchange.
|
|
792
813
|
*
|
|
793
814
|
* This is the inverse of the hand-over a collation makes, and it is
|
|
@@ -796,19 +817,26 @@ const sharedWith = (view, symbol, copyId) => {
|
|
|
796
817
|
* takes the two readings apart again, and without that a tolerance
|
|
797
818
|
* arrived at after the fact could never be applied.
|
|
798
819
|
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
820
|
+
* The copies named are one **side** of the derivation, the same side a
|
|
821
|
+
* window is measured over, and `sidesOf` is what says which they are.
|
|
822
|
+
* Naming one copy of a side that has several does not separate that
|
|
823
|
+
* side: what stays behind is the rest of it, mixed with the other
|
|
824
|
+
* side's copies, and a collation then compares one copy against that
|
|
825
|
+
* mixture rather than the two texts against each other.
|
|
826
|
+
*
|
|
827
|
+
* Symbols the named copies alone carry are already the version's own
|
|
828
|
+
* and are passed over, so a reading somebody has separated by hand
|
|
829
|
+
* keeps its identifier and the edit that speaks for it. Named symbols
|
|
830
|
+
* narrow the act to those; naming none separates the whole reading.
|
|
803
831
|
*/
|
|
804
|
-
export const separateReadings = (view, versionId,
|
|
832
|
+
export const separateReadings = (view, versionId, copies, symbolIds) => {
|
|
805
833
|
const version = view.get(versionId);
|
|
806
834
|
if (!version)
|
|
807
835
|
return noChange;
|
|
808
836
|
const chosen = symbolIds && new Set(symbolIds);
|
|
809
837
|
const shared = view.snapshot(versionId)
|
|
810
838
|
.filter(symbol => chosen === undefined || chosen.has(symbol.id))
|
|
811
|
-
.flatMap(symbol => sharedWith(view, symbol,
|
|
839
|
+
.flatMap(symbol => sharedWith(view, symbol, copies));
|
|
812
840
|
if (shared.length === 0)
|
|
813
841
|
return noChange;
|
|
814
842
|
const inserted = new Set(insertedBy(version).map(symbol => symbol.id));
|
|
@@ -20,16 +20,21 @@ import { Millimeters, Seconds } from "../Quantity.js";
|
|
|
20
20
|
* perforation, the height of the tracker bar hole and the paper speed
|
|
21
21
|
* (p. 180).
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
23
|
+
* Left in, that extension is not a difference between copies at all:
|
|
24
|
+
* the end of a hole here is a pneumatic on-time where the end of a
|
|
25
|
+
* scanned copy's hole is a punched slot, so a collation comparing the
|
|
26
|
+
* two reads the one as a lengthening of the other. `extension` takes it
|
|
27
|
+
* off at the end of every hole, and the copy records what was taken.
|
|
28
|
+
*
|
|
29
|
+
* How much to take off is measured rather than derived, since he gives
|
|
30
|
+
* only the 0.5 mm by which the Welte bar's holes exceed the Licensee's
|
|
31
|
+
* and not the absolute. Across welte225.org it comes to about 1.6 mm,
|
|
32
|
+
* and the shape of it is simple: a constant, not growing with the
|
|
33
|
+
* length of the perforation, with no shortest on-time the valve cannot
|
|
34
|
+
* fall below, and with no run along the roll that one roll's span of
|
|
35
|
+
* paper speed could show. The port that read it matters by about half a
|
|
36
|
+
* millimetre either way, without any gradient across the bar, which is
|
|
37
|
+
* measured but too coarse to model from one roll.
|
|
33
38
|
*/
|
|
34
39
|
/**
|
|
35
40
|
* He numbers his files by two rules at once, which his free samples
|
|
@@ -64,12 +69,25 @@ export interface PhillipsErollOptions {
|
|
|
64
69
|
* account for it.
|
|
65
70
|
*/
|
|
66
71
|
placeAt?: (elapsed: Seconds) => Millimeters;
|
|
72
|
+
/**
|
|
73
|
+
* How much longer a valve is held on than the perforation that
|
|
74
|
+
* opened it, taken off the end of every hole so that these lengths
|
|
75
|
+
* can be compared with a scanned copy's. Nothing leaves the holes
|
|
76
|
+
* as the reader reported them, which is what every copy read before
|
|
77
|
+
* this option existed states.
|
|
78
|
+
*
|
|
79
|
+
* The copy records what was taken, and `revertShortening` puts it
|
|
80
|
+
* back, so a figure revised later needs no second import. On
|
|
81
|
+
* welte225.org the extension measures about 1.6 mm, with no
|
|
82
|
+
* dependence on how long the perforation is.
|
|
83
|
+
*/
|
|
84
|
+
extension?: Millimeters;
|
|
67
85
|
}
|
|
68
86
|
/**
|
|
69
87
|
* Reads one of his e-roll files as a copy of the roll, in millimetres
|
|
70
88
|
* of paper, on the bar it was cut for and in that bar's numbering. A
|
|
71
89
|
* position the bar does not read is left out, as the bar would leave it.
|
|
72
90
|
*/
|
|
73
|
-
export declare function readFromPhillipsEroll(buffer: ArrayBuffer, { system, controlOffset, placeAt }?: PhillipsErollOptions): RollCopy;
|
|
91
|
+
export declare function readFromPhillipsEroll(buffer: ArrayBuffer, { system, controlOffset, placeAt, extension }?: PhillipsErollOptions): RollCopy;
|
|
74
92
|
/** The bars his files are known to be numbered by. */
|
|
75
93
|
export declare const phillipsSystems: readonly TrackerBar[];
|
|
@@ -2,6 +2,7 @@ import { read } from "midifile-ts";
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { assignObject } from "../Assumption.js";
|
|
4
4
|
import { systemOf } from "../TrackerBar.js";
|
|
5
|
+
import { shortenHoles } from "../alignment.js";
|
|
5
6
|
import { welteT100 } from "../systems/welteT100/bar.js";
|
|
6
7
|
import { welteLicensee } from "../systems/welteLicensee/bar.js";
|
|
7
8
|
import { inMetersPerMinute, mm, seconds, track } from "../Quantity.js";
|
|
@@ -24,16 +25,21 @@ import { inMetersPerMinute, mm, seconds, track } from "../Quantity.js";
|
|
|
24
25
|
* perforation, the height of the tracker bar hole and the paper speed
|
|
25
26
|
* (p. 180).
|
|
26
27
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
28
|
+
* Left in, that extension is not a difference between copies at all:
|
|
29
|
+
* the end of a hole here is a pneumatic on-time where the end of a
|
|
30
|
+
* scanned copy's hole is a punched slot, so a collation comparing the
|
|
31
|
+
* two reads the one as a lengthening of the other. `extension` takes it
|
|
32
|
+
* off at the end of every hole, and the copy records what was taken.
|
|
33
|
+
*
|
|
34
|
+
* How much to take off is measured rather than derived, since he gives
|
|
35
|
+
* only the 0.5 mm by which the Welte bar's holes exceed the Licensee's
|
|
36
|
+
* and not the absolute. Across welte225.org it comes to about 1.6 mm,
|
|
37
|
+
* and the shape of it is simple: a constant, not growing with the
|
|
38
|
+
* length of the perforation, with no shortest on-time the valve cannot
|
|
39
|
+
* fall below, and with no run along the roll that one roll's span of
|
|
40
|
+
* paper speed could show. The port that read it matters by about half a
|
|
41
|
+
* millimetre either way, without any gradient across the bar, which is
|
|
42
|
+
* measured but too coarse to model from one roll.
|
|
37
43
|
*/
|
|
38
44
|
/**
|
|
39
45
|
* He numbers his files by two rules at once, which his free samples
|
|
@@ -134,7 +140,7 @@ const positionsByPitch = (bar) => new Map(Array.from({ length: bar.trackCount },
|
|
|
134
140
|
* of paper, on the bar it was cut for and in that bar's numbering. A
|
|
135
141
|
* position the bar does not read is left out, as the bar would leave it.
|
|
136
142
|
*/
|
|
137
|
-
export function readFromPhillipsEroll(buffer, { system = welteT100, controlOffset, placeAt } = {}) {
|
|
143
|
+
export function readFromPhillipsEroll(buffer, { system = welteT100, controlOffset, placeAt, extension } = {}) {
|
|
138
144
|
const file = read(new Uint8Array(buffer));
|
|
139
145
|
const timed = onOneClock(file.tracks);
|
|
140
146
|
const elapsedAt = clockOf(temposIn(timed), file.header.ticksPerBeat);
|
|
@@ -157,7 +163,7 @@ export function readFromPhillipsEroll(buffer, { system = welteT100, controlOffse
|
|
|
157
163
|
}
|
|
158
164
|
}];
|
|
159
165
|
});
|
|
160
|
-
|
|
166
|
+
const copy = {
|
|
161
167
|
type: 'RollCopy',
|
|
162
168
|
id: v4(),
|
|
163
169
|
ops: [],
|
|
@@ -171,6 +177,9 @@ export function readFromPhillipsEroll(buffer, { system = welteT100, controlOffse
|
|
|
171
177
|
note: 'Read on Phillips’s pneumatic roll reader. The places are elapsed time put back onto the paper, and a hole runs as long as its switch stayed open, which is longer than the perforation.'
|
|
172
178
|
}
|
|
173
179
|
};
|
|
180
|
+
if (extension !== undefined)
|
|
181
|
+
shortenHoles(extension, copy);
|
|
182
|
+
return copy;
|
|
174
183
|
}
|
|
175
184
|
/** The bars his files are known to be numbered by. */
|
|
176
185
|
export const phillipsSystems = [welteT100, welteLicensee];
|
package/lib/schema.json
CHANGED
|
@@ -2828,6 +2828,10 @@
|
|
|
2828
2828
|
"description": "The average diameter of punched holes.",
|
|
2829
2829
|
"ontology": "reo:punchDiameter"
|
|
2830
2830
|
},
|
|
2831
|
+
"readerExtension": {
|
|
2832
|
+
"$ref": "#/definitions/Millimeters",
|
|
2833
|
+
"description": "How much longer this copy's reading of a hole ran than the perforation that caused it, where that was taken off the ends again. A pneumatic reader reports how long a valve stayed open, which exceeds the perforation that opened it, so its holes are overlong by a constant while its onsets agree. Nothing for a copy read by other means, whose holes are the punched slots themselves. Not exported to RDF."
|
|
2834
|
+
},
|
|
2831
2835
|
"scale": {
|
|
2832
2836
|
"description": "The factor this copy's features were scaled by to align them with the others. What it is put down to is stated apart: a paper-stretch condition, or the speed the copy was cut for. Not exported to RDF.",
|
|
2833
2837
|
"type": "number"
|
|
@@ -2861,7 +2865,8 @@
|
|
|
2861
2865
|
"items": {
|
|
2862
2866
|
"enum": [
|
|
2863
2867
|
"shifted",
|
|
2864
|
-
"stretched"
|
|
2868
|
+
"stretched",
|
|
2869
|
+
"shortened"
|
|
2865
2870
|
],
|
|
2866
2871
|
"type": "string"
|
|
2867
2872
|
},
|
package/lib/spec/context.json
CHANGED
package/package.json
CHANGED