diff --git a/light-programs/LightController.js b/light-programs/LightController.js
index 03b7a58..1b11c18 100644
--- a/light-programs/LightController.js
+++ b/light-programs/LightController.js
@@ -2,11 +2,14 @@ const Geometry = require('./Geometry')
const _ = require('lodash');
const programNames = [
- "PROGRAM_Main",
+ "shapes",
+ "musicFrequencyDot",
+ "frequencyActivation",
+ "musicVolumeDot",
// "PROGRAM_Transition",
// "PROGRAM_Triangulo",
+ "PROGRAM_Main",
"rays",
- "shapes",
"stripe-patterns",
"sound-waves",
"radial",
@@ -19,13 +22,11 @@ const programNames = [
"circles",
"musicFlow",
"rainbow",
- "musicVolumeDot",
"stars",
"debugSetup",
"debugShapes",
"all-off",
"all-white",
- "leap-test"
]
const Emitter = require('events')
@@ -145,8 +146,9 @@ module.exports = class LightController {
}
}
- updateLeds(leds) {
- lightsSampleEmitter.emit('lights', leds)
- this.setLightsCbk(leds)
+ updateLeds(rgbaLeds) {
+ const rgbLeds = _.map(rgbaLeds, rgba => rgba.slice(0, 3));
+ lightsSampleEmitter.emit('lights', rgbLeds)
+ this.setLightsCbk(rgbLeds)
}
}
diff --git a/light-programs/base-programs/SoundBasedFunction.js b/light-programs/base-programs/SoundBasedFunction.js
index 338815b..cd0f9b5 100644
--- a/light-programs/base-programs/SoundBasedFunction.js
+++ b/light-programs/base-programs/SoundBasedFunction.js
@@ -6,7 +6,19 @@ const soundEmitter = require("../../sound-broadcast")
// Fake sound wave with random
let lastRandom = 0;
let realSound = 0;
-let currentAudioFrame = null;
+
+
+let lastFrameData = {
+ centroid: 0,
+ rms: 0,
+ spectralBands: {bass: {energy: 0}},
+ filteredBands: {bass: {energy: 0, rms: 25}},
+ movingStats: {rms: {value: 0, normalizedValue: 0}},
+ spectralCentroid: {bin: 100}
+};
+
+let currentAudioFrame = lastFrameData;
+
let fakingSoundInterval = 0;
let t = 0;
function startFakeSound(){
@@ -15,18 +27,52 @@ function startFakeSound(){
// Magic formula to simulate song audio volume change?
realSound = Math.min(1, Math.max(0, Math.pow(Math.random(), 2)*0.2+realSound*0.7+Math.sin(t*7)/10+Math.sin(t/3)/10));
t += (25/1000)
+
+ lastFrameData = {rms: realSound, centroid: 50}
}, 25)
}
// After 1sec without mic sound, fake wave
let fakeSoundTimeout = setTimeout(startFakeSound, 1000)
-soundEmitter.on('processedaudioframe', frame => {
+let absolutefft = _.range(0,512).map(()=> 0);
+let maxabsolutefft = _.range(0,512).map(()=> 0);
+
+let medianVolume11 = _.map(_.range(11), () => 0)
+let averageVolume = 0;
+let averageRelativeVolume = 0;
+let averageVolumeSmoothed = 0;
+let averageVolumeSmoothedSlow = 0;
+let averageRelativeVolumeSmoothed = 0;
+let medianVolume = 0
+let maxVolume = 0;
+
+soundEmitter.on('processedaudioframe', (frame) => {
+ let {center: lastFrame} = frame;
realSound = frame.center.rms;
- currentAudioFrame = frame;
+ realSound = lastFrame.rms;
+
clearTimeout(fakeSoundTimeout)
clearInterval(fakingSoundInterval)
fakeSoundTimeout = setTimeout(startFakeSound, 1000)
+
+ currentAudioFrame = frame;
+ lastFrameData = lastFrame
+
+ _.each(maxabsolutefft, (v, i) => maxabsolutefft[i] = Math.max(maxabsolutefft[i]*0.99,lastFrame.absolutefft[i]));
+ _.each(absolutefft, (v, i) => absolutefft[i] = absolutefft[i]*0.5+0.5*lastFrame.absolutefft[i]);
+
+ averageVolume = realSound;
+ averageVolumeSmoothed = (averageVolume + 2 * averageVolumeSmoothed) / 3
+ averageVolumeSmoothedSlow = (averageVolume + 20 * averageVolumeSmoothedSlow) / 21
+
+ medianVolume11.push(averageRelativeVolume)
+ medianVolume11 = medianVolume11.slice(1)
+ medianVolume = _.sortBy(medianVolume11)[5]
+
+ maxVolume = (Math.max(maxVolume, averageVolume)*500+averageVolume)/501;
+ averageRelativeVolume = averageVolume / (maxVolume || 1)
+ averageRelativeVolumeSmoothed = averageVolumeSmoothed / (maxVolume || 1)
})
//
@@ -39,34 +85,8 @@ soundEmitter.on('processedaudioframe', frame => {
// fakeSoundTimeout = setTimeout(startFakeSound, 1000)
// })
-let averageVolume = 0;
-let averageRelativeVolume = 0;
-let averageVolumeSmoothed = 0;
-let averageVolumeSmoothedSlow = 0;
-let averageRelativeVolumeSmoothed = 0;
-let medianVolume15 = _.map(_.range(15), () => 0)
-let medianVolume = 0
let lastTime = new Date();
-let maxVolume = 0;
let processInterval = setTimeout(function computeSoundStats() {
- // calculate average
- averageVolume = realSound;
- averageVolumeSmoothed = (averageVolume + 2 * averageVolumeSmoothed) / 3
- averageVolumeSmoothedSlow = (averageVolume + 20 * averageVolumeSmoothedSlow) / 21
-
- // Plot
- // self.plotEnergyHistogram(self);
-
-
- // self.bassesAverageVolume = getAverageVolume(array, 32);
- maxVolume = (Math.max(maxVolume, averageVolume)*300+averageVolume)/301;
- averageRelativeVolume = averageVolume / (maxVolume || 1)
- averageRelativeVolumeSmoothed = averageVolumeSmoothed / (maxVolume || 1)
-
- medianVolume15.push(averageRelativeVolume)
- medianVolume15 = medianVolume15.slice(1)
- medianVolume = _.sortBy(medianVolume15)[7]
-
soundEmitter.emit('volume', {level: averageRelativeVolume, max: maxVolume})
// console.log("Last audio: " + (new Date() - lastTime) + "ms "+self.averageVolume)
@@ -87,7 +107,7 @@ module.exports = class SoundBasedFunction extends TimeTickedFunction{
this.averageRelativeVolume = averageRelativeVolume;
this.averageVolumeSmoothed = averageVolumeSmoothed;
this.averageVolumeSmoothedSlow = averageVolumeSmoothedSlow;
- this.medianVolume15 = medianVolume15
+ this.medianVolume11 = medianVolume11
this.medianVolume = medianVolume
let self = this;
@@ -102,9 +122,14 @@ module.exports = class SoundBasedFunction extends TimeTickedFunction{
self.averageRelativeVolume = averageRelativeVolume
self.averageRelativeVolumeSmoothed = averageRelativeVolumeSmoothed
- self.medianVolume15 = medianVolume15
+ self.medianVolume11 = medianVolume11
self.medianVolume = medianVolume
+ self.centroid = lastFrameData.centroid;
+ self.lastFrame = lastFrameData;
+ self.absolutefft = absolutefft;
+ self.maxabsolutefft = maxabsolutefft;
+
self.processInterval = setTimeout(updateValues, 1000/self.config.fps);
}, 1000/self.config.fps);
diff --git a/light-programs/programs/frequencyActivation.js b/light-programs/programs/frequencyActivation.js
new file mode 100644
index 0000000..8d77997
--- /dev/null
+++ b/light-programs/programs/frequencyActivation.js
@@ -0,0 +1,51 @@
+const SoundBasedFunction = require("./../base-programs/SoundBasedFunction");
+const ColorUtils = require("./../utils/ColorUtils");
+
+module.exports = class MusicVolumeDot extends SoundBasedFunction{
+ constructor(config, leds) {
+ super(config, leds);
+ }
+
+ start(config, draw, done){
+ this.lastVolume = new Array(this.numberOfLeds+1).join('0').split('').map(() => [0,0,0]);
+ this.time = 0;
+ this.maxVolume = 0;
+
+ super.start(config, draw, done)
+ }
+
+ // Override parent method
+ drawFrame(draw, done){
+ this.time += this.config.speed;
+
+ let size = this.config.zoom;
+ if(this.absolutefft) {
+ for (let i = 0; i < this.numberOfLeds; i++) {
+ let pos = Math.floor((i % 150)/size);
+ let vol = this.config.multiplier * this.absolutefft[pos+5]/10;
+
+ let newVal = ColorUtils.HSVtoRGB(vol, 1, Math.min(vol, 1));
+
+ this.lastVolume[i] = newVal;
+ }
+ }
+
+ draw(this.lastVolume);
+ done();
+ }
+
+ static presets(){
+ return {
+ }
+ }
+
+ // Override and extend config Schema
+ static configSchema(){
+ let res = super.configSchema();
+ res.multiplier = {type: Number, min: 0, max: 2, step: 0.01, default: 1};
+ res.zoom = {type: Number, min: 1, max: 32, step: 1, default: 4};
+ res.numberOfOnLeds = {type: Number, min: 1, max: 100, step: 1, default: 40};
+ res.cutThreshold = {type: Number, min: 0, max: 1, step: 0.01, default: 0.45};
+ return res;
+ }
+}
\ No newline at end of file
diff --git a/light-programs/programs/musicFrequencyDot.js b/light-programs/programs/musicFrequencyDot.js
new file mode 100644
index 0000000..3b182d0
--- /dev/null
+++ b/light-programs/programs/musicFrequencyDot.js
@@ -0,0 +1,87 @@
+const SoundBasedFunction = require("./../base-programs/SoundBasedFunction");
+const ColorUtils = require("./../utils/ColorUtils");
+
+module.exports = class MusicVolumeDot extends SoundBasedFunction{
+ constructor(config, leds) {
+ super(config, leds);
+ }
+
+ start(config, draw, done){
+ this.lastVolume = new Array(this.numberOfLeds+1).join('0').split('').map(() => [0,0,0]);
+ this.time = 0;
+ this.maxVolume = 0;
+
+ this.maxCentroid = 140;
+ this.minCentroid = 139;
+
+ super.start(config, draw, done)
+ }
+
+ // Override parent method
+ drawFrame(draw, done){
+ this.time += this.config.speed;
+
+ // let vol = this.averageRelativeVolume*this.config.multiplier;
+ let vol = this.lastFrame.spectralBands.bass.energy/100*this.config.multiplier;
+
+ // Como las luces tenues son MUY fuertes igual, a partir de cierto valor "las bajamos"
+ if(vol < this.config.cutThreshold){
+ vol = 0;
+ } else {
+ vol = (vol - this.config.cutThreshold) / (1-this.config.cutThreshold)
+ }
+
+ // let centroidHue = (this.lastFrame.spectralCentroid.bin - this.minCentroid) / (this.maxCentroid - this.minCentroid);
+ // this.maxCentroid = Math.max(this.lastFrame.spectralCentroid.bin, this.maxCentroid)
+ // this.minCentroid = Math.min(this.lastFrame.spectralCentroid.bin, this.minCentroid)
+ if(this.lastFrame.filteredBands) {
+ let bass = this.lastFrame.filteredBands.bass.movingStats.rms.normalizedValue;
+ let r = Math.round(255 * bass * bass * 0.5);
+ let mid = this.lastFrame.filteredBands.mid.movingStats.rms.normalizedValue;
+ let g = Math.round(255 * mid * mid * 4);
+ let high = this.lastFrame.filteredBands.high.movingStats.rms.normalizedValue;
+ let b = Math.round(255 * high * high * 4);
+
+
+ let width = Math.round((this.numberOfLeds / this.config.numberOfOnLeds));
+
+ for (let i = 0; i < this.numberOfLeds; i += 1) {
+ let rms = this.lastFrame.movingStats.rms.normalizedValue;
+ let explosion = Math.ceil(this.config.multiplier * rms * rms * rms * width / 3)
+ if (Math.abs((i % width - width/2)) < explosion) {
+ this.lastVolume[i] = [r, g, b];
+ } else {
+ this.lastVolume[i] = [0, 0, 0];
+ }
+
+ // if (i % width === 0) {
+ // this.lastVolume[i] = [r, 0, 0];
+ // } else if (i % width === Math.floor(width/3)) {
+ // this.lastVolume[i + Math.floor(width/3)] = [0, g, 0];
+ // } else if (i % width === Math.floor(2*width/3)) {
+ // this.lastVolume[i + 2 * Math.floor(width/3)] = [0, 0, b];
+ // } else {
+ // this.lastVolume[i] = [0, 0, 0];
+ // }
+
+ }
+ }
+
+ draw(this.lastVolume);
+ done();
+ }
+
+ static presets(){
+ return {
+ }
+ }
+
+ // Override and extend config Schema
+ static configSchema(){
+ let res = super.configSchema();
+ res.multiplier = {type: Number, min: 0, max: 2, step: 0.01, default: 1};
+ res.numberOfOnLeds = {type: Number, min: 1, max: 100, step: 1, default: 40};
+ res.cutThreshold = {type: Number, min: 0, max: 1, step: 0.01, default: 0.45};
+ return res;
+ }
+}
\ No newline at end of file
diff --git a/light-programs/programs/musicVolumeDot.js b/light-programs/programs/musicVolumeDot.js
index e4e078e..0a33f32 100644
--- a/light-programs/programs/musicVolumeDot.js
+++ b/light-programs/programs/musicVolumeDot.js
@@ -18,7 +18,8 @@ module.exports = class MusicVolumeDot extends SoundBasedFunction{
drawFrame(draw, done){
this.time += this.config.speed;
- let vol = this.averageRelativeVolume*this.config.multiplier;
+ // let vol = this.averageRelativeVolume*this.config.multiplier;
+ let vol = this.currentAudioFrame.center.movingStats.rms.normalizedValue*this.config.multiplier;
// Como las luces tenues son MUY fuertes igual, a partir de cierto valor "las bajamos"
if(vol < this.config.cutThreshold){
diff --git a/mic/mic.js b/mic/mic.js
index 5090d60..4a4373a 100644
--- a/mic/mic.js
+++ b/mic/mic.js
@@ -9,9 +9,9 @@ var mic = function mic(options) {
options = options || {};
var that = {};
var endian = osEndianness == "BE"? "big" : "little";
- var bitwidth = 32;
- var encoding = 'floating-point';
- var rate = that._sampleRate = options.rate || 44100;
+ var outputBitwidth = 32;
+ var outputEncoding = 'floating-point';
+ var outputRate = that._sampleRate = options.rate || 44100;
var channels = that._channels = options.channels || 1;
if (channels != 1) {
// TODO: stereo support.
@@ -21,7 +21,7 @@ var mic = function mic(options) {
var exitOnSilence = options.exitOnSilence || 0;
var fileType = options.fileType || 'raw';
var frameSize = options.frameSize || 512;
- var bufferSize = frameSize * channels * bitwidth / 8;
+ var bufferSize = frameSize * channels * outputBitwidth / 8;
var debug = options.debug || false;
var format, formatEndian, formatEncoding;
var audioProcess = null;
@@ -36,28 +36,43 @@ var mic = function mic(options) {
}
// Setup format variable for arecord call
- if(encoding === 'unsigned-integer') {
+ if(outputEncoding === 'unsigned-integer') {
formatEncoding = 'U';
} else {
formatEncoding = 'S';
}
- format = formatEncoding + bitwidth + '_' + osEndianness;
+ format = formatEncoding + outputBitwidth + '_' + osEndianness;
that.start = function start() {
if(audioProcess === null) {
if(isWindows){
- var params = ['-b', bitwidth, '--endian', endian,
- '-c', channels, '-r', rate, '-e', encoding,
- '-t' , 'waveaudio', 'default', '-p', '--buffer', bufferSize, '-V',
- '-V'];
+ var params = [
+ // Parameters for input (-t wave audio)
+ // '-b', '16',
+ // '--endian', endian,
+ '-c', channels,
+ // '-r', '44100',
+ // '-e', 'signed-integer',
+ '-t' , 'waveaudio', 'default',
+
+ // Parameters for output (- means pipe it)
+ '-b', outputBitwidth,
+ '--endian', endian,
+ '-c', channels,
+ '-r', outputRate,
+ '-e', outputEncoding,
+ '--buffer', bufferSize/8,
+ '-t' , 'raw',
+ '-'
+ ];
audioProcess = spawn('sox', params, audioProcessOptions)
console.log(params.join(" "))
}
else if(isMac){
- let params = ['-b', bitwidth, '--endian', endian,
- '-c', channels, '-r', rate, '-e', encoding,
+ let params = ['-b', outputBitwidth, '--endian', endian,
+ '-c', channels, '-r', outputRate, '-e', outputEncoding,
'-t', fileType, '--buffer', bufferSize, '-'];
console.log("rec", params.join(' '))
@@ -65,7 +80,7 @@ var mic = function mic(options) {
}
else {
// TODO: fix this branch, no idea about the args for this program.
- let params = ['-c', channels, '-r', rate, '-f',
+ let params = ['-c', channels, '-r', outputRate, '-f',
format, '-D', device, '-B', '100000'];
console.log("arecord", params.join(' '))
diff --git a/public/lightsSimulator.js b/public/lightsSimulator.js
index 499abac..b9990b5 100644
--- a/public/lightsSimulator.js
+++ b/public/lightsSimulator.js
@@ -13,6 +13,9 @@ class LightsSimulator extends React.Component {
this.lastFrameTime = performance.now();
this.lastFPS = 0;
this.frameCount = 0;
+
+ this.onVisibilityChange = this.onVisibilityChange.bind(this);
+ this.onFocusChange = this.onFocusChange.bind(this);
}
turnOnSimulation() {
@@ -30,22 +33,48 @@ class LightsSimulator extends React.Component {
socket.emit('stopSamplingLights', layout => {});
}
+ decodeLedsColorsFromString(encodedLights) {
+ let bytes = Uint8Array.from(atob(encodedLights), c => c.charCodeAt(0));
+
+ let byLed = new Array(bytes.length / 3);
+ for (let i = 0; i < bytes.length / 3; i += 1) {
+ byLed[i] = [bytes[i * 3], bytes[i * 3 + 1], bytes[i * 3 + 2]];
+ }
+ return byLed;
+ }
+
+ onVisibilityChange() {
+ if (document.hidden && this.state.renderingEnabled) {
+ this.turnOffSimulation();
+ } else if (!document.hidden && this.state.renderingEnabled) {
+ this.turnOnSimulation();
+ }
+ }
+
+ onFocusChange() {
+ debugger;
+ if (!document.hasFocus() && this.state.renderingEnabled) {
+ this.turnOffSimulation();
+ } else if (document.hasFocus() && this.state.renderingEnabled) {
+ this.turnOnSimulation();
+ }
+ }
+
componentDidMount() {
- socket.on('lightsSample', lights => {
+ socket.on('lightsSample', encodedLights => {
+ const lights = this.decodeLedsColorsFromString(encodedLights);
console.log("Lights data");
this.drawCanvas(lights);
});
- document.addEventListener('visibilitychange', () => {
- if (document.hidden && this.state.renderingEnabled) {
- this.turnOffSimulation();
- } else if (!document.hidden && this.state.renderingEnabled) {
- this.turnOnSimulation();
- }
- });
+ document.addEventListener('visibilitychange', this.onVisibilityChange);
+ document.onblur = this.onFocusChange;
+ document.onfocus = this.onFocusChange;
}
componentWillUnmount() {
+ document.removeEventListener('visibilitychange', this.onVisibilityChange);
+ // document.removeEventListener('blur', this.onFocusChange);
//this.stopCurrent()
}
diff --git a/public/lightsSimulator.js.map b/public/lightsSimulator.js.map
index a6f9b29..def8392 100644
--- a/public/lightsSimulator.js.map
+++ b/public/lightsSimulator.js.map
@@ -1 +1 @@
-{"version":3,"sources":["lightsSimulator.jsx"],"names":[],"mappings":"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","file":"lightsSimulator.js","sourcesContent":["if (!window.socket) {\n window.socket = io();\n}\n\nclass LightsSimulator extends React.Component {\n constructor() {\n super(...arguments)\n\n this.state = {\n renderingEnabled: false\n }\n\n this.lastFrameTime = performance.now();\n this.lastFPS = 0;\n this.frameCount = 0;\n }\n\n turnOnSimulation() {\n socket.emit('startSamplingLights', (layout) => {\n this.geometryX = layout.geometry.x\n this.geometryY = layout.geometry.y\n this.minX = _.min(this.geometryX)\n this.minY = _.min(this.geometryY)\n this.maxX = _.max(this.geometryX)\n this.maxY = _.max(this.geometryY)\n });\n }\n\n turnOffSimulation() {\n socket.emit('stopSamplingLights', (layout) => {});\n }\n\n componentDidMount() {\n socket.on('lightsSample', (lights) => {\n console.log(\"Lights data\")\n this.drawCanvas(lights)\n });\n\n document.addEventListener('visibilitychange', () =>{\n if(document.hidden && this.state.renderingEnabled) {\n this.turnOffSimulation();\n } else if (!document.hidden && this.state.renderingEnabled) {\n this.turnOnSimulation();\n }\n })\n }\n\n componentWillUnmount() {\n //this.stopCurrent()\n }\n\n componentDidUpdate(oldProps, oldState) {\n if (oldState.func !== this.state.func) {\n //this.startCurrent()\n }\n }\n\n drawCanvas(lights) {\n const drawStartTime = performance.now();\n\n const leds = this.geometryX.length;\n const ctx = this.refs.canvas.getContext('2d');\n\n ctx.globalCompositeOperation = 'source-over';\n ctx.fillStyle = 'black';\n ctx.fillRect(0, 0, this.props.width, this.props.height);\n\n ctx.globalCompositeOperation = 'lighter';\n\n if (this.state.renderingEnabled) {\n const X = this.geometryX;\n const Y = this.geometryY;\n\n for (let i = 0; i < leds; i++) {\n const [r, g, b] = lights[i];\n\n let SCALE = 4;\n const x = X[i]*SCALE + 5*SCALE;\n const y = Y[i]*SCALE + 5*SCALE;\n\n let power = r + g + b;\n if (power < 0) power = 0;\n\n let lightRadius = (40 + (r + g + b) / (255 * 3) * 80) * 1;\n\n let m = 2;\n if (power < 200) {\n m = 4;\n } else if (power < 100) {\n m = 8;\n } else if (power < 50) {\n m = 16;\n }\n let [or, og, ob] = [r * m, g * m, b * m];\n if (or > 255) or = 255;\n if (og > 255) og = 255;\n if (ob > 255) ob = 255;\n\n ctx.beginPath();\n\n lightRadius = lightRadius / 24;\n ctx.fillStyle = `rgba(${or}, ${og}, ${ob}, 1)`;\n\n // let gradient = ctx.createRadialGradient(x, y, 0, x, y, lightRadius)\n // gradient.addColorStop(0, `rgba(${or}, ${og}, ${ob}, 1)`)\n // // gradient.addColorStop(0.065, `rgba(${or}, ${og}, ${ob}, 1)`)\n // gradient.addColorStop(0.25, `rgba(${r}, ${g}, ${b}, 1)`)\n // // gradient.addColorStop(0.25, `rgba(${r}, ${g}, ${b}, 0.5)`)\n // gradient.addColorStop(0.5, `rgba(${r}, ${g}, ${b}, 0.25)`)\n // // gradient.addColorStop(1, `rgba(${0}, ${0}, ${0}, 1)`)\n // gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`)\n // ctx.fillStyle = gradient\n\n\n ctx.arc(x, y, lightRadius, Math.PI * 2, false);\n ctx.fill();\n }\n\n this.frameCount++;\n\n let drawMilliseconds = performance.now() - drawStartTime;\n let timeSinceLastFPS = performance.now() - this.lastFrameTime;\n if (timeSinceLastFPS > 100) {\n this.lastFPS = 1000 * this.frameCount / timeSinceLastFPS;\n this.frameCount = 0;\n this.lastFrameTime = performance.now();\n }\n\n ctx.fillStyle = 'white';\n ctx.font = \"12px sans-serif\";\n\n ctx.fillText(`Sim overhead FPS: ${Math.floor(1000/drawMilliseconds)}`, 10, 40);\n ctx.fillText(`FPS: ${this.lastFPS.toFixed(1)}`, 10, 20);\n }\n }\n\n __changeSelection() {\n if(this.state.renderingEnabled) {\n this.turnOffSimulation();\n } else {\n this.turnOnSimulation();\n }\n this.setState({renderingEnabled: !this.state.renderingEnabled});\n }\n\n render() {\n return
\n }\n}"]}
\ No newline at end of file
+{"version":3,"sources":["lightsSimulator.jsx"],"names":[],"mappings":"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","file":"lightsSimulator.js","sourcesContent":["if (!window.socket) {\n window.socket = io();\n}\n\nclass LightsSimulator extends React.Component {\n constructor() {\n super(...arguments)\n\n this.state = {\n renderingEnabled: false\n }\n\n this.lastFrameTime = performance.now();\n this.lastFPS = 0;\n this.frameCount = 0;\n\n this.onVisibilityChange = this.onVisibilityChange.bind(this);\n this.onFocusChange = this.onFocusChange.bind(this);\n }\n\n turnOnSimulation() {\n socket.emit('startSamplingLights', (layout) => {\n this.geometryX = layout.geometry.x\n this.geometryY = layout.geometry.y\n this.minX = _.min(this.geometryX)\n this.minY = _.min(this.geometryY)\n this.maxX = _.max(this.geometryX)\n this.maxY = _.max(this.geometryY)\n });\n }\n\n turnOffSimulation() {\n socket.emit('stopSamplingLights', (layout) => {});\n }\n\n decodeLedsColorsFromString(encodedLights) {\n let bytes = Uint8Array.from(atob(encodedLights), c => c.charCodeAt(0))\n\n let byLed = new Array(bytes.length / 3);\n for (let i = 0; i < bytes.length/3; i += 1) {\n byLed[i] = [bytes[i*3], bytes[i*3 + 1], bytes[i*3 + 2]];\n }\n return byLed;\n }\n\n onVisibilityChange() {\n if(document.hidden && this.state.renderingEnabled) {\n this.turnOffSimulation();\n } else if (!document.hidden && this.state.renderingEnabled) {\n this.turnOnSimulation();\n }\n }\n\n onFocusChange() {\n debugger;\n if(!document.hasFocus() && this.state.renderingEnabled) {\n this.turnOffSimulation();\n } else if (document.hasFocus() && this.state.renderingEnabled) {\n this.turnOnSimulation();\n }\n }\n\n componentDidMount() {\n socket.on('lightsSample', (encodedLights) => {\n const lights = this.decodeLedsColorsFromString(encodedLights)\n console.log(\"Lights data\")\n this.drawCanvas(lights)\n });\n\n document.addEventListener('visibilitychange', this.onVisibilityChange);\n document.onblur = this.onFocusChange;\n document.onfocus = this.onFocusChange;\n }\n\n componentWillUnmount() {\n document.removeEventListener('visibilitychange', this.onVisibilityChange);\n // document.removeEventListener('blur', this.onFocusChange);\n //this.stopCurrent()\n }\n\n componentDidUpdate(oldProps, oldState) {\n if (oldState.func !== this.state.func) {\n //this.startCurrent()\n }\n }\n\n drawCanvas(lights) {\n const drawStartTime = performance.now();\n\n const leds = this.geometryX.length;\n const ctx = this.refs.canvas.getContext('2d');\n\n ctx.globalCompositeOperation = 'source-over';\n ctx.fillStyle = 'black';\n ctx.fillRect(0, 0, this.props.width, this.props.height);\n\n ctx.globalCompositeOperation = 'lighter';\n\n if (this.state.renderingEnabled) {\n const X = this.geometryX;\n const Y = this.geometryY;\n\n for (let i = 0; i < leds; i++) {\n const [r, g, b] = lights[i];\n\n let SCALE = 4;\n const x = X[i]*SCALE + 5*SCALE;\n const y = Y[i]*SCALE + 5*SCALE;\n\n let power = r + g + b;\n if (power < 0) power = 0;\n\n let lightRadius = (40 + (r + g + b) / (255 * 3) * 80) * 1;\n\n let m = 2;\n if (power < 200) {\n m = 4;\n } else if (power < 100) {\n m = 8;\n } else if (power < 50) {\n m = 16;\n }\n let [or, og, ob] = [r * m, g * m, b * m];\n if (or > 255) or = 255;\n if (og > 255) og = 255;\n if (ob > 255) ob = 255;\n\n ctx.beginPath();\n\n lightRadius = lightRadius / 24;\n ctx.fillStyle = `rgba(${or}, ${og}, ${ob}, 1)`;\n\n // let gradient = ctx.createRadialGradient(x, y, 0, x, y, lightRadius)\n // gradient.addColorStop(0, `rgba(${or}, ${og}, ${ob}, 1)`)\n // // gradient.addColorStop(0.065, `rgba(${or}, ${og}, ${ob}, 1)`)\n // gradient.addColorStop(0.25, `rgba(${r}, ${g}, ${b}, 1)`)\n // // gradient.addColorStop(0.25, `rgba(${r}, ${g}, ${b}, 0.5)`)\n // gradient.addColorStop(0.5, `rgba(${r}, ${g}, ${b}, 0.25)`)\n // // gradient.addColorStop(1, `rgba(${0}, ${0}, ${0}, 1)`)\n // gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`)\n // ctx.fillStyle = gradient\n\n\n ctx.arc(x, y, lightRadius, Math.PI * 2, false);\n ctx.fill();\n }\n\n this.frameCount++;\n\n let drawMilliseconds = performance.now() - drawStartTime;\n let timeSinceLastFPS = performance.now() - this.lastFrameTime;\n if (timeSinceLastFPS > 100) {\n this.lastFPS = 1000 * this.frameCount / timeSinceLastFPS;\n this.frameCount = 0;\n this.lastFrameTime = performance.now();\n }\n\n ctx.fillStyle = 'white';\n ctx.font = \"12px sans-serif\";\n\n ctx.fillText(`Sim overhead FPS: ${Math.floor(1000/drawMilliseconds)}`, 10, 40);\n ctx.fillText(`FPS: ${this.lastFPS.toFixed(1)}`, 10, 20);\n }\n }\n\n __changeSelection() {\n if(this.state.renderingEnabled) {\n this.turnOffSimulation();\n } else {\n this.turnOnSimulation();\n }\n this.setState({renderingEnabled: !this.state.renderingEnabled});\n }\n\n render() {\n return \n }\n}"]}
\ No newline at end of file
diff --git a/public/lightsSimulator.jsx b/public/lightsSimulator.jsx
index a4bd19d..df0cb0a 100644
--- a/public/lightsSimulator.jsx
+++ b/public/lightsSimulator.jsx
@@ -13,6 +13,9 @@ class LightsSimulator extends React.Component {
this.lastFrameTime = performance.now();
this.lastFPS = 0;
this.frameCount = 0;
+
+ this.onVisibilityChange = this.onVisibilityChange.bind(this);
+ this.onFocusChange = this.onFocusChange.bind(this);
}
turnOnSimulation() {
@@ -30,22 +33,48 @@ class LightsSimulator extends React.Component {
socket.emit('stopSamplingLights', (layout) => {});
}
+ decodeLedsColorsFromString(encodedLights) {
+ let bytes = Uint8Array.from(atob(encodedLights), c => c.charCodeAt(0))
+
+ let byLed = new Array(bytes.length / 3);
+ for (let i = 0; i < bytes.length/3; i += 1) {
+ byLed[i] = [bytes[i*3], bytes[i*3 + 1], bytes[i*3 + 2]];
+ }
+ return byLed;
+ }
+
+ onVisibilityChange() {
+ if(document.hidden && this.state.renderingEnabled) {
+ this.turnOffSimulation();
+ } else if (!document.hidden && this.state.renderingEnabled) {
+ this.turnOnSimulation();
+ }
+ }
+
+ onFocusChange() {
+ debugger;
+ if(!document.hasFocus() && this.state.renderingEnabled) {
+ this.turnOffSimulation();
+ } else if (document.hasFocus() && this.state.renderingEnabled) {
+ this.turnOnSimulation();
+ }
+ }
+
componentDidMount() {
- socket.on('lightsSample', (lights) => {
+ socket.on('lightsSample', (encodedLights) => {
+ const lights = this.decodeLedsColorsFromString(encodedLights)
console.log("Lights data")
this.drawCanvas(lights)
});
- document.addEventListener('visibilitychange', () =>{
- if(document.hidden && this.state.renderingEnabled) {
- this.turnOffSimulation();
- } else if (!document.hidden && this.state.renderingEnabled) {
- this.turnOnSimulation();
- }
- })
+ document.addEventListener('visibilitychange', this.onVisibilityChange);
+ document.onblur = this.onFocusChange;
+ document.onfocus = this.onFocusChange;
}
componentWillUnmount() {
+ document.removeEventListener('visibilitychange', this.onVisibilityChange);
+ // document.removeEventListener('blur', this.onFocusChange);
//this.stopCurrent()
}
diff --git a/public/microphoneViewer.js b/public/microphoneViewer.js
index 6d360ef..83465aa 100644
--- a/public/microphoneViewer.js
+++ b/public/microphoneViewer.js
@@ -31,7 +31,8 @@ class MicrophoneViewer extends React.Component {
socket.on('micViewerReady', this._initializeState.bind(this));
socket.on('micSample', samples => {
- _.each(samples, ({ level, max }) => this.plotEnergyHistogram(level, max));
+ // _.each(samples, ({level, max}) => this.plotEnergyHistogram(level, max))
+ _.each(samples, sample => this.plotPerBandHistogram(sample));
});
this.createHistogramCanvas();
@@ -62,10 +63,12 @@ class MicrophoneViewer extends React.Component {
plotEnergyHistogram(level, max) {
let histogram = document.getElementById("music");
- let h = Math.round(level * 50);
+ level = level / 100;
+ let HEIGHT = this.canvasCtx.canvas.height;
+ let h = Math.round(level * HEIGHT);
this.canvasCtx.fillStyle = `hsl(${Math.round((1 - h / 50 % 1 + 0) * 255)}, ${50}%, ${50}%)`;
// this.canvasCtx.fillStyle = `#ff5500`;
- this.canvasCtx.fillRect(300, 50 - h, 2, h);
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, 50 - h, 2, h);
// Move all left
let imageData = this.canvasCtx.getImageData(2, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);
this.canvasCtx.putImageData(imageData, 0, 0);
@@ -75,9 +78,70 @@ class MicrophoneViewer extends React.Component {
this.canvasCtx.fillStyle = 'white';
this.canvasCtx.font = "12px monospace";
this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);
- this.canvasCtx.fillText(`MAX Vol: ${Math.round(max * 100)}`, 310, 15);
+ this.canvasCtx.fillText(`MAX Vol: ${Math.round(max * 100)}`, this.canvasCtx.canvas.width - 90, 15);
// this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);
- this.canvasCtx.fillText(`REL Vol: ${Math.round(level * 100)}`, 310, 45);
+ this.canvasCtx.fillText(`REL Vol: ${Math.round(level)}`, this.canvasCtx.canvas.width - 90, 45);
+ }
+
+ plotPerBandHistogram({ bass, mid, high, onsetbass, onsetmid, onsethigh }) {
+ let histogram = document.getElementById("music");
+ let r = Math.round(bass * 255);
+ let g = Math.round(mid * 255);
+ let b = Math.round(high * 255);
+ let max = 0;
+ let level = Math.min(1, (r + g + b) / (3 * 255));
+
+ // let w = 2;
+ // let HEIGHT = this.canvasCtx.canvas.height;
+ // let h = Math.round(level * HEIGHT);
+ // this.canvasCtx.fillStyle = `rgb(${r}, ${g}, ${b})`;
+ // this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);
+
+ //
+ let MIN = 30;
+ let w = 2;
+ let HEIGHT = this.canvasCtx.canvas.height / 3;
+ let h = Math.round(level * HEIGHT);
+ this.canvasCtx.globalCompositeOperation = "screen";
+ this.canvasCtx.fillStyle = `rgba(${Math.max(MIN, r)}, ${0}, ${0})`;
+ h = Math.round(r / 255 * HEIGHT);
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);
+ if (onsetbass) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT, w, 5);
+ }
+
+ h = Math.round(g / 255 * HEIGHT);
+ this.canvasCtx.fillStyle = `rgba(${0}, ${Math.max(MIN, g)}, ${0})`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h + HEIGHT, w, h);
+ if (onsetmid) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT, w, 5);
+ }
+
+ h = Math.round(b / 255 * HEIGHT);
+ this.canvasCtx.fillStyle = `rgba(${0}, ${0}, ${Math.max(MIN, b)})`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h + HEIGHT * 2, w, h);
+ if (onsethigh) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT * 2 - 5, w, 5);
+ }
+ //
+ this.canvasCtx.globalCompositeOperation = "source-over";
+
+ // this.canvasCtx.fillStyle = `#ff5500`;
+ // Move all left
+ let imageData = this.canvasCtx.getImageData(w, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);
+ this.canvasCtx.putImageData(imageData, 0, 0);
+ // now clear the right-most pixels:
+ this.canvasCtx.clearRect(this.canvasCtx.canvas.width - w, 0, w, this.canvasCtx.canvas.height);
+
+ this.canvasCtx.fillStyle = 'white';
+ this.canvasCtx.font = "12px monospace";
+ this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);
+ this.canvasCtx.fillText(`MAX Vol: ${Math.round(max * 100)}`, this.canvasCtx.canvas.width - 90, 15);
+ // this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);
+ this.canvasCtx.fillText(`REL Vol: ${Math.round(level * 100)}`, this.canvasCtx.canvas.width - 90, 45);
}
turnOn() {
@@ -95,7 +159,7 @@ class MicrophoneViewer extends React.Component {
{ className: 'mic-client' },
React.createElement(
'canvas',
- { id: 'music', width: '400', height: '50' },
+ { id: 'music', width: '800', height: '300' },
'a'
)
);
diff --git a/public/microphoneViewer.js.map b/public/microphoneViewer.js.map
index 8df8398..3b4542e 100644
--- a/public/microphoneViewer.js.map
+++ b/public/microphoneViewer.js.map
@@ -1 +1 @@
-{"version":3,"sources":["microphoneViewer.jsx"],"names":[],"mappings":"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","file":"microphoneViewer.js","sourcesContent":["if (!window.socket) {\n window.socket = io();\n}\n\nclass MicrophoneViewer extends React.Component {\n constructor() {\n super(...arguments)\n\n this.state = {\n micOn: true,\n connected: false,\n }\n }\n\n _initializeState(state) {\n this.setState({\n connected: true,\n })\n }\n\n _stateChange(state) {\n this.setState({\n selected: state.currentProgramName,\n currentConfig: state.currentConfig,\n remoteChange: true\n })\n console.log(state)\n }\n\n componentDidMount() {\n socket.on('micViewerReady', this._initializeState.bind(this));\n\n socket.on('micSample', samples => {\n _.each(samples, ({level, max}) => this.plotEnergyHistogram(level, max))\n });\n\n this.createHistogramCanvas()\n }\n\n createHistogramCanvas() {\n let c = document.getElementById(\"music\");\n this.canvasCtx = c.getContext(\"2d\");\n this.canvasCtx.clearRect(0, 0, this.canvasCtx.canvas.width, this.canvasCtx.canvas.height);\n this.frame = 0;\n }\n\n componentWillUnmount() {\n //this.stopCurrent()\n }\n\n componentDidUpdate(oldProps, oldState) {\n if (oldState.func !== this.state.func) {\n //this.startCurrent()\n }\n }\n\n handleProgramClick(key, ev) {\n ev.preventDefault()\n this.setCurrentProgram(key)\n }\n\n plotEnergyHistogram(level, max) {\n let histogram = document.getElementById(\"music\");\n\n let h = Math.round(level * 50);\n this.canvasCtx.fillStyle = `hsl(${Math.round((1 - h/50 % 1 + 0)*255)}, ${50}%, ${50}%)`;\n // this.canvasCtx.fillStyle = `#ff5500`;\n this.canvasCtx.fillRect(300, 50 - h, 2, h);\n // Move all left\n let imageData = this.canvasCtx.getImageData(2, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);\n this.canvasCtx.putImageData(imageData, 0, 0);\n // now clear the right-most pixels:\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 2, 0, 2, this.canvasCtx.canvas.height);\n\n this.canvasCtx.fillStyle = 'white'\n this.canvasCtx.font = \"12px monospace\";\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);\n this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, 310, 15);\n // this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);\n this.canvasCtx.fillText(`REL Vol: ${Math.round(level*100)}`, 310, 45);\n }\n\n turnOn(){\n this.setState({micOn: true});\n alert(\"No se duerme\")\n }\n\n turnOff(){\n this.setState({micOn: false})\n }\n\n render() {\n return \n \n
\n }\n}"]}
\ No newline at end of file
+{"version":3,"sources":["microphoneViewer.jsx"],"names":[],"mappings":"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","file":"microphoneViewer.js","sourcesContent":["if (!window.socket) {\n window.socket = io();\n}\n\nclass MicrophoneViewer extends React.Component {\n constructor() {\n super(...arguments)\n\n this.state = {\n micOn: true,\n connected: false,\n }\n }\n\n _initializeState(state) {\n this.setState({\n connected: true,\n })\n }\n\n _stateChange(state) {\n this.setState({\n selected: state.currentProgramName,\n currentConfig: state.currentConfig,\n remoteChange: true\n })\n console.log(state)\n }\n\n componentDidMount() {\n socket.on('micViewerReady', this._initializeState.bind(this));\n\n socket.on('micSample', samples => {\n // _.each(samples, ({level, max}) => this.plotEnergyHistogram(level, max))\n _.each(samples, sample => this.plotPerBandHistogram(sample))\n });\n\n this.createHistogramCanvas()\n }\n\n createHistogramCanvas() {\n let c = document.getElementById(\"music\");\n this.canvasCtx = c.getContext(\"2d\");\n this.canvasCtx.clearRect(0, 0, this.canvasCtx.canvas.width, this.canvasCtx.canvas.height);\n this.frame = 0;\n }\n\n componentWillUnmount() {\n //this.stopCurrent()\n }\n\n componentDidUpdate(oldProps, oldState) {\n if (oldState.func !== this.state.func) {\n //this.startCurrent()\n }\n }\n\n handleProgramClick(key, ev) {\n ev.preventDefault()\n this.setCurrentProgram(key)\n }\n\n plotEnergyHistogram(level, max) {\n let histogram = document.getElementById(\"music\");\n\n level = level /100;\n let HEIGHT = this.canvasCtx.canvas.height;\n let h = Math.round(level * HEIGHT);\n this.canvasCtx.fillStyle = `hsl(${Math.round((1 - h/50 % 1 + 0)*255)}, ${50}%, ${50}%)`;\n // this.canvasCtx.fillStyle = `#ff5500`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, 50 - h, 2, h);\n // Move all left\n let imageData = this.canvasCtx.getImageData(2, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);\n this.canvasCtx.putImageData(imageData, 0, 0);\n // now clear the right-most pixels:\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 2, 0, 2, this.canvasCtx.canvas.height);\n\n this.canvasCtx.fillStyle = 'white'\n this.canvasCtx.font = \"12px monospace\";\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);\n this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, this.canvasCtx.canvas.width - 90, 15);\n // this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);\n this.canvasCtx.fillText(`REL Vol: ${Math.round(level)}`, this.canvasCtx.canvas.width - 90, 45);\n }\n\n plotPerBandHistogram({bass, mid, high, onsetbass, onsetmid, onsethigh}) {\n let histogram = document.getElementById(\"music\");\n let r = Math.round(bass*255);\n let g = Math.round(mid*255);\n let b = Math.round(high*255);\n let max = 0;\n let level = Math.min(1, (r+g+b)/(3*255));\n\n\n\n // let w = 2;\n // let HEIGHT = this.canvasCtx.canvas.height;\n // let h = Math.round(level * HEIGHT);\n // this.canvasCtx.fillStyle = `rgb(${r}, ${g}, ${b})`;\n // this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);\n\n //\n let MIN = 30;\n let w = 2;\n let HEIGHT = this.canvasCtx.canvas.height / 3;\n let h = Math.round(level * HEIGHT);\n this.canvasCtx.globalCompositeOperation = \"screen\";\n this.canvasCtx.fillStyle = `rgba(${Math.max(MIN,r)}, ${0}, ${0})`;\n h = Math.round((r/255) * HEIGHT);\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);\n if(onsetbass) {\n this.canvasCtx.fillStyle = `#fff`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT, w, 5);\n }\n\n h = Math.round((g/255) * HEIGHT);\n this.canvasCtx.fillStyle = `rgba(${0}, ${Math.max(MIN,g)}, ${0})`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h +HEIGHT, w, h);\n if(onsetmid) {\n this.canvasCtx.fillStyle = `#fff`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT, w, 5);\n }\n\n h = Math.round((b/255) * HEIGHT);\n this.canvasCtx.fillStyle = `rgba(${0}, ${0}, ${Math.max(MIN,b)})`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h+HEIGHT*2, w, h);\n if(onsethigh) {\n this.canvasCtx.fillStyle = `#fff`;\n this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT*2-5, w, 5);\n }\n //\n this.canvasCtx.globalCompositeOperation = \"source-over\";\n\n\n\n // this.canvasCtx.fillStyle = `#ff5500`;\n // Move all left\n let imageData = this.canvasCtx.getImageData(w, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);\n this.canvasCtx.putImageData(imageData, 0, 0);\n // now clear the right-most pixels:\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - w, 0, w, this.canvasCtx.canvas.height);\n\n this.canvasCtx.fillStyle = 'white'\n this.canvasCtx.font = \"12px monospace\";\n this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);\n this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, this.canvasCtx.canvas.width - 90, 15);\n // this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);\n this.canvasCtx.fillText(`REL Vol: ${Math.round(level*100)}`, this.canvasCtx.canvas.width - 90, 45);\n }\n\n turnOn(){\n this.setState({micOn: true});\n alert(\"No se duerme\")\n }\n\n turnOff(){\n this.setState({micOn: false})\n }\n\n render() {\n return \n \n
\n }\n}"]}
\ No newline at end of file
diff --git a/public/microphoneViewer.jsx b/public/microphoneViewer.jsx
index e3a72bf..96021aa 100644
--- a/public/microphoneViewer.jsx
+++ b/public/microphoneViewer.jsx
@@ -31,7 +31,8 @@ class MicrophoneViewer extends React.Component {
socket.on('micViewerReady', this._initializeState.bind(this));
socket.on('micSample', samples => {
- _.each(samples, ({level, max}) => this.plotEnergyHistogram(level, max))
+ // _.each(samples, ({level, max}) => this.plotEnergyHistogram(level, max))
+ _.each(samples, sample => this.plotPerBandHistogram(sample))
});
this.createHistogramCanvas()
@@ -62,10 +63,12 @@ class MicrophoneViewer extends React.Component {
plotEnergyHistogram(level, max) {
let histogram = document.getElementById("music");
- let h = Math.round(level * 50);
+ level = level /100;
+ let HEIGHT = this.canvasCtx.canvas.height;
+ let h = Math.round(level * HEIGHT);
this.canvasCtx.fillStyle = `hsl(${Math.round((1 - h/50 % 1 + 0)*255)}, ${50}%, ${50}%)`;
// this.canvasCtx.fillStyle = `#ff5500`;
- this.canvasCtx.fillRect(300, 50 - h, 2, h);
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, 50 - h, 2, h);
// Move all left
let imageData = this.canvasCtx.getImageData(2, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);
this.canvasCtx.putImageData(imageData, 0, 0);
@@ -75,9 +78,74 @@ class MicrophoneViewer extends React.Component {
this.canvasCtx.fillStyle = 'white'
this.canvasCtx.font = "12px monospace";
this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);
- this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, 310, 15);
+ this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, this.canvasCtx.canvas.width - 90, 15);
// this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);
- this.canvasCtx.fillText(`REL Vol: ${Math.round(level*100)}`, 310, 45);
+ this.canvasCtx.fillText(`REL Vol: ${Math.round(level)}`, this.canvasCtx.canvas.width - 90, 45);
+ }
+
+ plotPerBandHistogram({bass, mid, high, onsetbass, onsetmid, onsethigh}) {
+ let histogram = document.getElementById("music");
+ let r = Math.round(bass*255);
+ let g = Math.round(mid*255);
+ let b = Math.round(high*255);
+ let max = 0;
+ let level = Math.min(1, (r+g+b)/(3*255));
+
+
+
+ // let w = 2;
+ // let HEIGHT = this.canvasCtx.canvas.height;
+ // let h = Math.round(level * HEIGHT);
+ // this.canvasCtx.fillStyle = `rgb(${r}, ${g}, ${b})`;
+ // this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);
+
+ //
+ let MIN = 30;
+ let w = 2;
+ let HEIGHT = this.canvasCtx.canvas.height / 3;
+ let h = Math.round(level * HEIGHT);
+ this.canvasCtx.globalCompositeOperation = "screen";
+ this.canvasCtx.fillStyle = `rgba(${Math.max(MIN,r)}, ${0}, ${0})`;
+ h = Math.round((r/255) * HEIGHT);
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h, w, h);
+ if(onsetbass) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT, w, 5);
+ }
+
+ h = Math.round((g/255) * HEIGHT);
+ this.canvasCtx.fillStyle = `rgba(${0}, ${Math.max(MIN,g)}, ${0})`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h +HEIGHT, w, h);
+ if(onsetmid) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT, w, 5);
+ }
+
+ h = Math.round((b/255) * HEIGHT);
+ this.canvasCtx.fillStyle = `rgba(${0}, ${0}, ${Math.max(MIN,b)})`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT - h+HEIGHT*2, w, h);
+ if(onsethigh) {
+ this.canvasCtx.fillStyle = `#fff`;
+ this.canvasCtx.fillRect(this.canvasCtx.canvas.width - 100, HEIGHT + HEIGHT*2-5, w, 5);
+ }
+ //
+ this.canvasCtx.globalCompositeOperation = "source-over";
+
+
+
+ // this.canvasCtx.fillStyle = `#ff5500`;
+ // Move all left
+ let imageData = this.canvasCtx.getImageData(w, 0, this.canvasCtx.canvas.width - 1, this.canvasCtx.canvas.height);
+ this.canvasCtx.putImageData(imageData, 0, 0);
+ // now clear the right-most pixels:
+ this.canvasCtx.clearRect(this.canvasCtx.canvas.width - w, 0, w, this.canvasCtx.canvas.height);
+
+ this.canvasCtx.fillStyle = 'white'
+ this.canvasCtx.font = "12px monospace";
+ this.canvasCtx.clearRect(this.canvasCtx.canvas.width - 100, 0, 100, this.canvasCtx.canvas.height);
+ this.canvasCtx.fillText(`MAX Vol: ${Math.round(max*100)}`, this.canvasCtx.canvas.width - 90, 15);
+ // this.canvasCtx.fillText(` Vol: ${Math.round(this.averageVolume*100)}`, 310, 30);
+ this.canvasCtx.fillText(`REL Vol: ${Math.round(level*100)}`, this.canvasCtx.canvas.width - 90, 45);
}
turnOn(){
@@ -91,7 +159,7 @@ class MicrophoneViewer extends React.Component {
render() {
return
-
+
}
}
\ No newline at end of file
diff --git a/public/test.html b/public/test.html
index 19731f7..45388c8 100644
--- a/public/test.html
+++ b/public/test.html
@@ -37,8 +37,8 @@
#music {
background-color: #333;
- height: 100px;
- width: 400px;
+ /*height: 100px;*/
+ /*width: 400px;*/
}
.state {
diff --git a/public/warro.html b/public/warro.html
index 02e205f..15ee769 100644
--- a/public/warro.html
+++ b/public/warro.html
@@ -51,7 +51,7 @@
#music {
background-color: #333;
- width: 400px;
+ /*width: 400px;*/
}
.state {
diff --git a/server.js b/server.js
index b646a1a..83c3ba3 100644
--- a/server.js
+++ b/server.js
@@ -1,17 +1,25 @@
const _ = require('lodash');
-
const fs = require('fs');
-// const privateKey = fs.readFileSync('sslcert/server.key', 'utf8');
-// const certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
-// const credentials = {key: privateKey, cert: certificate};
-
const express = require('express');
+const { Buffer } = require('buffer');
+
+require('./volume-broadcaster')
+let soundBroadcast = require("./sound-broadcast");
+
const app = express();
const http = require('http').createServer(app);
+
+// // HTTPS
+// const privateKey = fs.readFileSync('sslcert/server.key', 'utf8');
+// const certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
+// const credentials = {key: privateKey, cert: certificate};
// const httpsServer = require('https').createServer(credentials, app);
-require('./volume-broadcaster')
+const lightsToByteString = (ledsColorArray) => {
+ let bytes = _.flatten(ledsColorArray);
+ return Buffer.from(bytes).toString('base64');
+}
exports.createRemoteControl = function(lightProgram, deviceMultiplexer) {
app.use(express.static('public'))
@@ -34,17 +42,42 @@ exports.createRemoteControl = function(lightProgram, deviceMultiplexer) {
const io = require('socket.io').listen(http);
-
let lastVolumes = [];
+ let lastRawVolumes = [];
+ let lastBands = [];
let flushVolume = _.throttle(() => {
io.volatile.emit('micSample', lastVolumes)
lastVolumes = [];
- }, 100)
+ }, 30)
+
+ let avg = 3;
+
+ let last = new Date();
+
+ soundBroadcast.on('processedaudioframe', (frame) => {
+ let timeSinceLastFrame = new Date() - last;
+ if(timeSinceLastFrame > 50) {
+ console.log(`SOUND DROPPING FRAMES: Last processedaudioframe frame: ${timeSinceLastFrame}ms ago`.red)
+ }
+ last = new Date()
- require("./sound-broadcast").on('volume', volData => {
- lastVolumes.push(volData);
- flushVolume();
+ let {center: {filteredBands, movingStats: {rms: {normalizedValue}}}} = frame;
+ lastRawVolumes.push({... _.mapValues(filteredBands, b => b.movingStats.rms.normalizedValue), all: normalizedValue});
+
+ if(lastRawVolumes.length >= avg) {
+ let avgLastVolumes = {
+ bass: _.sum(_.map(lastRawVolumes, 'bass'))/avg,
+ mid: _.sum(_.map(lastRawVolumes, 'mid'))/avg,
+ high: _.sum(_.map(lastRawVolumes, 'high'))/avg,
+ all: _.sum(_.map(lastRawVolumes, 'all'))/avg
+ }
+
+ lastVolumes.push(avgLastVolumes);
+ flushVolume();
+
+ lastRawVolumes.shift();
+ }
})
io.on('connection', (socket) => {
@@ -57,24 +90,26 @@ exports.createRemoteControl = function(lightProgram, deviceMultiplexer) {
})
socket.on('startSamplingLights', (ack) => {
+ console.log('[ON] Web client sampling lights data'.green)
simulating = true
- console.log('Client requested startSamplingLights')
ack(lightProgram.layout)
})
+
socket.on('stopSamplingLights', () => {
- console.log('Client stoppedSamplingLights')
- return simulating = false;
+ console.log('[OFF] Web client stopped sampling lights'.gray)
+ simulating = false;
})
socket.on('restartProgram', () => lightProgram.restart())
let lightsCbk = lights => {
if(simulating) {
- socket.volatile.emit('lightsSample', lights)
+ let encodedColors = lightsToByteString(lights);
+ socket.volatile.emit('lightsSample', encodedColors)
}
}
- console.log("Remote control connnected")
+ console.log("[ON] Remote control connnected".green)
lightProgram.onLights(lightsCbk)
// socket.on('reconnect', function () {
@@ -93,7 +128,7 @@ exports.createRemoteControl = function(lightProgram, deviceMultiplexer) {
})
socket.on('disconnect', function () {
- console.log("Remote control DISCONNNECTED")
+ console.log("[OFF] Remote control DISCONNNECTED".gray)
lightProgram.removeOnLights(lightsCbk)
});