UNPKG

burns-audio-wam

Version:

Collection of Web Audio Modules (WAMs) by Burns Audio

479 lines (456 loc) 22.6 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/JX3PKernel.ts": /*!***************************!*\ !*** ./src/JX3PKernel.ts ***! \***************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ JX3PKernel: () => (/* binding */ JX3PKernel) /* harmony export */ }); /* harmony import */ var _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../shared/midi/SelectParameter */ "../shared/midi/SelectParameter.ts"); /* harmony import */ var _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/midi/IntParameter */ "../shared/midi/IntParameter.ts"); /* harmony import */ var _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/midi/ControlChangeMessager */ "../shared/midi/ControlChangeMessager.ts"); class JX3PKernel { constructor() { this.parameters = {}; this.parameters["env_attack"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("env_attack", "Env Attack", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(26), 0, 0, 127); this.parameters["env_decay"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("env_decay", "Env Decay", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(27), 0, 0, 127); this.parameters["env_sustain"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("env_sustain", "Env Sustain", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(28), 0, 0, 127); this.parameters["env_release"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("env_release", "Env Release", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(29), 0, 0, 127); const range = [ { value: 0, label: "16'" }, { value: 32, label: "8'" }, { value: 64, label: "4'" }, ]; const wave1 = [ { value: 0, label: "Ramp" }, { value: 32, label: "Pulse" }, { value: 64, label: "Square" } ]; const wave2 = [...wave1, { value: 96, label: "Noise" }]; this.parameters["dco1_octave"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco1_octave", "DCO1 Octave", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(72), 0, range); this.parameters["dco1_wave"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco1_wave", "DCO1 Wave", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(73), 0, wave1); const off_on = [ { value: 0, label: "Off" }, { value: 64, label: "On" } ]; this.parameters["dco1_lfo"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco1_lfo", "LFO->DCO1", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(82), 0, off_on); this.parameters["dco1_env"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco1_env", "Env->DCO1", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(81), 0, off_on); this.parameters["dco2_octave"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco2_octave", "DCO2 Octave", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(74), 0, range); this.parameters["dco2_wave"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco2_wave", "DCO1 Wave", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(75), 0, wave2); const cross_mod = [ { value: 0, label: "Off" }, { value: 32, label: "Sync" }, { value: 64, label: "Metal" } ]; const polarity = [ { value: 0, label: "Neg" }, { value: 64, label: "Pos" } ]; this.parameters["dco2_mod"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco2_mod", "DCO2 Crossmod", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(76), 0, cross_mod); this.parameters["dco2_tune"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("dco2_tune", "DCO2 Coarse Tune", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(13), 0, 0, 127); this.parameters["dco2_fine"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("dco2_fine", "DCO2 Fine Tune", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(12), 0, 0, 127); this.parameters["dco2_lfo"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco2_lfo", "LFO->DCO2", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(80), 0, off_on); this.parameters["dco2_env"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("dco2_env", "Env->DCO2", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(79), 0, off_on); this.parameters["osc_lfo"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("osc_lfo", "Osc LFO Mod", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(15), 0, 0, 127); this.parameters["osc_env"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("osc_env", "Osc Env Mod", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(14), 0, 0, 127); this.parameters["osc_env_polarity"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("osc_env_polarity", "Osc Env Polarity", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(77), 0, polarity); this.parameters["mix"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("mix", "Source Mix", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(16), 0, 0, 127); this.parameters["hpf"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("hpf", "High-pass Filter", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(17), 0, 0, 127); this.parameters["cutoff"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("cutoff", "Filter Cutoff", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(19), 0, 0, 127); this.parameters["res"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("res", "Filter Res", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(18), 0, 0, 127); this.parameters["filter_lfo"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("filter_lfo", "Filter Envelope", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(20), 0, 0, 127); this.parameters["filter_env"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("filter_env", "Filter LFO", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(21), 0, 0, 127); this.parameters["filter_env_polarity"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("filter_env_polarity", "Filter Env Polarity", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(77), 0, polarity); this.parameters["filter_pitch"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("filter_pitch", "Filter Pitch Follow", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(22), 0, 0, 127); this.parameters["level"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("level", "Patch level", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(23), 0, 0, 127); this.parameters["chorus"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("chorus", "Chorus", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(85), 0, off_on); const gate = [ { value: 0, label: "gate" }, { value: 64, label: "env" } ]; this.parameters["gate"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("gate", "Gate mode", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(78), 0, gate); const lfo_waves = [ { value: 0, label: "Sine" }, { value: 32, label: "Square" }, { value: 64, label: "Random" } ]; this.parameters["lfo_wave"] = new _shared_midi_SelectParameter__WEBPACK_IMPORTED_MODULE_0__.SelectParameter("lfo_wave", "LFO Wave", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(99), 0, off_on); this.parameters["lfo_delay"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("lfo_delay", "LFO Delay", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(25), 0, 0, 127); this.parameters["lfo_rate"] = new _shared_midi_IntParameter__WEBPACK_IMPORTED_MODULE_1__.IntParameter("lfo_rate", "LFO Rate", new _shared_midi_ControlChangeMessager__WEBPACK_IMPORTED_MODULE_2__.ControlChangeMessager(24), 0, 0, 127); } wamParameters() { let result = {}; for (let id of Object.keys(this.parameters)) { result[id] = this.parameters[id].toWAM(); if (id != this.parameters[id].id) { throw new Error(`Parameter ${id}: key does not match parameter id ${this.parameters[id].id}`); } } return result; } ingestMIDI(channel, event) { let result = false; for (let id of Object.keys(this.parameters)) { if (this.parameters[id].ingestMIDI(channel, event)) { result = true; } } return result; } parameterUpdate(values) { let result = false; const params = this.parameters; for (let id of Object.keys(values)) { if (params[id].parameterUpdate(values[id])) { result = true; } } return result; } automationMessages(force) { const params = this.parameters; return Object.keys(params).map(id => params[id].automationMessage(force)).filter(ev => ev !== undefined); } sysexNeeded() { return false; } toSysex(channel) { throw new Error("sysex not supported"); } fromSysex(channel, sysex) { return false; } midiMessages(channel, force = false) { let results = []; for (let id of Object.keys(this.parameters)) { results.push(...this.parameters[id].midiMessage(channel, force)); } return results; } } /***/ }), /***/ "../shared/midi/ControlChangeMessager.ts": /*!***********************************************!*\ !*** ../shared/midi/ControlChangeMessager.ts ***! \***********************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ ControlChangeMessager: () => (/* binding */ ControlChangeMessager), /* harmony export */ MIDI_CC: () => (/* binding */ MIDI_CC) /* harmony export */ }); const MIDI_CC = 0xB0; class ControlChangeMessager { constructor(ccNumber) { this.ccNumber = ccNumber; } ingestMIDI(currentChannel, currentValue, event) { if ((currentChannel < 0 && (event.bytes[0] & 0xf0) == MIDI_CC) || ((event.bytes[0] == MIDI_CC + currentChannel))) { if (event.bytes[1] == this.ccNumber) { return event.bytes[2]; } } return undefined; } toMIDI(channel, value) { return [ { type: "wam-midi", data: { bytes: [MIDI_CC + channel, this.ccNumber, value] } } ]; } sysexNeeded() { return false; } } /***/ }), /***/ "../shared/midi/IntParameter.ts": /*!**************************************!*\ !*** ../shared/midi/IntParameter.ts ***! \**************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ IntParameter: () => (/* binding */ IntParameter) /* harmony export */ }); const MIDI_CC = 0xB0; class IntParameter { constructor(id, label, messager, defaultValue, minValue = 0, maxValue = 127) { this.id = id; this.label = label; this.messager = messager; this.defaultValue = defaultValue; this.minValue = minValue; this.maxValue = maxValue; this.value = this.defaultValue; } toWAM() { return { type: "int", label: this.label, defaultValue: this.defaultValue, minValue: this.minValue, maxValue: this.maxValue, }; } ingestMIDI(currentChannel, event) { let currentValue = this.value; if (this.minValue < 0) { currentValue += (this.minValue * -1); } let value = this.messager.ingestMIDI(currentChannel, this.value, event); if (value === undefined) { return false; } if (value === currentValue) { return false; } if (this.minValue < 0) { this.value = value + this.minValue; } else { this.value = value; } if (value > this.maxValue) { value = this.maxValue; } if (value < this.minValue) { value = this.minValue; } this.automationDirty = true; return true; } updateFromSysex(value) { if (value > this.maxValue || value < this.minValue) { console.error(`Param ${this.id}: updateFromSysex called with value out of range(${this.minValue}-${this.maxValue}): ${value}`); return; } this.value = value; this.automationDirty = true; } sysexNeeded(force = false) { if (!this.midiDirty && !force) { return false; } return this.messager.sysexNeeded(); } parameterUpdate(newValue) { const dirty = this.value != newValue; if (dirty) { this.midiDirty = true; } this.value = newValue; return dirty; } midiMessage(channel, force = false) { if (!this.midiDirty && !force) { return []; } this.midiDirty = false; let value = this.value; if (this.minValue < 0) { value -= this.minValue; } return this.messager.toMIDI(channel, value); } automationMessage(force = false) { if (!this.automationDirty && !force) { return undefined; } this.automationDirty = false; return { type: "wam-automation", data: { id: this.id, value: this.value, normalized: false, } }; } } /***/ }), /***/ "../shared/midi/SelectParameter.ts": /*!*****************************************!*\ !*** ../shared/midi/SelectParameter.ts ***! \*****************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ SelectParameter: () => (/* binding */ SelectParameter) /* harmony export */ }); class SelectParameter { constructor(id, label, messager, defaultValue, options) { this.id = id; this.label = label; this.messager = messager; this.defaultValue = defaultValue; this.options = options; this.value = this.defaultValue; } toWAM() { return { label: this.label, type: "choice", defaultValue: this.defaultValue, minValue: 0, maxValue: this.options.length - 1, choices: this.options.map(o => o.label) }; } ingestMIDI(currentChannel, event) { let currentMidiValue = this.options[this.value].value; let newMidiValue = this.messager.ingestMIDI(currentChannel, currentMidiValue, event); if (newMidiValue === undefined) { return false; } if (newMidiValue === currentMidiValue) { return false; } const index = this.options.findIndex(o => o.value == newMidiValue); if (index < 0) { return false; } this.value = index; this.automationDirty = true; return true; } updateFromSysex(value) { this.value = value; this.automationDirty = true; } parameterUpdate(newValue) { const option = this.options[newValue]; if (option === undefined) { console.log("Could not find option for newvalue ", newValue, this.id, this.options); return false; } const dirty = this.value != newValue; if (dirty) { this.midiDirty = true; } this.value = newValue; return dirty; } midiMessage(channel, force = false) { if (!this.midiDirty && !force) { return []; } this.midiDirty = false; const option = this.options[this.value]; if (!option) { console.error(`select ${this.id}: value ${this.value} should reference a select option index ${this.options}`); return []; } return this.messager.toMIDI(channel, option.value); } sysexNeeded(force = false) { if (!this.midiDirty && !force) { return false; } return this.messager.sysexNeeded(); } automationMessage(force = false) { if (!this.automationDirty && !force) { return undefined; } this.automationDirty = false; return { type: "wam-automation", data: { id: this.id, value: this.value, normalized: false, } }; } } /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!******************************!*\ !*** ./src/JX3PProcessor.ts ***! \******************************/ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _JX3PKernel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./JX3PKernel */ "./src/JX3PKernel.ts"); const moduleId = "com.sequencerParty.jx3p"; const audioWorkletGlobalScope = globalThis; const scope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId); const MIDIControllerProcessor = scope.MIDIControllerProcessor; class MicrokorgProcessor extends MIDIControllerProcessor { loadKernel() { this.kernel = new _JX3PKernel__WEBPACK_IMPORTED_MODULE_0__.JX3PKernel(); } } try { audioWorkletGlobalScope.registerProcessor(moduleId, MicrokorgProcessor); } catch (error) { } })(); /******/ })() ;