linked-rolls 0.7.0 → 0.9.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.
@@ -1,5 +1,6 @@
1
1
  import { aperturePorts, CONSENSUS, DEFAULT_PUNCH_MM, geometryInMm, Grid, levelChanges, mezzoforteTravel, paperSeconds, pedalBrushing, pedalDefaults, pneumaticModel, PRESETS, ROWS_PER_MM, runPedals, TRACKER_BORE_MM, travelBetweenRails, WELTE_SPOOL, } from "welte-t100-emulator";
2
2
  import { welteT100 } from "./bar";
3
+ import { add, inCentimeters, mm, seconds, track } from "../../Quantity";
3
4
  /**
4
5
  * The instruments the emulator was fitted as: the consensus over the six
5
6
  * rolls with drawn nuance lines, and the setting that drew each of them,
@@ -35,9 +36,9 @@ export const defaultWelteT100Options = {
35
36
  pedals: pedalPresets.damping,
36
37
  velocity: { piano: 35, mezzoforte: 60, forte: 90 },
37
38
  pedalMode: 'continuous',
38
- trackerBore: TRACKER_BORE_MM,
39
- punchDiameter: DEFAULT_PUNCH_MM,
40
- division: 54
39
+ trackerBore: mm(TRACKER_BORE_MM),
40
+ punchDiameter: mm(DEFAULT_PUNCH_MM),
41
+ division: track(54)
41
42
  };
42
43
  /** What each expression code operates, in the emulator's terms. */
43
44
  const CODES = {
@@ -59,7 +60,7 @@ const CODES = {
59
60
  const isWelteT100ExpressionType = (type) => Object.hasOwn(CODES, type);
60
61
  const codeOf = (expressionType) => isWelteT100ExpressionType(expressionType) ? CODES[expressionType] : undefined;
61
62
  /** Paper the grid runs on past the last hole, so that a final pedal release completes. */
62
- const RUN_OUT_MM = 100;
63
+ const RUN_OUT = mm(100);
63
64
  /**
64
65
  * Which stack of valves an expression perforation belongs to. The symbol
65
66
  * usually says so, having been read off the tracker bar already; where it
@@ -74,9 +75,11 @@ const scopeOf = (event) => {
74
75
  };
75
76
  const isNote = (event) => event.type === 'note';
76
77
  const isExpression = (event) => event.type === 'expression';
77
- const rowOf = (mm) => mm * ROWS_PER_MM;
78
- /** When the spool brings a place on the roll, in mm, to the tracker bar. */
79
- export const secondsAt = (spool, mm) => paperSeconds(spool, mm / 10);
78
+ /** The row of the scan the constants were fitted on that a place on the roll falls in. */
79
+ const rowOf = (place) => place * ROWS_PER_MM;
80
+ const placeOfRow = (row) => mm(row / ROWS_PER_MM);
81
+ /** When the spool brings a place on the roll to the tracker bar. */
82
+ export const secondsAt = (spool, place) => seconds(paperSeconds(spool, inCentimeters(place)));
80
83
  const halfOf = (note, division) => note.vertical.from >= division ? 'treble' : 'bass';
81
84
  const readingOf = (event) => {
82
85
  const code = codeOf(event.expressionType);
@@ -108,10 +111,10 @@ const velocityOf = (travel, hook, map) => {
108
111
  * emulator expects.
109
112
  */
110
113
  const gridOver = (events, spool) => {
111
- const lastMm = events.reduce((furthest, event) => Math.max(furthest, event.horizontal.to), 0);
112
- const length = Math.ceil(rowOf(lastMm + RUN_OUT_MM)) + 1;
113
- const seconds = Float64Array.from({ length }, (_, row) => secondsAt(spool, row / ROWS_PER_MM));
114
- return new Grid(0, seconds);
114
+ const last = mm(events.reduce((furthest, event) => Math.max(furthest, event.horizontal.to), 0));
115
+ const length = Math.ceil(rowOf(add(last, RUN_OUT))) + 1;
116
+ const times = Float64Array.from({ length }, (_, row) => secondsAt(spool, placeOfRow(row)));
117
+ return new Grid(0, times);
115
118
  };
116
119
  const nuanceCurves = (grid, ports, samples, options) => {
117
120
  const curveOf = (half) => {
@@ -162,7 +165,7 @@ const performPedal = (type, curve, grid, readings, mode) => {
162
165
  type,
163
166
  performs: causeOf(grid.rowAt(change.index)),
164
167
  value: change.value,
165
- at: curve.seconds[change.index]
168
+ at: seconds(curve.seconds[change.index])
166
169
  }));
167
170
  };
168
171
  /**
@@ -179,7 +182,7 @@ const perform = (events, options, roll) => {
179
182
  const geometry = geometryInMm(roll.punchDiameter ?? options.punchDiameter, options.trackerBore);
180
183
  const ports = aperturePorts(grid, readings.map(reading => reading.punch), geometry);
181
184
  const samples = {
182
- place: Float64Array.from(grid.seconds, (_, row) => row / ROWS_PER_MM),
185
+ place: Float64Array.from(grid.seconds, (_, row) => placeOfRow(row)),
183
186
  seconds: grid.seconds
184
187
  };
185
188
  const nuance = nuanceCurves(grid, ports, samples, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linked-rolls",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Digital editions of piano rolls: import, collation, editorial assumptions, JSON-LD export, and emulation through a reproducing system",
5
5
  "license": "MIT",
6
6
  "repository": {