UNPKG

spessasynth_core

Version:

MIDI and SoundFont2/DLS library with no compromises

76 lines (69 loc) 2.2 kB
import { generatorLimits, generatorTypes } from "./generator_types.js"; export const GEN_BYTE_SIZE = 4; export class Generator { /** * The generator's enum number * @type {generatorTypes|number} */ generatorType = generatorTypes.INVALID; /** * The generator's 16-bit value * @type {number} */ generatorValue = 0; /** * Constructs a new generator * @param type {generatorTypes|number} * @param value {number} * @param validate {boolean} */ constructor(type = generatorTypes.INVALID, value = 0, validate = true) { this.generatorType = type; if (value === undefined) { throw new Error("No value provided."); } this.generatorValue = Math.round(value); if (validate) { const lim = generatorLimits[type]; if (lim !== undefined) { this.generatorValue = Math.max(lim.min, Math.min(lim.max, this.generatorValue)); } } } } /** * generator.js * purpose: contains enums for generators, * and their limis parses reads soundfont generators, sums them and applies limits */ /** * @param generatorType {number} * @param presetGens {Generator[]} * @param instrumentGens {Generator[]} */ export function addAndClampGenerator(generatorType, presetGens, instrumentGens) { const limits = generatorLimits[generatorType] || { min: 0, max: 32768, def: 0 }; let presetGen = presetGens.find(g => g.generatorType === generatorType); let presetValue = 0; if (presetGen) { presetValue = presetGen.generatorValue; } let instruGen = instrumentGens.find(g => g.generatorType === generatorType); let instruValue = limits.def; if (instruGen) { instruValue = instruGen.generatorValue; } // limits are applied in the compute_modulator function // clamp to prevent short from overflowing // testcase: Sega Genesis soundfont (spessasynth/#169) adds 20,999 and the default 13,500 to initialFilterFc // which is more than 32k return Math.max(-32767, Math.min(32767, instruValue + presetValue)); }