furnace-module-interface
Version:
An interface for loading, processing and saving furnace modules in an object-oriented manner. Fully typed via TypeScript.
108 lines (107 loc) • 4.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FurnaceInstrumentModule = void 0;
const bufferHelper_1 = require("./bufferHelper");
const defaults_1 = require("./defaults");
const instrument_1 = require("./instrument");
const meta_1 = require("./meta");
const sample_1 = require("./sample");
const wavetable_1 = require("./wavetable");
class FurnaceInstrumentModule {
constructor() {
this.version = defaults_1.defaults.version;
this.instruments = [instrument_1.FurnaceInstrument.create(),];
this.wavetables = [];
this.samples = [];
this.meta = meta_1.FurnaceMeta.create();
}
static create() {
return new FurnaceInstrumentModule();
}
static fromHelper(helper) {
const mod = FurnaceInstrumentModule.create();
if (FurnaceInstrumentModule.magic !== helper.getASCII(16)) {
throw new Error("Expected format magic string \"" + FurnaceInstrumentModule.magic + "\" when loading an instrument module.");
}
mod.version = helper.readUInt16LE();
helper.skipBytes(2);
const instrumentPtrs = [helper.readUInt32LE(),];
const wavePtrs = [];
const waveCount = helper.readUInt16LE();
const samplePtrs = [];
const sampleCount = helper.readUInt16LE();
helper.skipBytes(4);
for (let i = 0; i < waveCount; i++) {
wavePtrs.push(helper.readUInt32LE());
}
for (let i = 0; i < sampleCount; i++) {
samplePtrs.push(helper.readUInt32LE());
}
mod.instruments = instrumentPtrs.map((position) => {
const pos = helper.getPosition(0);
helper.setPosition(position);
const ins = instrument_1.FurnaceInstrument.fromHelper(helper);
helper.setPosition(pos);
return ins;
});
mod.wavetables = wavePtrs.map((position) => {
const pos = helper.getPosition(0);
helper.setPosition(position);
const ins = wavetable_1.FurnaceWavetable.fromHelper(helper);
helper.setPosition(pos);
return ins;
});
mod.samples = samplePtrs.map((position) => {
const pos = helper.getPosition(0);
helper.setPosition(position);
const ins = sample_1.FurnaceSample.fromHelper(helper, mod.version);
helper.setPosition(pos);
return ins;
});
mod.meta = meta_1.FurnaceMeta.checkFromHelper(helper);
return mod;
}
getAsBuffer() {
const helper = new bufferHelper_1.BufferWriteHelper();
helper.writeString(FurnaceInstrumentModule.magic, "ascii", false);
helper.writeUInt16LE(this.version);
helper.skipBytes(2);
if (this.instruments.length !== 1) {
throw new Error("Expected instrument module to contain 1 instrument, but it contains " + this.wavetables.length + "!");
}
if (this.wavetables.length > 256) {
throw new Error("At most 256 wavetables are supported, but " + this.wavetables.length + " were defined!");
}
if (this.samples.length > 256) {
throw new Error("At most 256 samples are supported, but " + this.samples.length + " were defined!");
}
const insPtrs = helper.getPosition(0);
helper.skipBytes(4 * this.instruments.length);
helper.writeUInt16LE(this.wavetables.length);
helper.writeUInt16LE(this.samples.length);
helper.skipBytes(4);
const wavePtrs = helper.getPosition(0);
helper.skipBytes(4 * this.wavetables.length);
const sampPtrs = helper.getPosition(0);
helper.skipBytes(4 * this.samples.length);
this.instruments.forEach((item, ix) => {
helper.writeUInt32LE(helper.getPosition(0), insPtrs + (ix * 4));
item.writeToBuffer(helper);
});
this.wavetables.forEach((item, ix) => {
helper.writeUInt32LE(helper.getPosition(0), wavePtrs + (ix * 4));
item.writeToBuffer(helper);
});
this.samples.forEach((item, ix) => {
helper.writeUInt32LE(helper.getPosition(0), sampPtrs + (ix * 4));
item.writeToBuffer(helper, this.version);
});
this.meta.writeToBuffer(helper);
return helper.getTrimmedBuffer();
}
getVersion() {
return this.version;
}
}
exports.FurnaceInstrumentModule = FurnaceInstrumentModule;
FurnaceInstrumentModule.magic = "-Furnace instr.-";