UNPKG

butterchurn

Version:

Butterchurn is a WebGL implementation of the Milkdrop Visualizer

1,206 lines (1,057 loc) 331 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("butterchurn", [], factory); else if(typeof exports === 'object') exports["butterchurn"] = factory(); else root["butterchurn"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./node_modules/ecma-proposal-math-extensions/reference-implementation/index.js": /*!**************************************************************************************!*\ !*** ./node_modules/ecma-proposal-math-extensions/reference-implementation/index.js ***! \**************************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; { const defineMath = (name, assignment) => { var configurable = typeof assignment === "function" ? true : false; var writable = typeof assignment === "function" ? true : false; var enumerable = typeof assignment === "function" ? true : false; Object.defineProperty(Math, name, { configurable: configurable, enumerable: enumerable, writable: writable, value: assignment }); }; defineMath("DEG_PER_RAD", Math.PI / 180); defineMath("RAD_PER_DEG", 180 / Math.PI); const f32A = new Float32Array(1); defineMath("scale", function scale(x, inLow, inHigh, outLow, outHigh) { if (arguments.length === 0) { return NaN; } if (Number.isNaN(x) || Number.isNaN(inLow) || Number.isNaN(inHigh) || Number.isNaN(outLow) || Number.isNaN(outHigh)) { return NaN; } if (x === Infinity || x === -Infinity) { return x; } return (x - inLow) * (outHigh - outLow) / (inHigh - inLow) + outLow; }); defineMath("fscale", function fscale(x, inLow, inHigh, outLow, outHigh) { f32A[0] = Math.scale(x, inLow, inHigh, outLow, outHigh); return f32A[0]; }); defineMath("clamp", function clamp(x, lower, upper) { return Math.min(upper, Math.max(lower, x)); }); defineMath("radians", function radians(degrees) { return degrees * Math.DEG_PER_RAD; }); defineMath("degrees", function degrees(radians) { return radians * Math.RAD_PER_DEG; }); } /***/ }), /***/ "./src/audio/audioLevels.js": /*!**********************************!*\ !*** ./src/audio/audioLevels.js ***! \**********************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AudioLevels; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var AudioLevels = /*#__PURE__*/ function () { function AudioLevels(audio) { _classCallCheck(this, AudioLevels); this.audio = audio; var sampleRate; if (this.audio.audioContext) { sampleRate = this.audio.audioContext.sampleRate; } else { sampleRate = 44100; } var bucketHz = sampleRate / this.audio.fftSize; var bassLow = Math.clamp(Math.round(20 / bucketHz) - 1, 0, this.audio.numSamps - 1); var bassHigh = Math.clamp(Math.round(320 / bucketHz) - 1, 0, this.audio.numSamps - 1); var midHigh = Math.clamp(Math.round(2800 / bucketHz) - 1, 0, this.audio.numSamps - 1); var trebHigh = Math.clamp(Math.round(11025 / bucketHz) - 1, 0, this.audio.numSamps - 1); this.starts = [bassLow, bassHigh, midHigh]; this.stops = [bassHigh, midHigh, trebHigh]; this.val = new Float32Array(3); this.imm = new Float32Array(3); this.att = new Float32Array(3); this.avg = new Float32Array(3); this.longAvg = new Float32Array(3); this.att.fill(1); this.avg.fill(1); this.longAvg.fill(1); } /* eslint-disable camelcase */ _createClass(AudioLevels, [{ key: "updateAudioLevels", value: function updateAudioLevels(fps, frame) { if (this.audio.freqArray.length > 0) { var effectiveFPS = fps; if (!AudioLevels.isFiniteNumber(effectiveFPS) || effectiveFPS < 15) { effectiveFPS = 15; } else if (effectiveFPS > 144) { effectiveFPS = 144; } // Clear for next loop this.imm.fill(0); for (var i = 0; i < 3; i++) { for (var j = this.starts[i]; j < this.stops[i]; j++) { this.imm[i] += this.audio.freqArray[j]; } } for (var _i = 0; _i < 3; _i++) { var rate = void 0; if (this.imm[_i] > this.avg[_i]) { rate = 0.2; } else { rate = 0.5; } rate = AudioLevels.adjustRateToFPS(rate, 30.0, effectiveFPS); this.avg[_i] = this.avg[_i] * rate + this.imm[_i] * (1 - rate); if (frame < 50) { rate = 0.9; } else { rate = 0.992; } rate = AudioLevels.adjustRateToFPS(rate, 30.0, effectiveFPS); this.longAvg[_i] = this.longAvg[_i] * rate + this.imm[_i] * (1 - rate); if (this.longAvg[_i] < 0.001) { this.val[_i] = 1.0; this.att[_i] = 1.0; } else { this.val[_i] = this.imm[_i] / this.longAvg[_i]; this.att[_i] = this.avg[_i] / this.longAvg[_i]; } } } } }, { key: "bass", get: function get() { return this.val[0]; } }, { key: "bass_att", get: function get() { return this.att[0]; } }, { key: "mid", get: function get() { return this.val[1]; } }, { key: "mid_att", get: function get() { return this.att[1]; } }, { key: "treb", get: function get() { return this.val[2]; } }, { key: "treb_att", get: function get() { return this.att[2]; } /* eslint-enable camelcase */ }], [{ key: "isFiniteNumber", value: function isFiniteNumber(num) { return Number.isFinite(num) && !Number.isNaN(num); } }, { key: "adjustRateToFPS", value: function adjustRateToFPS(rate, baseFPS, FPS) { return Math.pow(rate, baseFPS / FPS); } }]); return AudioLevels; }(); /***/ }), /***/ "./src/audio/audioProcessor.js": /*!*************************************!*\ !*** ./src/audio/audioProcessor.js ***! \*************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AudioProcessor; }); /* harmony import */ var _fft__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fft */ "./src/audio/fft.js"); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var AudioProcessor = /*#__PURE__*/ function () { function AudioProcessor(context) { _classCallCheck(this, AudioProcessor); this.numSamps = 512; this.fftSize = this.numSamps * 2; this.fft = new _fft__WEBPACK_IMPORTED_MODULE_0__["default"](this.fftSize, 512, true); if (context) { this.audioContext = context; this.audible = context.createDelay(); this.analyser = context.createAnalyser(); this.analyser.smoothingTimeConstant = 0.0; this.analyser.fftSize = this.fftSize; this.audible.connect(this.analyser); // Split channels this.analyserL = context.createAnalyser(); this.analyserL.smoothingTimeConstant = 0.0; this.analyserL.fftSize = this.fftSize; this.analyserR = context.createAnalyser(); this.analyserR.smoothingTimeConstant = 0.0; this.analyserR.fftSize = this.fftSize; this.splitter = context.createChannelSplitter(2); this.audible.connect(this.splitter); this.splitter.connect(this.analyserL, 0); this.splitter.connect(this.analyserR, 1); } // Initialised once as typed arrays // Used for webaudio API raw (time domain) samples. 0 -> 255 this.timeByteArray = new Uint8Array(this.fftSize); this.timeByteArrayL = new Uint8Array(this.fftSize); this.timeByteArrayR = new Uint8Array(this.fftSize); // Signed raw samples shifted to -128 -> 127 this.timeArray = new Int8Array(this.fftSize); this.timeByteArraySignedL = new Int8Array(this.fftSize); this.timeByteArraySignedR = new Int8Array(this.fftSize); // Temporary array for smoothing this.tempTimeArrayL = new Int8Array(this.fftSize); this.tempTimeArrayR = new Int8Array(this.fftSize); // Undersampled from this.fftSize to this.numSamps this.timeArrayL = new Int8Array(this.numSamps); this.timeArrayR = new Int8Array(this.numSamps); } _createClass(AudioProcessor, [{ key: "sampleAudio", value: function sampleAudio() { this.analyser.getByteTimeDomainData(this.timeByteArray); this.analyserL.getByteTimeDomainData(this.timeByteArrayL); this.analyserR.getByteTimeDomainData(this.timeByteArrayR); this.processAudio(); } }, { key: "updateAudio", value: function updateAudio(timeByteArray, timeByteArrayL, timeByteArrayR) { this.timeByteArray.set(timeByteArray); this.timeByteArrayL.set(timeByteArrayL); this.timeByteArrayR.set(timeByteArrayR); this.processAudio(); } /* eslint-disable no-bitwise */ }, { key: "processAudio", value: function processAudio() { for (var i = 0, j = 0, lastIdx = 0; i < this.fftSize; i++) { // Shift Unsigned to Signed about 0 this.timeArray[i] = this.timeByteArray[i] - 128; this.timeByteArraySignedL[i] = this.timeByteArrayL[i] - 128; this.timeByteArraySignedR[i] = this.timeByteArrayR[i] - 128; this.tempTimeArrayL[i] = 0.5 * (this.timeByteArraySignedL[i] + this.timeByteArraySignedL[lastIdx]); this.tempTimeArrayR[i] = 0.5 * (this.timeByteArraySignedR[i] + this.timeByteArraySignedR[lastIdx]); // Undersampled if (i % 2 === 0) { this.timeArrayL[j] = this.tempTimeArrayL[i]; this.timeArrayR[j] = this.tempTimeArrayR[i]; j += 1; } lastIdx = i; } // Use full width samples for the FFT this.freqArray = this.fft.timeToFrequencyDomain(this.timeArray); this.freqArrayL = this.fft.timeToFrequencyDomain(this.timeByteArraySignedL); this.freqArrayR = this.fft.timeToFrequencyDomain(this.timeByteArraySignedR); } }, { key: "connectAudio", value: function connectAudio(audionode) { audionode.connect(this.audible); } }, { key: "disconnectAudio", value: function disconnectAudio(audionode) { audionode.disconnect(this.audible); } /* eslint-enable no-bitwise */ }]); return AudioProcessor; }(); /***/ }), /***/ "./src/audio/fft.js": /*!**************************!*\ !*** ./src/audio/fft.js ***! \**************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return FFT; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var FFT = /*#__PURE__*/ function () { function FFT(samplesIn, samplesOut) { var equalize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; _classCallCheck(this, FFT); this.samplesIn = samplesIn; this.samplesOut = samplesOut; this.equalize = equalize; this.NFREQ = samplesOut * 2; if (this.equalize) { this.initEqualizeTable(); } this.initBitRevTable(); this.initCosSinTable(); } _createClass(FFT, [{ key: "initEqualizeTable", value: function initEqualizeTable() { this.equalizeArr = new Float32Array(this.samplesOut); var invHalfNFREQ = 1.0 / this.samplesOut; for (var i = 0; i < this.samplesOut; i++) { this.equalizeArr[i] = -0.02 * Math.log((this.samplesOut - i) * invHalfNFREQ); } } /* eslint-disable no-bitwise */ }, { key: "initBitRevTable", value: function initBitRevTable() { this.bitrevtable = new Uint16Array(this.NFREQ); for (var i = 0; i < this.NFREQ; i++) { this.bitrevtable[i] = i; } var j = 0; for (var _i = 0; _i < this.NFREQ; _i++) { if (j > _i) { var temp = this.bitrevtable[_i]; this.bitrevtable[_i] = this.bitrevtable[j]; this.bitrevtable[j] = temp; } var m = this.NFREQ >> 1; while (m >= 1 && j >= m) { j -= m; m >>= 1; } j += m; } } }, { key: "initCosSinTable", value: function initCosSinTable() { var dftsize = 2; var tabsize = 0; while (dftsize <= this.NFREQ) { tabsize += 1; dftsize <<= 1; } this.cossintable = [new Float32Array(tabsize), new Float32Array(tabsize)]; dftsize = 2; var i = 0; while (dftsize <= this.NFREQ) { var theta = -2.0 * Math.PI / dftsize; this.cossintable[0][i] = Math.cos(theta); this.cossintable[1][i] = Math.sin(theta); i += 1; dftsize <<= 1; } } }, { key: "timeToFrequencyDomain", value: function timeToFrequencyDomain(waveDataIn) { var real = new Float32Array(this.NFREQ); var imag = new Float32Array(this.NFREQ); for (var i = 0; i < this.NFREQ; i++) { var idx = this.bitrevtable[i]; if (idx < this.samplesIn) { real[i] = waveDataIn[idx]; } else { real[i] = 0; } imag[i] = 0; } var dftsize = 2; var t = 0; while (dftsize <= this.NFREQ) { var wpr = this.cossintable[0][t]; var wpi = this.cossintable[1][t]; var wr = 1.0; var wi = 0.0; var hdftsize = dftsize >> 1; for (var m = 0; m < hdftsize; m++) { for (var _i2 = m; _i2 < this.NFREQ; _i2 += dftsize) { var j = _i2 + hdftsize; var tempr = wr * real[j] - wi * imag[j]; var tempi = wr * imag[j] + wi * real[j]; real[j] = real[_i2] - tempr; imag[j] = imag[_i2] - tempi; real[_i2] += tempr; imag[_i2] += tempi; } var wtemp = wr; wr = wtemp * wpr - wi * wpi; wi = wi * wpr + wtemp * wpi; } dftsize <<= 1; t += 1; } var spectralDataOut = new Float32Array(this.samplesOut); if (this.equalize) { for (var _i3 = 0; _i3 < this.samplesOut; _i3++) { spectralDataOut[_i3] = this.equalizeArr[_i3] * Math.sqrt(real[_i3] * real[_i3] + imag[_i3] * imag[_i3]); } } else { for (var _i4 = 0; _i4 < this.samplesOut; _i4++) { spectralDataOut[_i4] = Math.sqrt(real[_i4] * real[_i4] + imag[_i4] * imag[_i4]); } } return spectralDataOut; } /* eslint-enable no-bitwise */ }]); return FFT; }(); /***/ }), /***/ "./src/blankPreset.js": /*!****************************!*\ !*** ./src/blankPreset.js ***! \****************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* eslint-disable */ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { 'use strict;'; var pmap = { baseVals: { gammaadj: 1.25, wave_g: 0.5, mv_x: 12.0, warpscale: 1.0, brighten: 0.0, mv_y: 9.0, wave_scale: 1.0, echo_alpha: 0.0, additivewave: 0.0, sx: 1.0, sy: 1.0, warp: 0.01, red_blue: 0.0, wave_mode: 0.0, wave_brighten: 0.0, wrap: 0.0, zoomexp: 1.0, fshader: 0.0, wave_r: 0.5, echo_zoom: 1.0, wave_smoothing: 0.75, warpanimspeed: 1.0, wave_dots: 0.0, wave_x: 0.5, wave_y: 0.5, zoom: 1.0, solarize: 0.0, modwavealphabyvolume: 0.0, dx: 0.0, cx: 0.5, dy: 0.0, darken_center: 0.0, cy: 0.5, invert: 0.0, bmotionvectorson: 0.0, rot: 0.0, modwavealphaend: 0.95, wave_mystery: -0.2, decay: 0.9, wave_a: 1.0, wave_b: 0.5, rating: 5.0, modwavealphastart: 0.75, darken: 0.0, echo_orient: 0.0, ib_r: 0.5, ib_g: 0.5, ib_b: 0.5, ib_a: 0.0, ib_size: 0.0, ob_r: 0.5, ob_g: 0.5, ob_b: 0.5, ob_a: 0.0, ob_size: 0.0, mv_dx: 0.0, mv_dy: 0.0, mv_a: 0.0, mv_r: 0.5, mv_g: 0.5, mv_b: 0.5, mv_l: 0.0 }, init_eqs: function init_eqs() { var m = {}; return m; }, frame_eqs: function frame_eqs(m) { m.rkeys = ['warp']; m.zoom = 1.01 + 0.02 * m.treb_att; m.warp = 0.15 + 0.25 * m.bass_att; return m; }, pixel_eqs: function pixel_eqs(m) { m.warp = m.warp + m.rad * 0.15; return m; }, waves: [{ baseVals: { a: 1.0, enabled: 0.0, b: 1.0, g: 1.0, scaling: 1.0, samples: 512.0, additive: 0.0, usedots: 0.0, spectrum: 0.0, r: 1.0, smoothing: 0.5, thick: 0.0, sep: 0.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; }, point_eqs: '' }, { baseVals: { a: 1.0, enabled: 0.0, b: 1.0, g: 1.0, scaling: 1.0, samples: 512.0, additive: 0.0, usedots: 0.0, spectrum: 0.0, r: 1.0, smoothing: 0.5, thick: 0.0, sep: 0.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; }, point_eqs: '' }, { baseVals: { a: 1.0, enabled: 0.0, b: 1.0, g: 1.0, scaling: 1.0, samples: 512.0, additive: 0.0, usedots: 0.0, spectrum: 0.0, r: 1.0, smoothing: 0.5, thick: 0.0, sep: 0.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; }, point_eqs: '' }, { baseVals: { a: 1.0, enabled: 0.0, b: 1.0, g: 1.0, scaling: 1.0, samples: 512.0, additive: 0.0, usedots: 0.0, spectrum: 0.0, r: 1.0, smoothing: 0.5, thick: 0.0, sep: 0.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; }, point_eqs: '' }], shapes: [{ baseVals: { r2: 0.0, a: 1.0, enabled: 0.0, b: 0.0, tex_ang: 0.0, thickoutline: 0.0, g: 0.0, textured: 0.0, g2: 1.0, tex_zoom: 1.0, additive: 0.0, border_a: 0.1, border_b: 1.0, b2: 0.0, a2: 0.0, r: 1.0, border_g: 1.0, rad: 0.1, x: 0.5, y: 0.5, ang: 0.0, sides: 4.0, border_r: 1.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; } }, { baseVals: { r2: 0.0, a: 1.0, enabled: 0.0, b: 0.0, tex_ang: 0.0, thickoutline: 0.0, g: 0.0, textured: 0.0, g2: 1.0, tex_zoom: 1.0, additive: 0.0, border_a: 0.1, border_b: 1.0, b2: 0.0, a2: 0.0, r: 1.0, border_g: 1.0, rad: 0.1, x: 0.5, y: 0.5, ang: 0.0, sides: 4.0, border_r: 1.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; } }, { baseVals: { r2: 0.0, a: 1.0, enabled: 0.0, b: 0.0, tex_ang: 0.0, thickoutline: 0.0, g: 0.0, textured: 0.0, g2: 1.0, tex_zoom: 1.0, additive: 0.0, border_a: 0.1, border_b: 1.0, b2: 0.0, a2: 0.0, r: 1.0, border_g: 1.0, rad: 0.1, x: 0.5, y: 0.5, ang: 0.0, sides: 4.0, border_r: 1.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; } }, { baseVals: { r2: 0.0, a: 1.0, enabled: 0.0, b: 0.0, tex_ang: 0.0, thickoutline: 0.0, g: 0.0, textured: 0.0, g2: 1.0, tex_zoom: 1.0, additive: 0.0, border_a: 0.1, border_b: 1.0, b2: 0.0, a2: 0.0, r: 1.0, border_g: 1.0, rad: 0.1, x: 0.5, y: 0.5, ang: 0.0, sides: 4.0, border_r: 1.0 }, init_eqs: function init_eqs(m) { m.rkeys = []; return m; }, frame_eqs: function frame_eqs(m) { return m; } }], warp: 'shader_body {\nret = texture2D(sampler_main, uv).rgb;\nret -= 0.004;\n}\n', comp: 'shader_body {\nret = texture2D(sampler_main, uv).rgb;\nret *= hue_shader;\n}\n' }; return pmap; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); /* eslint-enable */ /***/ }), /***/ "./src/equations/presetEquationRunner.js": /*!***********************************************!*\ !*** ./src/equations/presetEquationRunner.js ***! \***********************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PresetEquationRunner; }); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ "./src/utils.js"); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var PresetEquationRunner = /*#__PURE__*/ function () { function PresetEquationRunner(preset, globalVars, opts) { _classCallCheck(this, PresetEquationRunner); this.preset = preset; this.texsizeX = opts.texsizeX; this.texsizeY = opts.texsizeY; this.mesh_width = opts.mesh_width; this.mesh_height = opts.mesh_height; this.aspectx = opts.aspectx; this.aspecty = opts.aspecty; this.invAspectx = 1.0 / this.aspectx; this.invAspecty = 1.0 / this.aspecty; this.qs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 33).map(function (x) { return "q".concat(x); }); this.ts = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 9).map(function (x) { return "t".concat(x); }); this.regs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(100).map(function (x) { if (x < 10) { return "reg0".concat(x); } return "reg".concat(x); }); this.initializeEquations(globalVars); } _createClass(PresetEquationRunner, [{ key: "initializeEquations", value: function initializeEquations(globalVars) { this.runVertEQs = this.preset.pixel_eqs !== ''; this.mdVSQInit = null; this.mdVSRegs = null; this.mdVSFrame = null; this.mdVSUserKeys = null; this.mdVSFrameMap = null; this.mdVSShapes = null; this.mdVSUserKeysShapes = null; this.mdVSFrameMapShapes = null; this.mdVSWaves = null; this.mdVSUserKeysWaves = null; this.mdVSFrameMapWaves = null; this.mdVSQAfterFrame = null; this.gmegabuf = new Array(1048576).fill(0); var mdVSBase = { frame: globalVars.frame, time: globalVars.time, fps: globalVars.fps, bass: globalVars.bass, bass_att: globalVars.bass_att, mid: globalVars.mid, mid_att: globalVars.mid_att, treb: globalVars.treb, treb_att: globalVars.treb_att, meshx: this.mesh_width, meshy: this.mesh_height, aspectx: this.invAspectx, aspecty: this.invAspecty, pixelsx: this.texsizeX, pixelsy: this.texsizeY, gmegabuf: this.gmegabuf }; this.mdVS = Object.assign({}, this.preset.baseVals, mdVSBase); this.mdVS.megabuf = new Array(1048576).fill(0); this.mdVS.rand_start = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]); this.mdVS.rand_preset = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]); var nonUserKeys = this.qs.concat(this.regs, Object.keys(this.mdVS)); var mdVSAfterInit = this.preset.init_eqs(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].cloneVars(this.mdVS)); // qs need to be initialized to there init values every frame this.mdVSQInit = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, this.qs); this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, this.regs); var initUserVars = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSAfterInit, nonUserKeys))); initUserVars.megabuf = mdVSAfterInit.megabuf; initUserVars.gmegabuf = mdVSAfterInit.gmegabuf; this.mdVSFrame = this.preset.frame_eqs(Object.assign({}, this.mdVS, this.mdVSQInit, this.mdVSRegs, initUserVars)); // user vars need to be copied between frames this.mdVSUserKeys = Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(this.mdVSFrame, nonUserKeys)); // Determine vars to carry over between frames this.mdVSFrameMap = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.mdVSUserKeys); // qs for shapes this.mdVSQAfterFrame = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.qs); this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.regs); this.mdVSWaves = []; this.mdVSTWaveInits = []; this.mdVSUserKeysWaves = []; this.mdVSFrameMapWaves = []; if (this.preset.waves && this.preset.waves.length > 0) { for (var i = 0; i < this.preset.waves.length; i++) { var wave = this.preset.waves[i]; var baseVals = wave.baseVals; if (baseVals.enabled !== 0) { var mdVSWave = Object.assign({}, baseVals, mdVSBase); var nonUserWaveKeys = this.qs.concat(this.ts, this.regs, Object.keys(mdVSWave)); Object.assign(mdVSWave, this.mdVSQAfterFrame, this.mdVSRegs); mdVSWave.megabuf = new Array(1048576).fill(0); if (wave.init_eqs) { mdVSWave = wave.init_eqs(mdVSWave); this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.regs); // base vals need to be reset Object.assign(mdVSWave, baseVals); } this.mdVSWaves.push(mdVSWave); this.mdVSTWaveInits.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.ts)); this.mdVSUserKeysWaves.push(Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSWave, nonUserWaveKeys))); this.mdVSFrameMapWaves.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.mdVSUserKeysWaves[i])); } else { this.mdVSWaves.push({}); this.mdVSTWaveInits.push({}); this.mdVSUserKeysWaves.push([]); this.mdVSFrameMapWaves.push({}); } } } this.mdVSShapes = []; this.mdVSTShapeInits = []; this.mdVSUserKeysShapes = []; this.mdVSFrameMapShapes = []; if (this.preset.shapes && this.preset.shapes.length > 0) { for (var _i = 0; _i < this.preset.shapes.length; _i++) { var shape = this.preset.shapes[_i]; var _baseVals = shape.baseVals; if (_baseVals.enabled !== 0) { var mdVSShape = Object.assign({}, _baseVals, mdVSBase); var nonUserShapeKeys = this.qs.concat(this.ts, this.regs, Object.keys(mdVSShape)); Object.assign(mdVSShape, this.mdVSQAfterFrame, this.mdVSRegs); mdVSShape.megabuf = new Array(1048576).fill(0); if (shape.init_eqs) { mdVSShape = shape.init_eqs(mdVSShape); this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.regs); // base vals need to be reset Object.assign(mdVSShape, _baseVals); } this.mdVSShapes.push(mdVSShape); this.mdVSTShapeInits.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.ts)); this.mdVSUserKeysShapes.push(Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSShape, nonUserShapeKeys))); this.mdVSFrameMapShapes.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.mdVSUserKeysShapes[_i])); } else { this.mdVSShapes.push({}); this.mdVSTShapeInits.push({}); this.mdVSUserKeysShapes.push([]); this.mdVSFrameMapShapes.push({}); } } } } }, { key: "updatePreset", value: function updatePreset(preset, globalVars) { this.preset = preset; this.initializeEquations(globalVars); } }, { key: "updateGlobals", value: function updateGlobals(opts) { this.texsizeX = opts.texsizeX; this.texsizeY = opts.texsizeY; this.mesh_width = opts.mesh_width; this.mesh_height = opts.mesh_height; this.aspectx = opts.aspectx; this.aspecty = opts.aspecty; this.invAspectx = 1.0 / this.aspectx; this.invAspecty = 1.0 / this.aspecty; } }, { key: "runFrameEquations", value: function runFrameEquations(globalVars) { this.mdVSFrame = Object.assign({}, this.mdVS, this.mdVSQInit, this.mdVSFrameMap, globalVars); this.mdVSFrame = this.preset.frame_eqs(this.mdVSFrame); this.mdVSFrameMap = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.mdVSUserKeys); this.mdVSQAfterFrame = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.qs); } }]); return PresetEquationRunner; }(); /***/ }), /***/ "./src/image/imageTextures.js": /*!************************************!*\ !*** ./src/image/imageTextures.js ***! \************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ImageTextures; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var ImageTextures = /*#__PURE__*/ function () { function ImageTextures(gl) { var _this = this; _classCallCheck(this, ImageTextures); this.gl = gl; this.anisoExt = this.gl.getExtension('EXT_texture_filter_anisotropic') || this.gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || this.gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); this.samplers = {}; /* eslint-disable max-len */ this.clouds2Image = new Image(); this.clouds2Image.onload = function () { _this.samplers.clouds2 = _this.gl.createTexture(); _this.bindTexture(_this.samplers.clouds2, _this.clouds2Image, 128, 128); }; this.clouds2Image.src = 'data:image/jpeg;base64,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