The Next Generation
Electronic
Music
Why don't you recreate it?
Web ftw!
JSConf EU 2014
+
Server
+
+
LEDs
Node.js
Tessel 1
Adafruit NeoPixel
WebSocket
USB
Web Audio API
Wires
JSConf EU 2014: DEMO
Start again
The Next Generation
Notebook
Web Audio API
-
Play a song
-
Manipulate
-
Analyse
// Create new AudioContext
var audio_context = new AudioContext();
// Create AnalyserNode
var audio_analyser = audio_context.createAnalyser();
// Set "Fast Fourier transform"-size
audio_analyser.fftSize = 512;
// Save frequency data from the audio_analyser
var audio_frequencyData =
new Uint8Array(audio_analyser.frequencyBinCount);
Web Audio API
<audio id="player" controls preload src="song.mp3"></audio>
Web Audio API
// Get HTML audio element
var audio_element = document.getElementById('player');
// Set the audio_element as audio input
var audio_source =
audio_context.createMediaElementSource(audio_element);
// Connect the audio_source with the audio_analyser
audio_source.connect(audio_analyser);
// Connect the audio_analyser to the output (speaker etc.)
audio_analyser.connect(audio_context.destination);
// Get byte frequency data from the audio_analyser
audio_analyser.getByteFrequencyData(audio_frequencyData);
sub lows
lows
low mids
mids
high mids
highs
super highs
var NERDDISCO_audio = new ndAudio({
});
// Update & transform frequency data
NERDDISCO_audio.updateData();
// Get frequency data
NERDDISCO_audio.frequencyData;
// Get grouped frequency data
NERDDISCO_audio.groupedFrequencyData;
ndAudio
audio_element : document.querySelector('.player'),
fftSize : 512
ndAudio
DEMO
Notebook
Canvas API
-
Draw
-
Animate
-
Video processing
Canvas API
<canvas id="NERDDISCO" width="500" height="500"></canvas>
// Get the HTML canvas element
var canvas = document.getElementById('NERDDISCO');
// Get the canvas context
var ctx = canvas.getContext('2d');
// Set fill color
ctx.fillStyle = "rgb(200, 0, 0)";
// Draw a rectangle on the canvas
ctx.fillRect(10, 10, 55, 50);
Canvas API
function update() {
}
// Start animation loop
update();
// Clear whole canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw a rectangle
// ...
// Run at ~ 30 fps
setTimeout(function() {
}, 1000 / 30);
// Call update (recursion)
window.requestAnimationFrame(update);
ndVisualization
var NERDDISCO_visualization = new ndVisualization({
});
// Add visualization element to queue
NERDDISCO_visualization.addElement(
);
ndAudio : NERDDISCO_audio
new ndCircle({
x : 0, // x position
y : 0, // y position
r : 120, // radius
})
range : 'lowmid', // frequency range
trigger: 254 // min. frequency
ndVisualization
function update() {
}
// Update the audio data
NERDDISCO_audio.updateData();
// Draw every visualization element on canvas
NERDDISCO_visualization.draw();
// setTimeout + requestAnimationFrame
// ...
ndVisualization
ndAudio
DEMO
Notebook
LEDs
-
Adafruit
-
NeoPixel
-
NeoMatrix
nube 1
Adafruit NeoMatrix
var myLEDs = [
];
255, 0, 0, // red
0, 255, 0 // green
#1
#2
#3
255, 255, 0 // yellow
Adafruit Fadecandy
Notebook
USB
Fadecandy Server
Node.js
Fadecandy Client
Socket
ndSelector
-
Select area on canvas
-
1 ndSelector =
1 NeoMatrix
Pixel to LED mapping
Pixel to LED mapping
Canvas API
// Get the pixel data for one NeoPixel
var pixel_data = ctx.getImageData(x, y, width, height)
[ 255, 0, 128, 1,
55, 22, 73, 1,
20, 34, 0, 1 ]
// Create array for the result
var result = [];
// Sum red / green / blue for every pixel
for (var i = 0; i < pixel_data.length; i++) {
result[0] += pixel_data[i]; // red
result[1] += pixel_data[i + 1]; // green
result[2] += pixel_data[i + 2]; // blue
i += 2; // Jump to next pixel
}
Canvas API
// Amount of pixel for one NeoPixel
var pixel_amount = (pixel_data.length + 1) / 4;
// Calculate average color for one NeoPixel
result[0] = Math.floor(result[0] / pixel_amount);
result[1] = Math.floor(result[1] / pixel_amount);
result[2] = Math.floor(result[2] / pixel_amount);
ndVisualization
// Transform pixel data to LED colors
NERDDISCO_visualization.getLEDs()
Notebook
USB
Fadecandy Server
Node.js
Fadecandy Client
Socket
WebSocket
ndVisualization
function update() {
}
// Update the audio data
NERDDISCO_audio.updateData();
// Draw every visualization element on canvas
NERDDISCO_visualization.draw();
// setTimeout + requestAnimationFrame
// ...
// Calculate & send pixel data to the node.js server
NERDDISCO_connector.sendLEDs(
NERDDISCO_visualization.getLEDs()
);
ndVisualization
ndAudio
DEMO
nube 1
Notebook
USB
Fadecandy Server
Node.js
Fadecandy Client
Socket
WebSocket
Web MIDI API
-
Control MIDI devices
-
No plugin required
Web MIDI API
// Get permission from user
navigator.permissions.query({ name: 'midi', sysex: true });
// Permission granted: Request access to the MIDI devices
navigator.requestMIDIAccess({ sysex: true }).then(
);
// Got access
function(access) {
},
// Handle failure
function(failure) {}
// Iterate over all access.inputs.values()
// Listen to onmidimessage event
ndMidi
// Create instance of ndMidi
var NERDDISCO_midi = new ndMidi();
// Get permission for Web MIDI API &
// connect to the attached MIDI devices
NERDDISCO_midi.connect();
KORG nanoPAD2
The Next Generation
Thank you!
NERD DISCO: The Next Generation - JSConfChina 2015
By Tim Pietrusky
NERD DISCO: The Next Generation - JSConfChina 2015
Music visualization in the browser (HTML canvas, Web Audio API, socket.io) and on LEDs (Adafruit NeoPixel, Adafruit Fadecandy).
- 3,285