rlo-engine 1.0.3 → 1.1.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 +15 -4
- package/dist/Core/AudioMath.d.ts +29 -0
- package/dist/Core/AudioMath.d.ts.map +1 -0
- package/dist/Core/AudioMath.js +64 -0
- package/dist/Core/AudioMath.js.map +1 -0
- package/dist/Core/InstrumentMap.d.ts +36 -0
- package/dist/Core/InstrumentMap.d.ts.map +1 -0
- package/dist/Core/InstrumentMap.js +62 -0
- package/dist/Core/InstrumentMap.js.map +1 -0
- package/dist/Core/RLOCore.d.ts +49 -0
- package/dist/Core/RLOCore.d.ts.map +1 -0
- package/dist/Core/RLOCore.js +188 -0
- package/dist/Core/RLOCore.js.map +1 -0
- package/dist/Core/SequenceBuilder.d.ts +23 -0
- package/dist/Core/SequenceBuilder.d.ts.map +1 -0
- package/dist/Core/SequenceBuilder.js +31 -0
- package/dist/Core/SequenceBuilder.js.map +1 -0
- package/dist/Instruments/Analog/AnalogSynthBase.d.ts +17 -7
- package/dist/Instruments/Analog/AnalogSynthBase.d.ts.map +1 -1
- package/dist/Instruments/Analog/AnalogSynthBase.js +27 -16
- package/dist/Instruments/Analog/AnalogSynthBase.js.map +1 -1
- package/dist/Instruments/Analog/BassSynth.d.ts +12 -5
- package/dist/Instruments/Analog/BassSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/BassSynth.js +17 -10
- package/dist/Instruments/Analog/BassSynth.js.map +1 -1
- package/dist/Instruments/Analog/ChiptuneSynth.d.ts +11 -4
- package/dist/Instruments/Analog/ChiptuneSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/ChiptuneSynth.js +12 -5
- package/dist/Instruments/Analog/ChiptuneSynth.js.map +1 -1
- package/dist/Instruments/Analog/FMSynth.d.ts +11 -4
- package/dist/Instruments/Analog/FMSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/FMSynth.js +14 -7
- package/dist/Instruments/Analog/FMSynth.js.map +1 -1
- package/dist/Instruments/Analog/FormantSynth.d.ts +11 -4
- package/dist/Instruments/Analog/FormantSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/FormantSynth.js +12 -5
- package/dist/Instruments/Analog/FormantSynth.js.map +1 -1
- package/dist/Instruments/Analog/LeadSynth.d.ts +11 -4
- package/dist/Instruments/Analog/LeadSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/LeadSynth.js +14 -7
- package/dist/Instruments/Analog/LeadSynth.js.map +1 -1
- package/dist/Instruments/Analog/OrganSynth.d.ts +11 -4
- package/dist/Instruments/Analog/OrganSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/OrganSynth.js +17 -10
- package/dist/Instruments/Analog/OrganSynth.js.map +1 -1
- package/dist/Instruments/Analog/PadSynth.js +7 -7
- package/dist/Instruments/Analog/PadSynth.js.map +1 -1
- package/dist/Instruments/Analog/ReeseBassSynth.d.ts +11 -4
- package/dist/Instruments/Analog/ReeseBassSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/ReeseBassSynth.js +13 -6
- package/dist/Instruments/Analog/ReeseBassSynth.js.map +1 -1
- package/dist/Instruments/Analog/StringSynth.js +4 -4
- package/dist/Instruments/Analog/StringSynth.js.map +1 -1
- package/dist/Instruments/Analog/WoodwindSynth.d.ts +11 -4
- package/dist/Instruments/Analog/WoodwindSynth.d.ts.map +1 -1
- package/dist/Instruments/Analog/WoodwindSynth.js +19 -12
- package/dist/Instruments/Analog/WoodwindSynth.js.map +1 -1
- package/dist/Instruments/CoreSynthBase.d.ts +31 -24
- package/dist/Instruments/CoreSynthBase.d.ts.map +1 -1
- package/dist/Instruments/CoreSynthBase.js +53 -34
- package/dist/Instruments/CoreSynthBase.js.map +1 -1
- package/dist/Instruments/Decay/AdditiveSynth.d.ts +12 -5
- package/dist/Instruments/Decay/AdditiveSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/AdditiveSynth.js +9 -2
- package/dist/Instruments/Decay/AdditiveSynth.js.map +1 -1
- package/dist/Instruments/Decay/BrassSynth.d.ts +11 -4
- package/dist/Instruments/Decay/BrassSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/BrassSynth.js +22 -15
- package/dist/Instruments/Decay/BrassSynth.js.map +1 -1
- package/dist/Instruments/Decay/ChromaticPercussionSynth.d.ts +12 -5
- package/dist/Instruments/Decay/ChromaticPercussionSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/ChromaticPercussionSynth.js +16 -9
- package/dist/Instruments/Decay/ChromaticPercussionSynth.js.map +1 -1
- package/dist/Instruments/Decay/DecaySynthBase.d.ts +14 -8
- package/dist/Instruments/Decay/DecaySynthBase.d.ts.map +1 -1
- package/dist/Instruments/Decay/DecaySynthBase.js +22 -15
- package/dist/Instruments/Decay/DecaySynthBase.js.map +1 -1
- package/dist/Instruments/Decay/ElectricGuitarSynth.d.ts +12 -5
- package/dist/Instruments/Decay/ElectricGuitarSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/ElectricGuitarSynth.js +19 -12
- package/dist/Instruments/Decay/ElectricGuitarSynth.js.map +1 -1
- package/dist/Instruments/Decay/EthnicSynth.d.ts +12 -5
- package/dist/Instruments/Decay/EthnicSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/EthnicSynth.js +13 -6
- package/dist/Instruments/Decay/EthnicSynth.js.map +1 -1
- package/dist/Instruments/Decay/GuitarSynth.d.ts +12 -5
- package/dist/Instruments/Decay/GuitarSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/GuitarSynth.js +14 -7
- package/dist/Instruments/Decay/GuitarSynth.js.map +1 -1
- package/dist/Instruments/Decay/KarplusSynth.d.ts +7 -0
- package/dist/Instruments/Decay/KarplusSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/KarplusSynth.js +16 -8
- package/dist/Instruments/Decay/KarplusSynth.js.map +1 -1
- package/dist/Instruments/Decay/PianoSynth.d.ts +12 -5
- package/dist/Instruments/Decay/PianoSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/PianoSynth.js +19 -12
- package/dist/Instruments/Decay/PianoSynth.js.map +1 -1
- package/dist/Instruments/Decay/SlapBassSynth.d.ts +12 -5
- package/dist/Instruments/Decay/SlapBassSynth.d.ts.map +1 -1
- package/dist/Instruments/Decay/SlapBassSynth.js +13 -6
- package/dist/Instruments/Decay/SlapBassSynth.js.map +1 -1
- package/dist/Instruments/ISynthInstrument.d.ts +6 -0
- package/dist/Instruments/ISynthInstrument.d.ts.map +1 -1
- package/dist/Instruments/Speciality/DrumSynth.d.ts +7 -0
- package/dist/Instruments/Speciality/DrumSynth.d.ts.map +1 -1
- package/dist/Instruments/Speciality/DrumSynth.js +30 -21
- package/dist/Instruments/Speciality/DrumSynth.js.map +1 -1
- package/dist/Instruments/Speciality/SoundEffectsSynth.d.ts +7 -0
- package/dist/Instruments/Speciality/SoundEffectsSynth.d.ts.map +1 -1
- package/dist/Instruments/Speciality/SoundEffectsSynth.js +20 -12
- package/dist/Instruments/Speciality/SoundEffectsSynth.js.map +1 -1
- package/dist/Instruments/Synthesizer.d.ts +5 -0
- package/dist/Instruments/Synthesizer.d.ts.map +1 -1
- package/dist/Instruments/Synthesizer.js +7 -1
- package/dist/Instruments/Synthesizer.js.map +1 -1
- package/dist/Players/RLOGameEngine.d.ts +35 -0
- package/dist/Players/RLOGameEngine.d.ts.map +1 -0
- package/dist/Players/RLOGameEngine.js +98 -0
- package/dist/Players/RLOGameEngine.js.map +1 -0
- package/dist/Players/RLOMusicPlayer.d.ts +35 -0
- package/dist/Players/RLOMusicPlayer.d.ts.map +1 -0
- package/dist/Players/RLOMusicPlayer.js +167 -0
- package/dist/Players/RLOMusicPlayer.js.map +1 -0
- package/dist/RLO-Transpiler.d.ts +37 -15
- package/dist/RLO-Transpiler.d.ts.map +1 -1
- package/dist/RLO-Transpiler.js +139 -117
- package/dist/RLO-Transpiler.js.map +1 -1
- package/dist/compiler.d.ts +50 -31
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +165 -230
- package/dist/compiler.js.map +1 -1
- package/dist/crush.d.ts +1 -5
- package/dist/crush.d.ts.map +1 -1
- package/dist/crush.js +10 -3
- package/dist/crush.js.map +1 -1
- package/dist/index.d.ts +15 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/midi-parser.d.ts +14 -0
- package/dist/midi-parser.d.ts.map +1 -1
- package/dist/midi-parser.js +21 -0
- package/dist/midi-parser.js.map +1 -1
- package/dist/rlo-engine.min.js +441 -439
- package/dist/rlo-engine.min.js.map +1 -1
- package/dist/rlo-engine.min.umd.js +1 -1
- package/dist/rlo-engine.min.umd.js.map +1 -1
- package/dist/types.d.ts +21 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -1
- package/dist/vite.config.d.ts.map +1 -1
- package/dist/vite.config.js +16 -3
- package/dist/vite.config.js.map +1 -1
- package/dist/vite.config.js13k.d.ts.map +1 -1
- package/dist/vite.config.js13k.js +1 -0
- package/dist/vite.config.js13k.js.map +1 -1
- package/package.json +1 -1
- package/dist/Instruments/InstrumentFactory.d.ts +0 -2
- package/dist/Instruments/InstrumentFactory.d.ts.map +0 -1
- package/dist/Instruments/InstrumentFactory.js +0 -4
- package/dist/Instruments/InstrumentFactory.js.map +0 -1
- package/dist/RLO-Player.d.ts +0 -298
- package/dist/RLO-Player.d.ts.map +0 -1
- package/dist/RLO-Player.js +0 -724
- package/dist/RLO-Player.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { RLOCore } from "../Core/RLOCore.js";
|
|
2
|
+
import { AudioEffects } from "../AudioEffects.js";
|
|
3
|
+
import { decodeBinary } from "../RLO-Transpiler.js";
|
|
4
|
+
const hasMusicPlayer = typeof __ENABLE_MUSIC_PLAYER__ !== "undefined" ? __ENABLE_MUSIC_PLAYER__ : true;
|
|
5
|
+
const hasWorkerMetronome = typeof __ENABLE_WORKER_METRONOME__ !== "undefined" ? __ENABLE_WORKER_METRONOME__ : false;
|
|
6
|
+
/**
|
|
7
|
+
* A specialized extension of `RLOCore` designed for standalone music playback.
|
|
8
|
+
*
|
|
9
|
+
* @reason Architecture Separation:
|
|
10
|
+
* The base `RLOCore` is extremely lightweight and purely handles scheduling logic.
|
|
11
|
+
* `RLOMusicPlayer` adds heavy features like Convolution Reverb routing, URL fetching,
|
|
12
|
+
* binary decompression streams, and track caching. By separating these into a derived class,
|
|
13
|
+
* JS13k game developers who just want to play simple 1-channel blips don't have to bundle
|
|
14
|
+
* the gzip DecompressionStream or Convolution Reverb code.
|
|
15
|
+
*/
|
|
16
|
+
export class RLOMusicPlayer extends RLOCore {
|
|
17
|
+
constructor(audioContext, instrumentMap = []) {
|
|
18
|
+
super(audioContext, instrumentMap);
|
|
19
|
+
this._masterGainNode = null;
|
|
20
|
+
this._reverbNode = null;
|
|
21
|
+
this._fxGainNode = null;
|
|
22
|
+
this._trackCacheMap = new Map();
|
|
23
|
+
this._maxCacheSizeLimit = 20;
|
|
24
|
+
this._currentReverbMode = "concert";
|
|
25
|
+
if (!hasMusicPlayer)
|
|
26
|
+
return;
|
|
27
|
+
AudioEffects._generateReverb(this._ctx, "concert");
|
|
28
|
+
AudioEffects._generateReverb(this._ctx, "studio");
|
|
29
|
+
this._visibilityEventHandler = () => {
|
|
30
|
+
if (document.hidden) {
|
|
31
|
+
this._ctx.suspend();
|
|
32
|
+
}
|
|
33
|
+
else if (this._isPlaying) {
|
|
34
|
+
this._ctx.resume();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
if (typeof document !== "undefined" && !hasWorkerMetronome) {
|
|
38
|
+
document.addEventListener("visibilitychange", this._visibilityEventHandler);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
setReverbMode(mode) {
|
|
42
|
+
if (!hasMusicPlayer)
|
|
43
|
+
return;
|
|
44
|
+
this._currentReverbMode = mode;
|
|
45
|
+
if (this._reverbNode && this._fxGainNode) {
|
|
46
|
+
this._reverbNode.buffer = AudioEffects._generateReverb(this._ctx, mode);
|
|
47
|
+
this._fxGainNode.gain.setTargetAtTime(mode === "studio" ? 0.05 : 0.2, this._now, 0.1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
dispose() {
|
|
51
|
+
if (!hasMusicPlayer)
|
|
52
|
+
return super.dispose();
|
|
53
|
+
super.dispose();
|
|
54
|
+
if (typeof document !== "undefined" && !hasWorkerMetronome) {
|
|
55
|
+
document.removeEventListener("visibilitychange", this._visibilityEventHandler);
|
|
56
|
+
}
|
|
57
|
+
this._trackCacheMap.clear();
|
|
58
|
+
}
|
|
59
|
+
setVolume(vol) {
|
|
60
|
+
super.setVolume(vol);
|
|
61
|
+
if (!hasMusicPlayer)
|
|
62
|
+
return;
|
|
63
|
+
if (this._masterGainNode) {
|
|
64
|
+
this._masterGainNode.gain.setTargetAtTime(vol, this._now, 0.1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
getCurrentTime() {
|
|
68
|
+
if (!hasMusicPlayer)
|
|
69
|
+
return 0;
|
|
70
|
+
if (this._trkD === 0 || !this._isPlaying)
|
|
71
|
+
return 0;
|
|
72
|
+
return Math.max(0, this._trkT) % this._trkD;
|
|
73
|
+
}
|
|
74
|
+
getTotalDuration() {
|
|
75
|
+
if (!hasMusicPlayer)
|
|
76
|
+
return 0;
|
|
77
|
+
return this._trkD;
|
|
78
|
+
}
|
|
79
|
+
_createRouting(fadeInTime = 0) {
|
|
80
|
+
if (!hasMusicPlayer)
|
|
81
|
+
return super._createRouting(fadeInTime);
|
|
82
|
+
this._reverbNode = this._ctx.createConvolver();
|
|
83
|
+
this._reverbNode.buffer = AudioEffects._generateReverb(this._ctx, this._currentReverbMode);
|
|
84
|
+
this._masterGainNode = this._createGain();
|
|
85
|
+
this._activeNodes.push(this._reverbNode, this._masterGainNode);
|
|
86
|
+
this._applyLinearFade(this._masterGainNode.gain, this._volume, fadeInTime);
|
|
87
|
+
this._fxGainNode = this._createGain();
|
|
88
|
+
this._fxGainNode.gain.value = this._currentReverbMode === "studio" ? 0.05 : 0.2;
|
|
89
|
+
this._activeNodes.push(this._fxGainNode);
|
|
90
|
+
const masterFilter = this._ctx.createBiquadFilter();
|
|
91
|
+
masterFilter.type = "lowpass";
|
|
92
|
+
masterFilter.frequency.value = Math.min(this._ctx.sampleRate / 2 - 1, 6500);
|
|
93
|
+
this._activeNodes.push(masterFilter);
|
|
94
|
+
const compressor = this._createCompressor();
|
|
95
|
+
this._activeNodes.push(compressor);
|
|
96
|
+
this._masterGainNode.connect(masterFilter).connect(compressor).connect(this._ctx.destination);
|
|
97
|
+
this._masterGainNode.connect(this._reverbNode).connect(this._fxGainNode).connect(masterFilter);
|
|
98
|
+
return { destination: this._masterGainNode };
|
|
99
|
+
}
|
|
100
|
+
async play(trackUrlOrData, fadeInOrOpts = 0, oldLoop = true) {
|
|
101
|
+
if (!hasMusicPlayer)
|
|
102
|
+
return;
|
|
103
|
+
let track;
|
|
104
|
+
let fadeInTime = 0;
|
|
105
|
+
let optionsObj = {};
|
|
106
|
+
if (typeof fadeInOrOpts === "object") {
|
|
107
|
+
fadeInTime = fadeInOrOpts.fadeInTime ?? 0;
|
|
108
|
+
optionsObj = fadeInOrOpts;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
fadeInTime = fadeInOrOpts;
|
|
112
|
+
optionsObj = { fadeInTime, loop: oldLoop };
|
|
113
|
+
}
|
|
114
|
+
if (typeof trackUrlOrData === "string") {
|
|
115
|
+
if (this._trackCacheMap.has(trackUrlOrData)) {
|
|
116
|
+
track = this._trackCacheMap.get(trackUrlOrData);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const response = await fetch(trackUrlOrData);
|
|
120
|
+
const hasTranspiler = typeof window.__ENABLE_TRANSPILER__ !== "undefined" ? window.__ENABLE_TRANSPILER__ : true;
|
|
121
|
+
if (!hasTranspiler || trackUrlOrData.toLowerCase().endsWith(".json")) {
|
|
122
|
+
const text = await response.text();
|
|
123
|
+
track = JSON.parse(text);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const rawBuffer = await response.arrayBuffer();
|
|
127
|
+
const view = new DataView(rawBuffer);
|
|
128
|
+
const isDecompressed = view.byteLength >= 3 && view.getUint8(0) === 82 && view.getUint8(1) === 76 && view.getUint8(2) === 79;
|
|
129
|
+
if (isDecompressed) {
|
|
130
|
+
track = decodeBinary(rawBuffer);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const ds = new window.DecompressionStream("gzip");
|
|
134
|
+
const writer = ds.writable.getWriter();
|
|
135
|
+
writer.write(rawBuffer);
|
|
136
|
+
writer.close();
|
|
137
|
+
track = decodeBinary(await new Response(ds.readable).arrayBuffer());
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
this._trackCacheMap.set(trackUrlOrData, track);
|
|
141
|
+
if (this._trackCacheMap.size > this._maxCacheSizeLimit) {
|
|
142
|
+
const firstKey = this._trackCacheMap.keys().next().value;
|
|
143
|
+
if (firstKey)
|
|
144
|
+
this._trackCacheMap.delete(firstKey);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
track = trackUrlOrData;
|
|
150
|
+
}
|
|
151
|
+
this.playSequence(track, optionsObj);
|
|
152
|
+
}
|
|
153
|
+
stop() {
|
|
154
|
+
if (!hasMusicPlayer)
|
|
155
|
+
return super.stop();
|
|
156
|
+
if (this._masterGainNode) {
|
|
157
|
+
const now = this._now;
|
|
158
|
+
this._masterGainNode.gain.cancelScheduledValues(now);
|
|
159
|
+
this._masterGainNode.gain.setValueAtTime(0, now);
|
|
160
|
+
this._masterGainNode = null;
|
|
161
|
+
this._fxGainNode = null;
|
|
162
|
+
this._reverbNode = null;
|
|
163
|
+
}
|
|
164
|
+
super.stop();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=RLOMusicPlayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RLOMusicPlayer.js","sourceRoot":"","sources":["../../Players/RLOMusicPlayer.ts"],"names":[],"mappings":"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"}
|
package/dist/RLO-Transpiler.d.ts
CHANGED
|
@@ -3,20 +3,42 @@ import { RloData } from "./types.js";
|
|
|
3
3
|
* Universal translator for handling RLO data formats.
|
|
4
4
|
* Converts between Human AoS (Array of Structures), Intermediate SoA (Structure of Arrays),
|
|
5
5
|
* and highly compressed binary buffers.
|
|
6
|
+
*
|
|
7
|
+
* @reason Why Structure of Arrays (SoA) and Delta-Time?
|
|
8
|
+
* By decoupling a note into flat typed arrays (time, duration, frequency, velocity, instrument)
|
|
9
|
+
* we allow gzip/deflate algorithms to identify massive byte repetition. For example, if a
|
|
10
|
+
* hi-hat plays on the exact same instrument ID and velocity for 50 notes, SoA groups those 50
|
|
11
|
+
* identical bytes contiguously in memory, allowing gzip to compress them down to literally 1 or 2 bytes.
|
|
12
|
+
* Converting absolute time to delta-time serves the same purpose: instead of constantly increasing
|
|
13
|
+
* time signatures, rhythmic music will yield contiguous identical delta-time bytes which gzip dominates.
|
|
6
14
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Converts standard interleaved JSON into Delta-Timed Structure of Arrays.
|
|
17
|
+
* @param humanJson The flat-packed JSON array.
|
|
18
|
+
* @param fullRangeFreq If true, writes raw 32-bit floats. If false, aggressively quantizes to 8-bit MIDI scale.
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodeToSoA(humanJson: RloData, fullRangeFreq?: boolean): {
|
|
21
|
+
durationSecs: number;
|
|
22
|
+
f: Float32Array<ArrayBuffer> | Uint8Array<ArrayBuffer>;
|
|
23
|
+
t: Uint16Array<ArrayBuffer>;
|
|
24
|
+
d: Uint16Array<ArrayBuffer>;
|
|
25
|
+
v: Uint8Array<ArrayBuffer>;
|
|
26
|
+
i: Uint8Array<ArrayBuffer>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Tightly packs the Delta-Timed SoA into a memory-aligned ArrayBuffer.
|
|
30
|
+
*
|
|
31
|
+
* @reason We explicitly manage endianness via DataView for the 16-bit and 32-bit arrays
|
|
32
|
+
* to ensure that a `.rlo` file compiled on an x86 machine (Little Endian) plays flawlessly
|
|
33
|
+
* on an ARM or obscure Big-Endian web client.
|
|
34
|
+
*/
|
|
35
|
+
export declare function encodeToBinary(humanJson: RloData, fullRangeFreq?: boolean): ArrayBuffer;
|
|
36
|
+
/**
|
|
37
|
+
* Reconstructs a high-speed runtime object directly from the binary buffer.
|
|
38
|
+
*
|
|
39
|
+
* @reason During decode, we pre-allocate the exact flat array size `new Array(N * 5)`.
|
|
40
|
+
* This guarantees that the V8 engine allocates contiguous memory without dynamic resizing overhead.
|
|
41
|
+
* It reconstructs absolute time by accumulating the delta-time ticks to prevent floating-point drift.
|
|
42
|
+
*/
|
|
43
|
+
export declare function decodeBinary(buffer: ArrayBuffer): RloData;
|
|
22
44
|
//# sourceMappingURL=RLO-Transpiler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RLO-Transpiler.d.ts","sourceRoot":"","sources":["../RLO-Transpiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAMrC;;;;GAIG;AACH,
|
|
1
|
+
{"version":3,"file":"RLO-Transpiler.d.ts","sourceRoot":"","sources":["../RLO-Transpiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAMrC;;;;;;;;;;;;GAYG;AACH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,GAAE,OAAe;;;;;;;EAiD3E;AAEH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,OAAO,EAClB,aAAa,GAAE,OAAe,GAC7B,WAAW,CA8CX;AAEH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CA6CzD"}
|
package/dist/RLO-Transpiler.js
CHANGED
|
@@ -3,131 +3,153 @@ const hasTranspiler = typeof __ENABLE_TRANSPILER__ !== "undefined" ? __ENABLE_TR
|
|
|
3
3
|
* Universal translator for handling RLO data formats.
|
|
4
4
|
* Converts between Human AoS (Array of Structures), Intermediate SoA (Structure of Arrays),
|
|
5
5
|
* and highly compressed binary buffers.
|
|
6
|
+
*
|
|
7
|
+
* @reason Why Structure of Arrays (SoA) and Delta-Time?
|
|
8
|
+
* By decoupling a note into flat typed arrays (time, duration, frequency, velocity, instrument)
|
|
9
|
+
* we allow gzip/deflate algorithms to identify massive byte repetition. For example, if a
|
|
10
|
+
* hi-hat plays on the exact same instrument ID and velocity for 50 notes, SoA groups those 50
|
|
11
|
+
* identical bytes contiguously in memory, allowing gzip to compress them down to literally 1 or 2 bytes.
|
|
12
|
+
* Converting absolute time to delta-time serves the same purpose: instead of constantly increasing
|
|
13
|
+
* time signatures, rhythmic music will yield contiguous identical delta-time bytes which gzip dominates.
|
|
6
14
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
f[n] =
|
|
28
|
-
freq > 0
|
|
29
|
-
? Math.max(0, Math.min(255, Math.round(12 * Math.log2(freq / 440) + 69)))
|
|
30
|
-
: 0;
|
|
31
|
-
}
|
|
32
|
-
const roundedTime = Math.max(0, Math.round(time * 1000));
|
|
33
|
-
t[n] = Math.min(65535, roundedTime - lastRoundedTime); // Clamp to Uint16 max to prevent wraparound
|
|
34
|
-
d[n] = Math.min(65535, Math.max(0, Math.round(humanJson.notes[ptr + 2] * 1000)));
|
|
35
|
-
v[n] = Math.max(0, Math.min(255, Math.round(humanJson.notes[ptr + 3] * 255)));
|
|
36
|
-
i[n] = humanJson.notes[ptr + 4];
|
|
37
|
-
lastRoundedTime += t[n]; // Add the clamped delta to accurately track absolute encoded time
|
|
38
|
-
}
|
|
39
|
-
const soa = {
|
|
40
|
-
durationSecs: humanJson.durationSecs,
|
|
41
|
-
f,
|
|
42
|
-
t,
|
|
43
|
-
d,
|
|
44
|
-
v,
|
|
45
|
-
i,
|
|
46
|
-
};
|
|
47
|
-
return soa;
|
|
48
|
-
}
|
|
49
|
-
/** Tightly packs the Delta-Timed SoA into a memory-aligned ArrayBuffer */
|
|
50
|
-
static _encodeToBinary(humanJson, fullRangeFreq = false) {
|
|
51
|
-
if (!hasTranspiler)
|
|
52
|
-
return new ArrayBuffer(0);
|
|
53
|
-
const isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
|
|
54
|
-
const soa = this._encodeToSoA(humanJson, fullRangeFreq);
|
|
55
|
-
const N = soa.f.length;
|
|
56
|
-
// Arrays: Time(2*N) + Dur(2*N) + Freq(1*N or 4*N) + Vel(1*N) + Inst(1*N)
|
|
57
|
-
const bytesPerNote = fullRangeFreq ? 10 : 7;
|
|
58
|
-
const buffer = new ArrayBuffer(12 + bytesPerNote * N);
|
|
59
|
-
const view = new DataView(buffer);
|
|
60
|
-
view.setUint8(0, 82);
|
|
61
|
-
view.setUint8(1, 76);
|
|
62
|
-
view.setUint8(2, 79);
|
|
63
|
-
view.setUint8(3, fullRangeFreq ? 70 : 50); // 'RLOF' for Float32, 'RLO2' for Uint8
|
|
64
|
-
view.setFloat32(4, soa.durationSecs, true);
|
|
65
|
-
view.setUint32(8, N, true);
|
|
66
|
-
if (isLittleEndian) {
|
|
67
|
-
new Uint16Array(buffer, 12, N).set(soa.t);
|
|
68
|
-
new Uint16Array(buffer, 12 + 2 * N, N).set(soa.d);
|
|
69
|
-
if (fullRangeFreq) {
|
|
70
|
-
new Float32Array(buffer, 12 + 4 * N, N).set(soa.f);
|
|
71
|
-
}
|
|
15
|
+
/**
|
|
16
|
+
* Converts standard interleaved JSON into Delta-Timed Structure of Arrays.
|
|
17
|
+
* @param humanJson The flat-packed JSON array.
|
|
18
|
+
* @param fullRangeFreq If true, writes raw 32-bit floats. If false, aggressively quantizes to 8-bit MIDI scale.
|
|
19
|
+
*/
|
|
20
|
+
export function encodeToSoA(humanJson, fullRangeFreq = false) {
|
|
21
|
+
if (!hasTranspiler)
|
|
22
|
+
return null;
|
|
23
|
+
const N = humanJson.notes.length / 5;
|
|
24
|
+
const f = fullRangeFreq ? new Float32Array(N) : new Uint8Array(N);
|
|
25
|
+
const t = new Uint16Array(N);
|
|
26
|
+
const d = new Uint16Array(N);
|
|
27
|
+
const v = new Uint8Array(N);
|
|
28
|
+
const i = new Uint8Array(N);
|
|
29
|
+
let lastRoundedTime = 0;
|
|
30
|
+
for (let n = 0, ptr = 0; n < N; n++, ptr += 5) {
|
|
31
|
+
const time = humanJson.notes[ptr + 1];
|
|
32
|
+
const freq = humanJson.notes[ptr];
|
|
33
|
+
if (fullRangeFreq) {
|
|
34
|
+
f[n] = freq;
|
|
72
35
|
}
|
|
73
36
|
else {
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (fullRangeFreq) {
|
|
80
|
-
view.setFloat32(12 + 4 * N + n * 4, soa.f[n], true);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
37
|
+
// Map the frequency in Hz back down to a 1-byte 0-255 index
|
|
38
|
+
f[n] =
|
|
39
|
+
freq > 0
|
|
40
|
+
? Math.max(0, Math.min(255, Math.round(12 * Math.log2(freq / 440) + 69)))
|
|
41
|
+
: 0;
|
|
83
42
|
}
|
|
43
|
+
const roundedTime = Math.max(0, Math.round(time * 1000));
|
|
44
|
+
t[n] = Math.min(65535, roundedTime - lastRoundedTime); // Clamp to Uint16 max to prevent wraparound
|
|
45
|
+
d[n] = Math.min(65535, Math.max(0, Math.round(humanJson.notes[ptr + 2] * 1000)));
|
|
46
|
+
v[n] = Math.max(0, Math.min(255, Math.round(humanJson.notes[ptr + 3] * 255)));
|
|
47
|
+
i[n] = humanJson.notes[ptr + 4];
|
|
48
|
+
lastRoundedTime += t[n]; // Add the clamped delta to accurately track absolute encoded time
|
|
49
|
+
}
|
|
50
|
+
const soa = {
|
|
51
|
+
durationSecs: humanJson.durationSecs,
|
|
52
|
+
f,
|
|
53
|
+
t,
|
|
54
|
+
d,
|
|
55
|
+
v,
|
|
56
|
+
i,
|
|
57
|
+
};
|
|
58
|
+
return soa;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Tightly packs the Delta-Timed SoA into a memory-aligned ArrayBuffer.
|
|
62
|
+
*
|
|
63
|
+
* @reason We explicitly manage endianness via DataView for the 16-bit and 32-bit arrays
|
|
64
|
+
* to ensure that a `.rlo` file compiled on an x86 machine (Little Endian) plays flawlessly
|
|
65
|
+
* on an ARM or obscure Big-Endian web client.
|
|
66
|
+
*/
|
|
67
|
+
export function encodeToBinary(humanJson, fullRangeFreq = false) {
|
|
68
|
+
if (!hasTranspiler)
|
|
69
|
+
return new ArrayBuffer(0);
|
|
70
|
+
const isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
|
|
71
|
+
const soa = encodeToSoA(humanJson, fullRangeFreq);
|
|
72
|
+
const N = soa.f.length;
|
|
73
|
+
// Arrays: Time(2*N) + Dur(2*N) + Freq(1*N or 4*N) + Vel(1*N) + Inst(1*N)
|
|
74
|
+
const bytesPerNote = fullRangeFreq ? 10 : 7;
|
|
75
|
+
const buffer = new ArrayBuffer(12 + bytesPerNote * N);
|
|
76
|
+
const view = new DataView(buffer);
|
|
77
|
+
view.setUint8(0, 82);
|
|
78
|
+
view.setUint8(1, 76);
|
|
79
|
+
view.setUint8(2, 79);
|
|
80
|
+
view.setUint8(3, fullRangeFreq ? 70 : 50); // 'RLOF' for Float32, 'RLO2' for Uint8
|
|
81
|
+
view.setFloat32(4, soa.durationSecs, true);
|
|
82
|
+
view.setUint32(8, N, true);
|
|
83
|
+
if (isLittleEndian) {
|
|
84
|
+
new Uint16Array(buffer, 12, N).set(soa.t);
|
|
85
|
+
new Uint16Array(buffer, 12 + 2 * N, N).set(soa.d);
|
|
84
86
|
if (fullRangeFreq) {
|
|
85
|
-
new
|
|
86
|
-
new Uint8Array(buffer, 12 + 9 * N, N).set(soa.i);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
new Uint8Array(buffer, 12 + 4 * N, N).set(soa.f);
|
|
90
|
-
new Uint8Array(buffer, 12 + 5 * N, N).set(soa.v);
|
|
91
|
-
new Uint8Array(buffer, 12 + 6 * N, N).set(soa.i);
|
|
87
|
+
new Float32Array(buffer, 12 + 4 * N, N).set(soa.f);
|
|
92
88
|
}
|
|
93
|
-
return buffer;
|
|
94
89
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const durationSecs = view.getFloat32(4, true);
|
|
105
|
-
const N = view.getUint32(8, true);
|
|
106
|
-
// Single-byte arrays are endian-agnostic
|
|
107
|
-
const f8 = isFullRange ? null : new Uint8Array(buffer, 12 + 4 * N, N);
|
|
108
|
-
const v = new Uint8Array(buffer, 12 + (isFullRange ? 8 : 5) * N, N);
|
|
109
|
-
const i = new Uint8Array(buffer, 12 + (isFullRange ? 9 : 6) * N, N);
|
|
110
|
-
const notes = new Array(N * 5);
|
|
111
|
-
let currentTime = 0;
|
|
112
|
-
for (let n = 0, ptr = 0; n < N; n++, ptr += 5) {
|
|
113
|
-
// Read multi-byte values explicitly as Little-Endian
|
|
114
|
-
const tn = view.getUint16(12 + n * 2, true);
|
|
115
|
-
const dn = view.getUint16(12 + 2 * N + n * 2, true);
|
|
116
|
-
const fn = isFullRange
|
|
117
|
-
? view.getFloat32(12 + 4 * N + n * 4, true)
|
|
118
|
-
: f8[n];
|
|
119
|
-
currentTime += tn / 1000;
|
|
120
|
-
notes[ptr] = isFullRange
|
|
121
|
-
? fn
|
|
122
|
-
: fn > 0
|
|
123
|
-
? 440 * Math.pow(2, (fn - 69) / 12)
|
|
124
|
-
: 0;
|
|
125
|
-
notes[ptr + 1] = currentTime;
|
|
126
|
-
notes[ptr + 2] = dn / 1000;
|
|
127
|
-
notes[ptr + 3] = v[n] / 255;
|
|
128
|
-
notes[ptr + 4] = i[n];
|
|
90
|
+
else {
|
|
91
|
+
// Explicitly write multi-byte values as Little-Endian using DataView
|
|
92
|
+
// to ensure cross-platform compatibility (avoiding native endianness issues of TypedArrays)
|
|
93
|
+
for (let n = 0; n < N; n++) {
|
|
94
|
+
view.setUint16(12 + n * 2, soa.t[n], true);
|
|
95
|
+
view.setUint16(12 + 2 * N + n * 2, soa.d[n], true);
|
|
96
|
+
if (fullRangeFreq) {
|
|
97
|
+
view.setFloat32(12 + 4 * N + n * 4, soa.f[n], true);
|
|
98
|
+
}
|
|
129
99
|
}
|
|
130
|
-
return { durationSecs, notes };
|
|
131
100
|
}
|
|
101
|
+
if (fullRangeFreq) {
|
|
102
|
+
new Uint8Array(buffer, 12 + 8 * N, N).set(soa.v);
|
|
103
|
+
new Uint8Array(buffer, 12 + 9 * N, N).set(soa.i);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
new Uint8Array(buffer, 12 + 4 * N, N).set(soa.f);
|
|
107
|
+
new Uint8Array(buffer, 12 + 5 * N, N).set(soa.v);
|
|
108
|
+
new Uint8Array(buffer, 12 + 6 * N, N).set(soa.i);
|
|
109
|
+
}
|
|
110
|
+
return buffer;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Reconstructs a high-speed runtime object directly from the binary buffer.
|
|
114
|
+
*
|
|
115
|
+
* @reason During decode, we pre-allocate the exact flat array size `new Array(N * 5)`.
|
|
116
|
+
* This guarantees that the V8 engine allocates contiguous memory without dynamic resizing overhead.
|
|
117
|
+
* It reconstructs absolute time by accumulating the delta-time ticks to prevent floating-point drift.
|
|
118
|
+
*/
|
|
119
|
+
export function decodeBinary(buffer) {
|
|
120
|
+
if (!hasTranspiler)
|
|
121
|
+
return { durationSecs: 0, notes: new Float32Array(0) };
|
|
122
|
+
const view = new DataView(buffer);
|
|
123
|
+
const magic = String.fromCharCode(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
|
|
124
|
+
if (magic !== "RLO2" && magic !== "RLOF")
|
|
125
|
+
throw new Error("Invalid RLO Binary format. Please recompile tracks.");
|
|
126
|
+
const isFullRange = magic === "RLOF";
|
|
127
|
+
const durationSecs = view.getFloat32(4, true);
|
|
128
|
+
const N = view.getUint32(8, true);
|
|
129
|
+
// Single-byte arrays are endian-agnostic
|
|
130
|
+
const f8 = isFullRange ? null : new Uint8Array(buffer, 12 + 4 * N, N);
|
|
131
|
+
const v = new Uint8Array(buffer, 12 + (isFullRange ? 8 : 5) * N, N);
|
|
132
|
+
const i = new Uint8Array(buffer, 12 + (isFullRange ? 9 : 6) * N, N);
|
|
133
|
+
const notes = new Float32Array(N * 5);
|
|
134
|
+
let currentTime = 0;
|
|
135
|
+
for (let n = 0, ptr = 0; n < N; n++, ptr += 5) {
|
|
136
|
+
// Read multi-byte values explicitly as Little-Endian
|
|
137
|
+
const tn = view.getUint16(12 + n * 2, true);
|
|
138
|
+
const dn = view.getUint16(12 + 2 * N + n * 2, true);
|
|
139
|
+
const fn = isFullRange
|
|
140
|
+
? view.getFloat32(12 + 4 * N + n * 4, true)
|
|
141
|
+
: f8[n];
|
|
142
|
+
currentTime += tn / 1000;
|
|
143
|
+
notes[ptr] = isFullRange
|
|
144
|
+
? fn
|
|
145
|
+
: fn > 0
|
|
146
|
+
? 440 * Math.pow(2, (fn - 69) / 12)
|
|
147
|
+
: 0;
|
|
148
|
+
notes[ptr + 1] = currentTime;
|
|
149
|
+
notes[ptr + 2] = dn / 1000;
|
|
150
|
+
notes[ptr + 3] = v[n] / 255;
|
|
151
|
+
notes[ptr + 4] = i[n];
|
|
152
|
+
}
|
|
153
|
+
return { durationSecs, notes };
|
|
132
154
|
}
|
|
133
155
|
//# sourceMappingURL=RLO-Transpiler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RLO-Transpiler.js","sourceRoot":"","sources":["../RLO-Transpiler.ts"],"names":[],"mappings":"AAGA,MAAM,aAAa,GACjB,OAAO,qBAAqB,KAAK,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AAE9E;;;;GAIG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"RLO-Transpiler.js","sourceRoot":"","sources":["../RLO-Transpiler.ts"],"names":[],"mappings":"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"}
|
package/dist/compiler.d.ts
CHANGED
|
@@ -1,40 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { RloData } from "./types.js";
|
|
2
3
|
import { CompileStats } from "./midi-parser.js";
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
url: string;
|
|
18
|
-
}[], stats: CompileStats, baseUrl: string): void;
|
|
19
|
-
/**
|
|
20
|
-
* Processes a single loose MIDI file.
|
|
21
|
-
*/
|
|
22
|
-
export declare function processLooseMidiFile(midiFile: string, midiDir: string, outDir: string, manifest: {
|
|
23
|
-
id: string;
|
|
24
|
-
name: string;
|
|
25
|
-
url: string;
|
|
26
|
-
}[], stats: CompileStats, baseUrl: string): void;
|
|
27
|
-
/**
|
|
28
|
-
* Processes a single loose JSON file containing RloData and converts it to binary.
|
|
29
|
-
*/
|
|
30
|
-
export declare function processLooseJsonFile(jsonFile: string, jsonDir: string, outDir: string, manifest: {
|
|
4
|
+
/** Configuration options for the compilation pipeline. */
|
|
5
|
+
export interface CompilerOptions {
|
|
6
|
+
outputJson: boolean;
|
|
7
|
+
outputRlo: boolean;
|
|
8
|
+
noTrim: boolean;
|
|
9
|
+
fullRange: boolean;
|
|
10
|
+
zipsDir: string;
|
|
11
|
+
midiDir: string;
|
|
12
|
+
jsonDir: string | null;
|
|
13
|
+
outDir: string;
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
}
|
|
16
|
+
/** Represents a processed file in the generated manifest. */
|
|
17
|
+
export interface ManifestEntry {
|
|
31
18
|
id: string;
|
|
32
19
|
name: string;
|
|
33
20
|
url: string;
|
|
34
|
-
}
|
|
21
|
+
}
|
|
22
|
+
/** Strategy interface for processing different input sources. */
|
|
23
|
+
export interface IFileProcessor {
|
|
24
|
+
/** Processes the target source and updates the manifest and statistics. */
|
|
25
|
+
process(options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
26
|
+
}
|
|
27
|
+
/** Abstract base processor containing shared compilation and output logic. */
|
|
28
|
+
declare abstract class BaseProcessor implements IFileProcessor {
|
|
29
|
+
abstract process(options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
30
|
+
protected _outputCompiledData(songName: string, displayName: string, rloData: RloData, targetDir: string, urlPrefix: string, options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
31
|
+
protected _sanitizeName(name: string): string;
|
|
32
|
+
protected _formatDisplayName(name: string): string;
|
|
33
|
+
}
|
|
34
|
+
/** Processes ZIP archives containing MIDI files. */
|
|
35
|
+
export declare class ZipProcessor extends BaseProcessor {
|
|
36
|
+
process(options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
37
|
+
}
|
|
38
|
+
/** Processes loose MIDI files in a directory. */
|
|
39
|
+
export declare class MidiProcessor extends BaseProcessor {
|
|
40
|
+
process(options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
41
|
+
}
|
|
42
|
+
/** Processes pre-compiled loose JSON RLO files. */
|
|
43
|
+
export declare class JsonProcessor extends BaseProcessor {
|
|
44
|
+
process(options: CompilerOptions, manifest: ManifestEntry[], stats: CompileStats): void;
|
|
45
|
+
}
|
|
35
46
|
/**
|
|
36
|
-
*
|
|
37
|
-
* Scans the zips directory, processes all MIDI files, and outputs .rlo tracks.
|
|
47
|
+
* Enterprise Compiler Pipeline orchestrating the file processors.
|
|
38
48
|
*/
|
|
49
|
+
export declare class CompilerPipeline {
|
|
50
|
+
private _options;
|
|
51
|
+
private _processors;
|
|
52
|
+
constructor(options: CompilerOptions);
|
|
53
|
+
execute(): void;
|
|
54
|
+
private _printSummary;
|
|
55
|
+
}
|
|
56
|
+
/** Parses CLI arguments into an Options Object and executes the pipeline. */
|
|
39
57
|
export declare function runCompiler(): void;
|
|
58
|
+
export {};
|
|
40
59
|
//# sourceMappingURL=compiler.d.ts.map
|