UNPKG

spessasynth_core

Version:

MIDI and SoundFont2/DLS library with no compromises

115 lines (104 loc) 2.77 kB
import { BasicGlobalZone } from "./basic_global_zone.js"; import { BasicInstrumentZone } from "./basic_instrument_zone.js"; import { SpessaSynthWarn } from "../../utils/loggin.js"; export class BasicInstrument { /** * The instrument's name * @type {string} */ instrumentName = ""; /** * The instrument's zones * @type {BasicInstrumentZone[]} * @readonly */ instrumentZones = []; /** * Instrument's global zone * @type {BasicGlobalZone} */ globalZone = new BasicGlobalZone(); /** * Instrument's linked presets (the presets that use it) * note that duplicates are allowed since one preset can use the same instrument multople times * @type {BasicPreset[]} */ linkedPresets = []; /** * @returns {number} */ get useCount() { return this.linkedPresets.length; } /** * @returns {BasicInstrumentZone} */ createZone() { const zone = new BasicInstrumentZone(this); this.instrumentZones.push(zone); return zone; } /** * @param preset {BasicPreset} */ linkTo(preset) { this.linkedPresets.push(preset); this.instrumentZones.forEach(z => z.useCount++); } /** * @param preset {BasicPreset} */ unlinkFrom(preset) { const index = this.linkedPresets.indexOf(preset); if (index < 0) { SpessaSynthWarn(`Cannot unlink ${preset.presetName} from ${this.instrumentName}: not linked.`); return; } this.linkedPresets.splice(index, 1); this.instrumentZones.forEach(z => z.useCount--); } deleteUnusedZones() { this.instrumentZones = this.instrumentZones.filter(z => { const stays = z.useCount > 0; if (!stays) { z.deleteZone(); } return stays; }); } // unlinks everything from this instrument deleteInstrument() { if (this.useCount > 0) { throw new Error(`Cannot delete an instrument that is used by: ${this.linkedPresets.map(p => p.presetName)}.`); } this.instrumentZones.forEach(z => z.deleteZone()); } /** * @param index {number} * @param force {boolean} ignore use count * @returns {boolean} if deleted */ deleteZone(index, force = false) { const zone = this.instrumentZones[index]; zone.useCount -= 1; if (zone.useCount < 1 || force) { zone.deleteZone(); this.instrumentZones.splice(index, 1); return true; } return false; } }