UNPKG

furnace-module-interface

Version:

An interface for loading, processing and saving furnace modules in an object-oriented manner. Fully typed via TypeScript.

199 lines (198 loc) 7.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Furnace16bitSample = exports.Furnace8bitSample = exports.FurnaceSample = void 0; const defaults_1 = require("./defaults"); class FurnaceSample { constructor() { this.name = defaults_1.defaults.sampleName; this.compatRate = defaults_1.defaults.sampleRate; this.c4Rate = defaults_1.defaults.sampleRate; this.loopStart = null; this.loopEnd = null; this.volume = null; this.pitch = null; this.data = Furnace8bitSample.create(); this.precense = [0, 0, 0, 0,]; } static create() { return new FurnaceSample(); } static fromHelper(helper, version) { const sample = FurnaceSample.create(); const _magic = helper.getASCII(4); const old = FurnaceSample.magic === _magic; if (!old && FurnaceSample.magic2 !== _magic) { throw new Error("Expected format magic string \"" + FurnaceSample.magic + "\" or \"" + FurnaceSample.magic2 + "\" when loading a sample block."); } helper.skipBytes(4); sample.name = helper.readString("utf-8"); const length = helper.readUInt32LE(); sample.compatRate = helper.readUInt32LE(); if (old) { sample.volume = helper.readInt16LE(); sample.pitch = helper.readInt16LE(); if (version >= 58) { sample.volume = null; sample.pitch = null; } } else { sample.volume = null; sample.pitch = null; sample.c4Rate = helper.readUInt32LE(); } const format = helper.readUInt8(); const loadFormat = FurnaceSample.getFormatFunctionFromId(format); if (old) { helper.skipBytes(1); sample.c4Rate = helper.readUInt16LE(); sample.loopStart = helper.readUInt32LE(); sample.loopEnd = length; sample.precense = [0, 0, 0, 0,]; } else { helper.skipBytes(3); sample.loopStart = helper.readUInt32LE(); sample.loopEnd = helper.readUInt32LE(); sample.precense = [helper.readUInt32LE(), helper.readUInt32LE(), helper.readUInt32LE(), helper.readUInt32LE(),]; } if (sample.loopStart === 0xFFFFFFFF) { sample.loopStart = null; } if (sample.loopEnd === 0xFFFFFFFF) { sample.loopEnd = null; } const pos = helper.getPosition(0); const buf = helper.buffer.subarray(pos, pos + (length * (version < 58 ? 2 : FurnaceSample.getFormatMultiply(format)))); sample.data = loadFormat(buf, length); return sample; } static getFormatMultiply(format) { switch (format) { case 8: return 1; case 16: return 2; } throw new Error("Unknown or unsupported sample format id " + format); } static getFormatFunctionFromId(format) { switch (format) { case 8: return Furnace8bitSample.fromBuffer; case 16: return Furnace16bitSample.fromBuffer; } throw new Error("Unknown or unsupported sample format id " + format); } writeToBuffer(helper, version) { if (version >= 102) { this.writeToBufferSMP2(helper); } else { this.writeToBufferSMPL(helper, version); } } writeToBufferSMP2(helper) { var _a, _b; const _begin = helper.getPosition(8); helper.writeString(FurnaceSample.magic2, "ascii", false); helper.skipBytes(4); helper.writeString(this.name, "utf-8", true); helper.writeUInt32LE(this.data.entries / FurnaceSample.getFormatMultiply(this.data.formatId)); helper.writeUInt32LE(this.compatRate); helper.writeUInt32LE(this.c4Rate); helper.writeUInt8(this.data.formatId); helper.skipBytes(3); helper.writeUInt32LE((_a = this.loopStart) !== null && _a !== void 0 ? _a : 0xFFFFFFFF); helper.writeUInt32LE((_b = this.loopEnd) !== null && _b !== void 0 ? _b : 0xFFFFFFFF); helper.writeUInt32LE(this.precense[0]); helper.writeUInt32LE(this.precense[1]); helper.writeUInt32LE(this.precense[2]); helper.writeUInt32LE(this.precense[3]); helper.writeBuffer(this.data.rawBuffer, 0, this.data.rawBuffer.length); helper.writeUInt32LE(helper.getPosition() - _begin, _begin - 4); } writeToBufferSMPL(helper, version) { var _a, _b, _c; const _begin = helper.getPosition(8); helper.writeString(FurnaceSample.magic, "ascii", false); helper.skipBytes(4); helper.writeString(this.name, "utf-8", true); helper.writeUInt32LE(this.data.entries / (version < 58 ? 2 : FurnaceSample.getFormatMultiply(this.data.formatId))); helper.writeUInt32LE(this.compatRate); helper.writeInt16LE((_a = this.volume) !== null && _a !== void 0 ? _a : 0); helper.writeInt16LE((_b = this.pitch) !== null && _b !== void 0 ? _b : 0); helper.writeUInt8(this.data.formatId); helper.skipBytes(1); helper.writeUInt16LE(this.c4Rate); helper.writeUInt32LE((_c = this.loopStart) !== null && _c !== void 0 ? _c : 0xFFFFFFFF); helper.writeBuffer(this.data.rawBuffer, 0, this.data.rawBuffer.length); helper.writeUInt32LE(helper.getPosition() - _begin, _begin - 4); } } exports.FurnaceSample = FurnaceSample; FurnaceSample.magic = "SMPL"; FurnaceSample.magic2 = "SMP2"; class Furnace8bitSample { constructor() { this.formatName = "8-bit PCM"; this.formatId = 8; this.entries = 0; } static create() { const format = new Furnace8bitSample(); format.rawBuffer = Buffer.alloc(0); return format; } static fromBuffer(buffer, length) { const format = new Furnace8bitSample(); format.rawBuffer = buffer; format.entries = length; return format; } convertToArray() { const array = new Int16Array(this.entries); for (let i = 0; i < this.entries; i++) { array[i] = this.rawBuffer.readInt8(i) << 8; } return array; } convertFromArray(array) { this.entries = array.length; this.rawBuffer = Buffer.alloc(this.entries); for (let i = 0; i < this.entries; i++) { this.rawBuffer.writeInt8(array[i] >> 8, i); } } } exports.Furnace8bitSample = Furnace8bitSample; class Furnace16bitSample { constructor() { this.formatName = "16-bit PCM"; this.formatId = 16; this.entries = 0; } static create() { const format = new Furnace16bitSample(); format.rawBuffer = Buffer.alloc(0); return format; } static fromBuffer(buffer, length) { const format = new Furnace16bitSample(); format.rawBuffer = buffer; format.entries = length; return format; } convertToArray() { const array = new Int16Array(this.entries); for (let i = 0; i < this.entries; i++) { array[i] = this.rawBuffer.readInt16LE(i * 2); } return array; } convertFromArray(array) { this.entries = array.length; this.rawBuffer = Buffer.alloc(this.entries * 2); for (let i = 0; i < this.entries; i++) { this.rawBuffer.writeInt16LE(array[i], i * 2); } } } exports.Furnace16bitSample = Furnace16bitSample;