linked-rolls 0.65.0 → 0.67.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 +8 -0
- package/lib/analysis/paper.d.ts +28 -1
- package/lib/analysis/paper.js +60 -2
- package/lib/analysis/reservations.js +2 -2
- package/lib/emulation/Emulation.js +59 -4
- package/lib/io/migrate.js +67 -2
- package/lib/model/Agent.d.ts +17 -0
- package/lib/model/Assumption.d.ts +53 -8
- package/lib/model/Edition.d.ts +1 -8
- package/lib/model/FeatureSource.d.ts +2 -17
- package/lib/model/RollCopy.d.ts +44 -52
- package/lib/model/RollCopy.js +10 -0
- package/lib/model/Version.d.ts +30 -0
- package/lib/readers/stanfordAton.js +18 -13
- package/lib/schema.json +287 -200
- package/lib/spec/context.json +12 -15
- package/lib/systems/ReproducingSystem.d.ts +21 -28
- package/lib/systems/welte.d.ts +31 -7
- package/lib/systems/welte.js +37 -13
- package/lib/systems/welteLicensee/system.d.ts +10 -4
- package/lib/systems/welteLicensee/system.js +11 -5
- package/lib/systems/welteT100/system.d.ts +6 -5
- package/lib/systems/welteT100/system.js +7 -5
- package/lib/systems/welteT98/system.js +1 -0
- package/package.json +1 -1
package/lib/spec/context.json
CHANGED
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"used": {
|
|
90
90
|
"@id": "crm:P16_used_specific_object",
|
|
91
91
|
"@type": "@id"
|
|
92
|
+
},
|
|
93
|
+
"software": {
|
|
94
|
+
"@id": "crmdig:L23_used_software_or_firmware",
|
|
95
|
+
"@context": { "version": "owl:versionInfo" }
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
},
|
|
@@ -99,6 +103,13 @@
|
|
|
99
103
|
},
|
|
100
104
|
"creation": "lrmoo:R17i_was_created_by",
|
|
101
105
|
"procedure": "crm:P33_used_specific_technique",
|
|
106
|
+
"lengthRatio": {
|
|
107
|
+
"@id": "reo:lengthRatio",
|
|
108
|
+
"@context": {
|
|
109
|
+
"value": "crm:P90_has_value",
|
|
110
|
+
"uncertainty": "reo:uncertainty"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
102
113
|
"editors": "crm:P14_carried_out_by",
|
|
103
114
|
"publisher": "crm:P14_carried_out_by",
|
|
104
115
|
"publicationDate": {
|
|
@@ -139,13 +150,6 @@
|
|
|
139
150
|
"created": "lrmoo:R17_created",
|
|
140
151
|
"copies": "reo:witness",
|
|
141
152
|
"versions": "lrmoo:R75_incorporates",
|
|
142
|
-
"tempoAdjustment": {
|
|
143
|
-
"@id": "reo:tempo",
|
|
144
|
-
"@context": {
|
|
145
|
-
"startsWith": "reo:from",
|
|
146
|
-
"endsWith": "reo:to"
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
153
|
"name": "rdfs:label",
|
|
150
154
|
"sameAs": {
|
|
151
155
|
"@id": "owl:sameAs",
|
|
@@ -176,14 +180,7 @@
|
|
|
176
180
|
"height": "reo:height",
|
|
177
181
|
"holeSeparation": "reo:holeSeparation",
|
|
178
182
|
"scanResolution": "reo:scanResolution",
|
|
179
|
-
"value": "crm:P90_has_value"
|
|
180
|
-
"measuredBy": "crmdig:L23_used_software_or_firmware",
|
|
181
|
-
"software": "rdfs:label",
|
|
182
|
-
"version": "owl:versionInfo",
|
|
183
|
-
"date": {
|
|
184
|
-
"@id": "dcterms:date",
|
|
185
|
-
"@type": "xsd:date"
|
|
186
|
-
}
|
|
183
|
+
"value": "crm:P90_has_value"
|
|
187
184
|
}
|
|
188
185
|
},
|
|
189
186
|
"production": {
|
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
import { HoleChain } from "../model/Feature.js";
|
|
2
2
|
import { Expression, Note } from "../model/Symbol.js";
|
|
3
3
|
import { TrackerBar } from "./TrackerBar.js";
|
|
4
|
-
import {
|
|
5
|
-
export type SpeedUnit = 'ft/min' | 'm/min';
|
|
6
|
-
/**
|
|
7
|
-
* The playback tempo of the roll as a paper speed, stated at the
|
|
8
|
-
* beginning and at the end, since the speed may change over the
|
|
9
|
-
* course of the roll through acceleration.
|
|
10
|
-
* @see crm:E54 Dimension
|
|
11
|
-
*/
|
|
12
|
-
export interface RollTempoIn<U extends SpeedUnit> {
|
|
13
|
-
/**
|
|
14
|
-
* The tempo at the beginning of the roll.
|
|
15
|
-
* @see reo:from
|
|
16
|
-
*/
|
|
17
|
-
startsWith: Quantity<U>;
|
|
18
|
-
/**
|
|
19
|
-
* The tempo at the end of the roll.
|
|
20
|
-
* @see reo:to
|
|
21
|
-
*/
|
|
22
|
-
endsWith: Quantity<U>;
|
|
23
|
-
/**
|
|
24
|
-
* The unit of the tempo measurement.
|
|
25
|
-
* @see crm:P91 has unit
|
|
26
|
-
*/
|
|
27
|
-
unit: U;
|
|
28
|
-
}
|
|
29
|
-
export type RollTempo = RollTempoIn<'ft/min'> | RollTempoIn<'m/min'>;
|
|
4
|
+
import { MetersPerMinute, Millimeters, Seconds } from "../model/Quantity.js";
|
|
30
5
|
/**
|
|
31
6
|
* A note or expression of a version with the dimensions of its carriers
|
|
32
7
|
* averaged in and the editorial assumptions applied, which is all a
|
|
@@ -99,8 +74,26 @@ export type EmulatedCurve = DynamicsCurve | PedalCurve;
|
|
|
99
74
|
export type RollProperties = {
|
|
100
75
|
/** Diameter of the punches, where the copies record it. */
|
|
101
76
|
punchDiameter?: Millimeters;
|
|
102
|
-
/**
|
|
103
|
-
|
|
77
|
+
/**
|
|
78
|
+
* The speed the version's paper starts at, where the copies that bear
|
|
79
|
+
* witness to it state the speed they were cut for (`paperSpeedOf`), or
|
|
80
|
+
* failing them those of the version it derives from on the same
|
|
81
|
+
* system, whose paper it keeps. A stated speed is the speed at the
|
|
82
|
+
* beginning of the roll, as a tempo marking gives it, and the spool
|
|
83
|
+
* accelerates from there.
|
|
84
|
+
*/
|
|
85
|
+
paperSpeed?: MetersPerMinute;
|
|
86
|
+
/**
|
|
87
|
+
* Where the version is a re-cut for another system: how long its paper
|
|
88
|
+
* runs for a length of the paper of the version it derives from, and
|
|
89
|
+
* the speed stated for that version, if any. A system with no spool of
|
|
90
|
+
* its own times such a version by these, so that it sounds at the
|
|
91
|
+
* tempo of the roll it was re-cut from.
|
|
92
|
+
*/
|
|
93
|
+
recutFrom?: {
|
|
94
|
+
readonly lengthRatio: number;
|
|
95
|
+
readonly paperSpeed?: MetersPerMinute;
|
|
96
|
+
};
|
|
104
97
|
/**
|
|
105
98
|
* Place on the edition's shared axis × this = millimetres of the version's
|
|
106
99
|
* own paper, unstretched. About 0.775 for a green issue of a red
|
package/lib/systems/welte.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Grid, Half, Model, ModelInput, Parameters, PedalInput, PedalMode, PedalTravel, PortGeometry, Spool } from "welte-mignon-emulator";
|
|
2
2
|
import { Expression } from "../model/Symbol.js";
|
|
3
3
|
import { NegotiatedEvent, Performance, RollProperties } from "./ReproducingSystem.js";
|
|
4
|
-
import { Millimeters, Seconds, Track } from "../model/Quantity.js";
|
|
4
|
+
import { MetersPerMinute, Millimeters, Seconds, Track } from "../model/Quantity.js";
|
|
5
5
|
import { type VelocityMap } from "./velocity.js";
|
|
6
6
|
/**
|
|
7
7
|
* What the Welte systems share downstream of the relay. Hagmann has the
|
|
@@ -15,6 +15,9 @@ export type WelteOptions = {
|
|
|
15
15
|
/**
|
|
16
16
|
* The take-up spool, which sets the time axis: it is held at a constant
|
|
17
17
|
* rate of revolution, so the paper runs faster as the spool fills.
|
|
18
|
+
* Where a speed is stated for the version's copies, or a re-cut is timed
|
|
19
|
+
* by the roll it was made from, the spool is started at that speed and
|
|
20
|
+
* only its geometry is taken from here; see `spoolFor`.
|
|
18
21
|
*/
|
|
19
22
|
spool: Spool;
|
|
20
23
|
/** Constants of the nuancing mechanism, one set for each half of the keyboard. */
|
|
@@ -67,15 +70,33 @@ export declare const pedalPresetOf: (pedals: Parameters) => PedalPreset | undefi
|
|
|
67
70
|
*
|
|
68
71
|
* Rows are rows of the version's own paper, so the spool is asked in
|
|
69
72
|
* `paperOfRow` and never in `placeOfRow`: one is the paper that passes the
|
|
70
|
-
* tracker bar, the other is the coordinate the edition states.
|
|
73
|
+
* tracker bar, the other is the coordinate the edition states. A place is
|
|
74
|
+
* put to the spool through `paperOfPlace` for the same reason, so that a
|
|
75
|
+
* note sounds on the clock its pedal and bellows run on.
|
|
71
76
|
*/
|
|
72
77
|
export type Paper = {
|
|
73
78
|
readonly rowOf: (place: Millimeters) => number;
|
|
74
79
|
readonly placeOfRow: (row: number) => Millimeters;
|
|
75
80
|
readonly paperOfRow: (row: number) => Millimeters;
|
|
81
|
+
readonly paperOfPlace: (place: Millimeters) => Millimeters;
|
|
76
82
|
};
|
|
77
83
|
/** When the spool brings a place on the roll to the tracker bar. */
|
|
78
84
|
export declare const secondsAt: (spool: Spool, place: Millimeters) => Seconds;
|
|
85
|
+
/** The speed the spool starts the paper at. */
|
|
86
|
+
export declare const startingSpeedOf: (spool: Spool) => MetersPerMinute;
|
|
87
|
+
/**
|
|
88
|
+
* The spool a version runs on.
|
|
89
|
+
*
|
|
90
|
+
* A speed stated for the version's copies is where it starts, as a tempo
|
|
91
|
+
* marking is the speed at the beginning of the roll. Failing that, a system
|
|
92
|
+
* whose spool is a reading of its own instruments runs on it as it stands:
|
|
93
|
+
* the red and the green spool are both calibrated at Welte's Tempo 70. A
|
|
94
|
+
* system with no spool of its own, as the Licensee has none, times a re-cut
|
|
95
|
+
* by the roll it was re-cut from, at that roll's stated speed or else the
|
|
96
|
+
* spool's own, shortened by the length ratio, so that it sounds at the tempo
|
|
97
|
+
* of the original. Where none of this applies the spool stands as given.
|
|
98
|
+
*/
|
|
99
|
+
export declare const spoolFor: (spool: Spool, roll: RollProperties, ownSpool: boolean) => Spool;
|
|
79
100
|
/** A perforation as the emulator reads it: the control it operates and the rows it spans. */
|
|
80
101
|
export type WeltePunch = {
|
|
81
102
|
readonly half: Half;
|
|
@@ -98,6 +119,12 @@ export type Mechanism<P extends WeltePunch> = {
|
|
|
98
119
|
readonly portsOf: (grid: Grid, punches: readonly P[], geometry: PortGeometry) => Ports;
|
|
99
120
|
readonly model: Model;
|
|
100
121
|
readonly runPedals: (input: PedalInput, params: Parameters) => PedalTravel;
|
|
122
|
+
/**
|
|
123
|
+
* Whether the spool in the options is a reading of this system's own
|
|
124
|
+
* instruments. Where it is not, a re-cut is timed by the roll it was
|
|
125
|
+
* re-cut from (`spoolFor`).
|
|
126
|
+
*/
|
|
127
|
+
readonly ownSpool: boolean;
|
|
101
128
|
/** The name of the instrument the curves say they came from. */
|
|
102
129
|
readonly instrument: string;
|
|
103
130
|
};
|
|
@@ -108,10 +135,7 @@ export type WeltePerformance = Performance & {
|
|
|
108
135
|
};
|
|
109
136
|
/**
|
|
110
137
|
* Plays the events on a Welte mechanism: notes at the velocity of their half's
|
|
111
|
-
* bellows, and the two pedals as the travel of theirs
|
|
112
|
-
*
|
|
113
|
-
* The edition's tempo adjustment is left aside: it is stated as a paper
|
|
114
|
-
* speed, and what the spool holds constant is its rate of revolution, so
|
|
115
|
-
* the two are not the same quantity. The spool in the options sets the speed.
|
|
138
|
+
* bellows, and the two pedals as the travel of theirs, on the spool
|
|
139
|
+
* `spoolFor` gives the version.
|
|
116
140
|
*/
|
|
117
141
|
export declare const performWelte: <P extends WeltePunch>(events: readonly NegotiatedEvent[], options: WelteOptions, roll: RollProperties, mechanism: Mechanism<P>) => WeltePerformance;
|
package/lib/systems/welte.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { clamp, geometryInMm, Grid, levelChanges, mezzoforteTravel, paperSeconds, pedalBrushing, pedalDefaults, ROWS_PER_MM, travelBetweenRails, } from "welte-mignon-emulator";
|
|
2
|
-
import { inCentimeters, mm, seconds } from "../model/Quantity.js";
|
|
1
|
+
import { clamp, geometryInMm, Grid, levelChanges, mezzoforteTravel, paperSeconds, paperSpeed, pedalBrushing, pedalDefaults, ROWS_PER_MM, travelBetweenRails, } from "welte-mignon-emulator";
|
|
2
|
+
import { inCentimeters, metersPerMinute, mm, seconds } from "../model/Quantity.js";
|
|
3
3
|
import { partitionPoint } from "../shared/sorted.js";
|
|
4
4
|
import { velocityOf } from "./velocity.js";
|
|
5
5
|
/** Whether two sets of constants are the same, value for value. */
|
|
@@ -28,10 +28,35 @@ const isExpression = (event) => event.type === 'expression';
|
|
|
28
28
|
const paperOf = (toOwnPaper) => ({
|
|
29
29
|
rowOf: place => place * toOwnPaper * ROWS_PER_MM,
|
|
30
30
|
placeOfRow: row => mm(row / (toOwnPaper * ROWS_PER_MM)),
|
|
31
|
-
paperOfRow: row => mm(row / ROWS_PER_MM)
|
|
31
|
+
paperOfRow: row => mm(row / ROWS_PER_MM),
|
|
32
|
+
paperOfPlace: place => mm(place * toOwnPaper)
|
|
32
33
|
});
|
|
33
34
|
/** When the spool brings a place on the roll to the tracker bar. */
|
|
34
35
|
export const secondsAt = (spool, place) => seconds(paperSeconds(spool, inCentimeters(place)));
|
|
36
|
+
/** The speed the spool starts the paper at. */
|
|
37
|
+
export const startingSpeedOf = (spool) => metersPerMinute(paperSpeed(spool, 0) * 60 / 100);
|
|
38
|
+
/** The spool turned so that it starts the paper at the speed, its geometry and acceleration kept. */
|
|
39
|
+
const startingAt = (spool, speed) => ({ ...spool, revolutionSeconds: spool.circumferenceCm / (speed * 100 / 60) });
|
|
40
|
+
/**
|
|
41
|
+
* The spool a version runs on.
|
|
42
|
+
*
|
|
43
|
+
* A speed stated for the version's copies is where it starts, as a tempo
|
|
44
|
+
* marking is the speed at the beginning of the roll. Failing that, a system
|
|
45
|
+
* whose spool is a reading of its own instruments runs on it as it stands:
|
|
46
|
+
* the red and the green spool are both calibrated at Welte's Tempo 70. A
|
|
47
|
+
* system with no spool of its own, as the Licensee has none, times a re-cut
|
|
48
|
+
* by the roll it was re-cut from, at that roll's stated speed or else the
|
|
49
|
+
* spool's own, shortened by the length ratio, so that it sounds at the tempo
|
|
50
|
+
* of the original. Where none of this applies the spool stands as given.
|
|
51
|
+
*/
|
|
52
|
+
export const spoolFor = (spool, roll, ownSpool) => {
|
|
53
|
+
if (roll.paperSpeed !== undefined)
|
|
54
|
+
return startingAt(spool, roll.paperSpeed);
|
|
55
|
+
if (ownSpool || !roll.recutFrom)
|
|
56
|
+
return spool;
|
|
57
|
+
const { lengthRatio, paperSpeed: original = startingSpeedOf(spool) } = roll.recutFrom;
|
|
58
|
+
return startingAt(spool, metersPerMinute(original * lengthRatio));
|
|
59
|
+
};
|
|
35
60
|
const halfOf = (note, division) => note.vertical.from >= division ? 'treble' : 'bass';
|
|
36
61
|
/**
|
|
37
62
|
* One sample per row of the scan the constants were fitted on, from the
|
|
@@ -62,14 +87,15 @@ const nuanceCurves = (grid, ports, samples, options, model, instrument) => {
|
|
|
62
87
|
};
|
|
63
88
|
return { bass: curveOf('bass'), treble: curveOf('treble') };
|
|
64
89
|
};
|
|
65
|
-
const performNotes = (events, grid, nuance, options, paper) => events
|
|
90
|
+
const performNotes = (events, grid, nuance, options, paper, spool) => events
|
|
66
91
|
.filter(isNote)
|
|
67
92
|
.flatMap((note) => {
|
|
68
93
|
const curve = nuance[halfOf(note, options.division)];
|
|
69
94
|
const velocity = curve.velocity[grid.indexOfRow(paper.rowOf(note.horizontal.from))];
|
|
95
|
+
const at = (place) => secondsAt(spool, paper.paperOfPlace(place));
|
|
70
96
|
return [
|
|
71
|
-
{ type: 'noteOn', performs: note, pitch: note.pitch, velocity, at:
|
|
72
|
-
{ type: 'noteOff', performs: note, pitch: note.pitch, velocity: 127, at:
|
|
97
|
+
{ type: 'noteOn', performs: note, pitch: note.pitch, velocity, at: at(note.horizontal.from) },
|
|
98
|
+
{ type: 'noteOff', performs: note, pitch: note.pitch, velocity: 127, at: at(note.horizontal.to) }
|
|
73
99
|
];
|
|
74
100
|
});
|
|
75
101
|
/**
|
|
@@ -93,11 +119,8 @@ const performPedal = (type, curve, grid, readings, mode) => {
|
|
|
93
119
|
};
|
|
94
120
|
/**
|
|
95
121
|
* Plays the events on a Welte mechanism: notes at the velocity of their half's
|
|
96
|
-
* bellows, and the two pedals as the travel of theirs
|
|
97
|
-
*
|
|
98
|
-
* The edition's tempo adjustment is left aside: it is stated as a paper
|
|
99
|
-
* speed, and what the spool holds constant is its rate of revolution, so
|
|
100
|
-
* the two are not the same quantity. The spool in the options sets the speed.
|
|
122
|
+
* bellows, and the two pedals as the travel of theirs, on the spool
|
|
123
|
+
* `spoolFor` gives the version.
|
|
101
124
|
*/
|
|
102
125
|
export const performWelte = (events, options, roll, mechanism) => {
|
|
103
126
|
const paper = paperOf(roll.toOwnPaper ?? 1);
|
|
@@ -110,7 +133,8 @@ export const performWelte = (events, options, roll, mechanism) => {
|
|
|
110
133
|
});
|
|
111
134
|
return punch ? [{ event, punch }] : [];
|
|
112
135
|
});
|
|
113
|
-
const
|
|
136
|
+
const spool = spoolFor(options.spool, roll, mechanism.ownSpool);
|
|
137
|
+
const grid = gridOver(events, spool, paper);
|
|
114
138
|
const geometry = geometryInMm(roll.punchDiameter ?? options.punchDiameter, options.trackerBore);
|
|
115
139
|
const ports = mechanism.portsOf(grid, readings.map(reading => reading.punch), geometry);
|
|
116
140
|
const samples = {
|
|
@@ -126,7 +150,7 @@ export const performWelte = (events, options, roll, mechanism) => {
|
|
|
126
150
|
grid,
|
|
127
151
|
ports,
|
|
128
152
|
events: [
|
|
129
|
-
...performNotes(events, grid, nuance, options, paper),
|
|
153
|
+
...performNotes(events, grid, nuance, options, paper, spool),
|
|
130
154
|
...performPedal('damper', damper, grid, readingsOf('sustainPedal'), options.pedalMode),
|
|
131
155
|
...performPedal('hammerRail', hammerRail, grid, readingsOf('hammerRail'), options.pedalMode)
|
|
132
156
|
],
|
|
@@ -27,9 +27,13 @@ export declare const instrumentNames: readonly WelteLicenseeInstrumentName[];
|
|
|
27
27
|
* Welte's own spool is carried over with the constants. Phillips (p. 181) says
|
|
28
28
|
* Licensee rolls "play at a range of paper speeds", so there is no one figure
|
|
29
29
|
* to put here and the red geometry is a placeholder rather than a reading.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* It is therefore never played as it stands where anything better is known:
|
|
31
|
+
* a speed stated for the version's copies, as a Licensee label states its
|
|
32
|
+
* tempo, sets where it starts, and failing that a re-cut runs at the speed of
|
|
33
|
+
* the roll it was re-cut from times the length ratio, so that it sounds at
|
|
34
|
+
* that roll's tempo (`spoolFor`). Either way only its geometry is used, and
|
|
35
|
+
* that is better varied than trusted: it scales every conductance by k and
|
|
36
|
+
* every time constant by 1/k, and touches nothing dimensionless.
|
|
33
37
|
*/
|
|
34
38
|
export declare const defaultWelteLicenseeOptions: WelteLicenseeOptions;
|
|
35
39
|
/**
|
|
@@ -41,6 +45,8 @@ export declare const defaultWelteLicenseeOptions: WelteLicenseeOptions;
|
|
|
41
45
|
* What it does not have is an instrument of its own. The constants are the
|
|
42
46
|
* T-100's, the spool is the T-100's, and neither has ever been checked against
|
|
43
47
|
* a Licensee. `instruments` therefore offers a single `unfitted` arm, and every
|
|
44
|
-
* curve produced here names itself as such.
|
|
48
|
+
* curve produced here names itself as such. The spool sets no tempo of its
|
|
49
|
+
* own: a version runs at the speed stated for its copies, or at that of the
|
|
50
|
+
* roll it was re-cut from times the length ratio.
|
|
45
51
|
*/
|
|
46
52
|
export declare const welteLicenseeSystem: ReproducingSystem<WelteLicenseeOptions>;
|
|
@@ -23,9 +23,13 @@ export const instrumentNames = [
|
|
|
23
23
|
* Welte's own spool is carried over with the constants. Phillips (p. 181) says
|
|
24
24
|
* Licensee rolls "play at a range of paper speeds", so there is no one figure
|
|
25
25
|
* to put here and the red geometry is a placeholder rather than a reading.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* It is therefore never played as it stands where anything better is known:
|
|
27
|
+
* a speed stated for the version's copies, as a Licensee label states its
|
|
28
|
+
* tempo, sets where it starts, and failing that a re-cut runs at the speed of
|
|
29
|
+
* the roll it was re-cut from times the length ratio, so that it sounds at
|
|
30
|
+
* that roll's tempo (`spoolFor`). Either way only its geometry is used, and
|
|
31
|
+
* that is better varied than trusted: it scales every conductance by k and
|
|
32
|
+
* every time constant by 1/k, and touches nothing dimensionless.
|
|
29
33
|
*/
|
|
30
34
|
export const defaultWelteLicenseeOptions = {
|
|
31
35
|
...defaultWelteT100Options,
|
|
@@ -50,11 +54,13 @@ const licenseeInstrument = (nuance) => instrumentNameOf(nuance) === 'consensus'
|
|
|
50
54
|
* What it does not have is an instrument of its own. The constants are the
|
|
51
55
|
* T-100's, the spool is the T-100's, and neither has ever been checked against
|
|
52
56
|
* a Licensee. `instruments` therefore offers a single `unfitted` arm, and every
|
|
53
|
-
* curve produced here names itself as such.
|
|
57
|
+
* curve produced here names itself as such. The spool sets no tempo of its
|
|
58
|
+
* own: a version runs at the speed stated for its copies, or at that of the
|
|
59
|
+
* roll it was re-cut from times the length ratio.
|
|
54
60
|
*/
|
|
55
61
|
export const welteLicenseeSystem = {
|
|
56
62
|
name: 'Welte-Mignon (Licensee)',
|
|
57
63
|
trackerBar: welteLicensee,
|
|
58
64
|
defaultOptions: defaultWelteLicenseeOptions,
|
|
59
|
-
perform: performAs(licenseeInstrument)
|
|
65
|
+
perform: performAs(licenseeInstrument, false)
|
|
60
66
|
};
|
|
@@ -24,12 +24,13 @@ export type WelteT100Options = WelteOptions;
|
|
|
24
24
|
export declare const defaultWelteT100Options: WelteT100Options;
|
|
25
25
|
/**
|
|
26
26
|
* The mechanism, given a way of naming the instrument on the curves it
|
|
27
|
-
* produces
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* curve has to say
|
|
27
|
+
* produces and whether the spool it is given is that instrument's own. The
|
|
28
|
+
* Licensee reads the same commands and is played by the same valves, so it
|
|
29
|
+
* shares this; what it may not share is the name, since a Licensee playback
|
|
30
|
+
* runs on constants fitted to Freiburg instruments and the curve has to say
|
|
31
|
+
* so, nor the spool, which is the red one it carries over.
|
|
31
32
|
*/
|
|
32
|
-
export declare const performAs: (instrumentOf: (nuance: Record<Half, Parameters>) => string) => (events: readonly NegotiatedEvent[], options: WelteT100Options, roll: RollProperties) => Performance;
|
|
33
|
+
export declare const performAs: (instrumentOf: (nuance: Record<Half, Parameters>) => string, ownSpool?: boolean) => (events: readonly NegotiatedEvent[], options: WelteT100Options, roll: RollProperties) => Performance;
|
|
33
34
|
/**
|
|
34
35
|
* The red Welte, as welte-mignon-emulator models it: the take-up spool sets
|
|
35
36
|
* the time axis, the Nuancierbälge fill through their conduits and are
|
|
@@ -55,17 +55,19 @@ const punchOf = (event, rows) => {
|
|
|
55
55
|
};
|
|
56
56
|
/**
|
|
57
57
|
* The mechanism, given a way of naming the instrument on the curves it
|
|
58
|
-
* produces
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* curve has to say
|
|
58
|
+
* produces and whether the spool it is given is that instrument's own. The
|
|
59
|
+
* Licensee reads the same commands and is played by the same valves, so it
|
|
60
|
+
* shares this; what it may not share is the name, since a Licensee playback
|
|
61
|
+
* runs on constants fitted to Freiburg instruments and the curve has to say
|
|
62
|
+
* so, nor the spool, which is the red one it carries over.
|
|
62
63
|
*/
|
|
63
|
-
export const performAs = (instrumentOf) => (events, options, roll) => {
|
|
64
|
+
export const performAs = (instrumentOf, ownSpool = true) => (events, options, roll) => {
|
|
64
65
|
const { events: performed, curves } = performWelte(events, options, roll, {
|
|
65
66
|
punchOf,
|
|
66
67
|
portsOf: aperturePorts,
|
|
67
68
|
model: pneumaticModel,
|
|
68
69
|
runPedals,
|
|
70
|
+
ownSpool,
|
|
69
71
|
instrument: instrumentOf(options.nuance)
|
|
70
72
|
});
|
|
71
73
|
return { events: performed, curves };
|
|
@@ -110,6 +110,7 @@ const perform = (events, options, roll) => {
|
|
|
110
110
|
portsOf: (grid, punches, geometry) => aperturePorts(grid, punches, geometry, gap),
|
|
111
111
|
model: pneumaticT98Model,
|
|
112
112
|
runPedals,
|
|
113
|
+
ownSpool: true,
|
|
113
114
|
instrument: `Welte-Mignon T-98, ${labelOf(options.instrument)}`
|
|
114
115
|
});
|
|
115
116
|
const stops = rewindRow(grid, ports, options);
|
package/package.json
CHANGED