butterchurn
Version:
Butterchurn is a WebGL implementation of the Milkdrop Visualizer
1,206 lines (1,057 loc) • 331 kB
JavaScript
(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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