diff --git a/src/VisualizerCore.js b/src/VisualizerCore.js new file mode 100644 index 0000000..cea6573 --- /dev/null +++ b/src/VisualizerCore.js @@ -0,0 +1,55 @@ +"use strict"; + +export default function VisualizerCore(mediaSource, fftSize = 1024) { + this._stream = mediaSource; + this._analyzing = false; + this._updateListeners = []; + this._audioCtx = new window.AudioContext(); + this._source = null; // Prepare for either a MediaStream or a MediaElement. + try { + this.source = this._audioCtx.createMediaStreamSource(this._stream); + } catch (e) { + this._source = this._audioCtx.createMediaElementSource(this._stream); + } + this._analyzer = this._audioCtx.createAnalyser(); + this._analyzer.fftSize = fftSize; + this._source.connect(this._analyzer); + this._analyzer.connect(this._audioCtx.destination); + this._buffer = new Uint8Array(this._analyzer.frequencyBinCount); + + this.lastUpdate = null; + + this.analyze = function () { + if (this._analyzing) { + return; + } + this._analyzing = true; + requestAnimationFrame(this.update); + }; + + let _self = this; + this.update = function (timestamp) { + if (!_self._analyzing) return; + + requestAnimationFrame(_self.update); + if (!_self.lastUpdate) { + _self.lastUpdate = timestamp; + } + let delta = timestamp - _self.lastUpdate; + _self._analyzer.getByteFrequencyData(_self._buffer); + + _self._updateListeners.forEach(listener => { + listener(delta, _self._buffer); + }); + }; + this.stop = function () { + this._analyzing = false; + }; + this.addUpdateListener = function (listener) { + console.log("added listener."); + this._updateListeners.push(listener); + }; + this.getNumberOfBins = function () { + return this._buffer.length; + }; +} diff --git a/src/audioshowkit.js b/src/audioshowkit.js new file mode 100644 index 0000000..9a390c3 --- /dev/null +++ b/src/audioshowkit.js @@ -0,0 +1 @@ +"use strict"; \ No newline at end of file diff --git a/src/patterns/HorizontalBar.js b/src/patterns/HorizontalBar.js new file mode 100644 index 0000000..16a0977 --- /dev/null +++ b/src/patterns/HorizontalBar.js @@ -0,0 +1,22 @@ +"use strict"; + +export default function bindHorizontalBar(canvasElement, visualizerCore) { + let _width = canvasElement.width; + let _height = canvasElement.height; + let _canvasCtx = canvasElement.getContext("2d"); + let _visualizerCore = visualizerCore; + let update = function (delta, bins) { + _canvasCtx.clearRect(0, 0, _width, _height); // clear canvas. + let barWidth = Math.floor(_width / bins.length) - 1; // -1 for 1 pixel gap between bars. + let barIndex = 0; + console.log("updating visuals.." + barWidth); + bins.forEach(bin => { + let normalBin = bin / 255.0; + _canvasCtx.fillStyle = "rgb(" + 0 + "," + bin + "," + bin + ")"; + let barHeight = _height * normalBin; + _canvasCtx.fillRect(barIndex * barWidth, _height - barHeight, barWidth, barHeight); + barIndex += 1; + }); + }; + _visualizerCore.addUpdateListener(update); +} \ No newline at end of file diff --git a/tests/Elektronomia - Collide.mp3 b/tests/Elektronomia - Collide.mp3 new file mode 100644 index 0000000..012819e Binary files /dev/null and b/tests/Elektronomia - Collide.mp3 differ diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 0000000..4f6385e --- /dev/null +++ b/tests/index.html @@ -0,0 +1,17 @@ + + + + + + + AudioShowKit visual test + + + + + + + + + + \ No newline at end of file diff --git a/tests/main.css b/tests/main.css new file mode 100644 index 0000000..e69de29 diff --git a/tests/script.js b/tests/script.js new file mode 100644 index 0000000..f491284 --- /dev/null +++ b/tests/script.js @@ -0,0 +1,24 @@ +"use strict"; + +import bindHorizontalBar from "../src/patterns/HorizontalBar.js"; +import VisualizerCore from "../src/VisualizerCore.js"; + +// We will see if the visualizers core and event systems are working correctly. +let startBtn = document.getElementById("startbtn"); +startBtn.addEventListener("click", async (ev) => { + let mediaStream = new Audio("../tests/Elektronomia - Collide.mp3"); + mediaStream.addEventListener("canplaythrough", (ev) => { + let visCore = new VisualizerCore(mediaStream, 128); + let coreAndEventCanvas = document.createElement("canvas"); + coreAndEventCanvas.width = 640; + coreAndEventCanvas.height = 200; + + console.log("starting playthrough."); + mediaStream.play(); + visCore.analyze(); + document.body.appendChild(coreAndEventCanvas); + + bindHorizontalBar(coreAndEventCanvas, visCore); + }); + +}); \ No newline at end of file