WEB AUDIO BAND

@shiota

2013
OH HAI!
slideshare.net/eshiota
github.com/eshiota
@shiota
+
RETROJS
I started playing with Web Audio API after watching a presentation by @almirfilho about it. My
challenge: play the ...
Web Audio API
oscillators
// Vendor prefixed
var context = new webkitAudioContext();
connect()

context.createOscillator()

context.destination
var oscillator = context.createOscillator();
oscillator.connect(context.destination);
frequência
duração

A note, crudely speaking, is a frequency played for a certain duration.
oscillator.frequency.value = 780;
oscillator.start(0);
oscillator.stop(context.currentTime + 0.5);
Live coding
RETROJS

Demo (RetroJS) - http://eshiota.github.io/retro-audio-js/
Demo (RetroJS - Mario Theme)
{
"title" : "Super Mario Bros Theme",
"tempo" : 200,
"time_signature" : "4/4",
"score" : [
{
"instrument" : "oscillator-sq...
Web Audio API
buffers
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
1.
2.
3.
4.
5.

AJAX request
Decode response on request load
Create buffer source
Connect source to destination
Play
1. AJAX request
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
2. Decode response on request load
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
3. Create buffer source
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
4. Connect source to destination
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
5. Play
var context = new webkitAudioContext()
, request = new XMLHttpRequest()
;
request.open("get", "/drums/snare.wav");
request...
Live coding
WEB AUDIO BAND
Overview
instrument

gain node

instrument

gain node

instrument

gain node

master gain
node

output
WEB AUDIO BAND
Drum Sequencer
Track 1
Track 2
Track 3
Track 4
Track 1
Track 2
Track 3
Track 4
play track 1
Track 1
Track 2
Track 3
Track 4
Track 1
Track 2
Track 3
Track 4
play track 2
Track 1
Track 2
Track 3
Track 4
Drums.soundsMap = {
"snare" : "/sounds/drums/snare.wav",
"kick" : "/sounds/drums/kick.wav",
"tom_hi" : "/sounds/drums/tom_...
SoundsMapLoader.loadSounds = function (audioContext) {
var dfds = []
, masterDfd = $.Deferred()
;
for (var key in this.sou...
SoundsMapLoader.loadSound = function (audioContext, key, url) {
var request = new XMLHttpRequest()
, dfd = $.Deferred()
;
...
//
//
//
//
//
//
//

Each beat (1/4 note) has 4 divisions (1/16 notes). A full cycle has
32 1/16 notes, which will be cal...
60bpm = 1bps
1bps = 4 posições p/ segundo
1000ms / 4 => positionDuration = 250ms
Demo (Web Audio Band - Drum Sequencer)
WEB AUDIO BAND
Synth Sequencer
Oscillators (sawtooth waves)
+
Overdrive
oscillator

overdrive
plugin

gain node
Demo (Web Audio Band - Synth Sequencer)
WEB AUDIO BAND
Bass Sequencer
SoundFont

WAV

MP
3
[Tue Nov
$ ls -w
A0.mp3
A1.mp3
A2.mp3
A3.mp3
A4.mp3
A5.mp3
A6.mp3

19 01:42 ~/Sites/petprojects/webaudio_band/public/sound...
Demo (Web Audio Band - Bass Sequencer)
WEB AUDIO BAND
Websockets
/admin?key=

/
/

Host
Interface

Instrument
Interface

Instrument
Interface
new instrument
slot
instruments
available

Host
Interface

Instrument
Interface

Instrument
Interface
instrument
connect

instrument
select
instruments
available

Host
Interface

Instrument
Interface

Instrument
Interface
instrument
played

Host
Interface

play(sound);

instrument
play

Instrument
Interface
Demo (Web Audio Band - Remote Instruments)
Por quê?

Why did I develop this projet?
Eu amo música.

I love music.
Programar é divertido.

Programming is fun.
Aprimorei conceitos de arquitetura.

I improved my architecture concepts.
Aprendi e conheci mais sobre:

I learned and got to know more about:
JavaScript
Sass
Web Audio API
Bower
Grunt
NodeJS
ExpressJS
Socket.IO
MIDI/SoundFont
E pra provar que esses caras estão errados:

And did it to prove that these guys are wrong:
The Web is not dead. Long live the Web.
And I finish this talk with a picture of my cats Jamie and Lexie. <3
THANKS!
slideshare.net/eshiota
github.com/eshiota
@shiota
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
Upcoming SlideShare
Loading in …5
×

Web Audio Band - Playing with a band in your browser

2,993 views

Published on

Have you imagined jamming with a band using only HTML, CSS, and JavaScript? Using the Web Audio API, Websockets, and a little bit of creativity, I presented an experiment using multiple devices communicating with each other, and playing music using only a web browser.

Já imaginou montar uma banda usando apenas HTML, CSS e JavaScript? Usando Web Audio API, Websockets, e um pouquinho de criatividade, mostrei um experimento de como múltiplos dispositivos podem se comunicar e tocar música direto no navegador.

0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,993
On SlideShare
0
From Embeds
0
Number of Embeds
53
Actions
Shares
0
Downloads
16
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

Web Audio Band - Playing with a band in your browser

  1. 1. WEB AUDIO BAND @shiota 2013
  2. 2. OH HAI! slideshare.net/eshiota github.com/eshiota @shiota
  3. 3. +
  4. 4. RETROJS I started playing with Web Audio API after watching a presentation by @almirfilho about it. My challenge: play the Super Mario Bros theme using JavaScript only.
  5. 5. Web Audio API oscillators
  6. 6. // Vendor prefixed var context = new webkitAudioContext();
  7. 7. connect() context.createOscillator() context.destination
  8. 8. var oscillator = context.createOscillator(); oscillator.connect(context.destination);
  9. 9. frequência duração A note, crudely speaking, is a frequency played for a certain duration.
  10. 10. oscillator.frequency.value = 780; oscillator.start(0); oscillator.stop(context.currentTime + 0.5);
  11. 11. Live coding
  12. 12. RETROJS Demo (RetroJS) - http://eshiota.github.io/retro-audio-js/
  13. 13. Demo (RetroJS - Mario Theme)
  14. 14. { "title" : "Super Mario Bros Theme", "tempo" : 200, "time_signature" : "4/4", "score" : [ { "instrument" : "oscillator-square", "volume" : 0.5, "sheet" : [ ["E5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8" , ["E5.8", "F#4.8"], "-.8" , ["C5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8", ["G5.8", "B4.8", "G4.8"], "-.8", "-.4" ["C5.8", "E4.8"], "-.4" , ["G4.8", "C4.8"], ["G4.4T3", "C4.4T3"], ["E5.4T3", "G4.4T3"], ["C5.8", "E4.8"], "-.4" , ["G4.8", "C4.8"], ["G4.4T3", "C4.4T3"], ["E5.4T3", "G4.4T3"], , "G4.8", "-.8", "-.4", "-.4" , ["E4.8", "G3.8"], "-.4" , ["A4.8", "C4.8"], "-.8", ["B.8", "D4.8"] , "-.8", ["Bb4.8", "Db4.8"], ["A4.8", "C4.8"], "-.8", ["G5.4T3", "B4.4T3"], ["A5.8", "C5.8"], "-.8", ["F5.8", "A4.8"], ["G5.8", "B4.8"], "-.8", ["E5.8", "G4.8"], "-.8", ["C5.8", "E4.8"], ["D5.8", "F4.8"], ["B4.8", "D4.8"], "-.4", "-.4" , ["E4.8", "G3.8"], "-.4" , ["A4.8", "C4.8"], "-.8", ["B.8", "D4.8"] , "-.8", ["Bb4.8", "Db4.8"], ["A4.8", "C4.8"], "-.8", ["G5.4T3", "B4.4T3"], ["A5.8", "C5.8"], "-.8", ["F5.8", "A4.8"], ["G5.8", "B4.8"], "-.8", ["E5.8", "G4.8"], "-.8", ["C5.8", "E4.8"], ["D5.8", "F4.8"], ["B4.8", "D4.8"], "-.2", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", "-.4", ["Eb5.8", "Ab4.8"], "-.4", ["D5.8", "F4.8"], "-.4", ["C5.8", "E4.8"], "-.8", "-.4", "C5.8"], "-.8", ["G#4.8", "D4.8"], ["A4.8", "E4.8"], ["C5.8", "G4.8"], "-.8", ["A4.8", "C4.8"], ["C5.8", "E4.8"], ["D5.8", "F4.8"], "-.4", "C5.8"], "-.8", ["C6.8", "G5.8"], "-.8", ["C6.8", "G5.8"], ["C6.8", "G5.8"], "-.8", "-.4", "-.4", "C5.8"], "-.8", ["G#4.8", "D4.8"], ["A4.8", "E4.8"], ["C5.8", "G4.8"], "-.8", ["A4.8", "C4.8"], ["C5.8", "E4.8"], ["D5.8", "F4.8"], "-.2", "-.4", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", ["G5.8", "E5.8"], ["Gb5.8", "Eb5.8"], ["F5.8", "D5.8"], ["D#5.8", "B4.8"], "-.8", ["E5.8", "-.4", ["Eb5.8", "Ab4.8"], "-.4", ["D5.8", "F4.8"], "-.4", ["C5.8", "E4.8"], "-.8", "-.4", "C5.8"], "-.8", ["G#4.8", "D4.8"], ["A4.8", "E4.8"], ["C5.8", "G4.8"], "-.8", ["A4.8", "C4.8"], ["C5.8", "E4.8"], ["D5.8", "F4.8"], "-.4", "C5.8"], "-.8", ["C6.8", "G5.8"], "-.8", ["C6.8", "G5.8"], ["C6.8", "G5.8"], "-.8", "-.4", "-.4", "C5.8"], "-.8", ["G#4.8", "D4.8"], ["A4.8", "E4.8"], ["C5.8", "G4.8"], "-.8", ["A4.8", "C4.8"], ["C5.8", "E4.8"], ["D5.8", "F4.8"], "-.2", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], "-.8", ["G4.8", "E5.8"], ["C5.8", "E4.8"], "-.8", ["A4.8", "E4.8"], ["G4.8", "C4.8"], "-.8", "-.4", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], ["G4.8", "E5.8"], "-.2", "-.2", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], "-.8", ["G4.8", "E5.8"], ["C5.8", "E4.8"], "-.8", ["A4.8", "E4.8"], ["G4.8", "C4.8"], "-.8", "-.4", ["E5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8" , ["E5.8", "F#4.8"], "-.8" , ["C5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8", ["G5.8", "B4.8", "G4.8"], "-.8", "-.4" ["C5.8", "E4.8"], "-.4" , ["G4.8", "C4.8"], ["G4.4T3", "C4.4T3"], ["E5.4T3", "G4.4T3"], ["C5.8", "E4.8"], "-.4" , ["G4.8", "C4.8"], ["G4.4T3", "C4.4T3"], ["E5.4T3", "G4.4T3"], , "G4.8", "-.8", "-.4", "-.4" , ["E4.8", "G3.8"], "-.4" , ["A4.8", "C4.8"], "-.8", ["B.8", "D4.8"] , "-.8", ["Bb4.8", "Db4.8"], ["A4.8", "C4.8"], "-.8", ["G5.4T3", "B4.4T3"], ["A5.8", "C5.8"], "-.8", ["F5.8", "A4.8"], ["G5.8", "B4.8"], "-.8", ["E5.8", "G4.8"], "-.8", ["C5.8", "E4.8"], ["D5.8", "F4.8"], ["B4.8", "D4.8"], "-.4", "-.4" , ["E4.8", "G3.8"], "-.4" , ["A4.8", "C4.8"], "-.8", ["B.8", "D4.8"] , "-.8", ["Bb4.8", "Db4.8"], ["A4.8", "C4.8"], "-.8", ["G5.4T3", "B4.4T3"], ["A5.8", "C5.8"], "-.8", ["F5.8", "A4.8"], ["G5.8", "B4.8"], "-.8", ["E5.8", "G4.8"], "-.8", ["C5.8", "E4.8"], ["D5.8", "F4.8"], ["B4.8", "D4.8"], "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["B4.4T3", "G4.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["E5.4T3", "G5.4T3"], ["D5.4T3", "F5.4T3"], ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["A4.8", "F4.8"], ["G4.8", "E4.8"], "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["G4.8", "B4.8"], ["D5.8", "F5.8"], "-.8", ["D5.8", "F5.8"], ["D5.4T3", "F5.4T3"], ["C5.4T3", "E5.4T3"], ["B4.4T3", "D5.4T3"], ["G4.8", "C5.8"], "E4.8", "-.8", "E4.8", "C4.8", "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["B4.4T3", "G4.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["E5.4T3", "G5.4T3"], ["D5.4T3", "F5.4T3"], ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["A4.8", "F4.8"], ["G4.8", "E4.8"], "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["G4.8", "B4.8"], ["D5.8", "F5.8"], "-.8", ["D5.8", "F5.8"], ["D5.4T3", "F5.4T3"], ["C5.4T3", "E5.4T3"], ["B4.4T3", "D5.4T3"], ["G4.8", "C5.8"], "E4.8", "-.8", "E4.8", "C4.8", "-.8", "-.4", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], "-.8", ["G4.8", "E5.8"], ["C5.8", "E4.8"], "-.8", ["A4.8", "E4.8"], ["G4.8", "C4.8"], "-.8", "-.4", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], ["G4.8", "E5.8"], "-.2", "-.2", ["Ab4.8", "C5.8"], ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], "-.8", ["Ab4.8", "C5.8"], ["Bb4.8", "D5.8"], "-.8", ["G4.8", "E5.8"], ["C5.8", "E4.8"], "-.8", ["A4.8", "E4.8"], ["G4.8", "C4.8"], "-.8", "-.4", ["E5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8" , ["E5.8", "F#4.8"], "-.8" , ["C5.8", "F#4.8"], ["E5.8", "F#4.8"], "-.8", ["G5.8", "B4.8", "G4.8"], "-.8", "-.4" , "G4.8", "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["B4.4T3", "G4.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["E5.4T3", "G5.4T3"], ["D5.4T3", "F5.4T3"], ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["A4.8", "F4.8"], ["G4.8", "E4.8"], "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["G4.8", "B4.8"], ["D5.8", "F5.8"], "-.8", ["D5.8", "F5.8"], ["D5.4T3", "F5.4T3"], ["C5.4T3", "E5.4T3"], ["B4.4T3", "D5.4T3"], ["G4.8", "C5.8"], "E4.8", "-.8", "E4.8", "C4.8", "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["B4.4T3", "G4.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["F5.4T3", "A5.4T3"], ["E5.4T3", "G5.4T3"], ["D5.4T3", "F5.4T3"], ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["A4.8", "F4.8"], ["G4.8", "E4.8"], "-.8", "-.4", ["E5.8", "C5.8"], ["C5.8", "A4.8"], "-.8", ["G4.8", "E4.8"], "-.4", ["G#4.8", "E4.8"], "-.8", ["A4.8", "F4.8"], ["C5.8", "F5.8"], "-.8", ["C5.8", "F5.8"], ["A4.8", "F4.8"], "-.8", "-.4", ["G4.8", "B4.8"], ["D5.8", "F5.8"], "-.8", ["D5.8", "F5.8"], ["D5.4T3", "F5.4T3"], ["C5.4T3", "E5.4T3"], ["B4.4T3", "D5.4T3"], ["G4.8", "C5.8"], "E4.8", "-.8", "E4.8", "C4.8", "-.8", "-.4" ] }, { "volume" : 0.5, "instrument" : "oscillator-square", "sheet" : [ "D3.8", "D3.8", "-.8", "D3.8", "-.8", "D3.8", "D3.8", "-.8", "G3.8", "-.8", "-.4", "G3.8", "-.8", "-.4", "G3.8", "-.4", "E3.8", "-.4", "E3.4T3", "C4.4T3", "E4.4T3", "G3.8", "-.4", "E3.8", "-.4", "E3.4T3", "C4.4T3", "E4.4T3", "C3.8", "F4.8", "C3.8", "F4.8", "-.4", "-.8", "-.4", "-.8", "F3.8", "D4.8", "F3.8", "D4.8", "-.8", "G3.8", "E4.8", "-.8", "-.8", "G3.8", "E4.8", "-.8", "-.8", "Gb3.8", "F3.8", "-.8", "C4.8", "-.8", "A3.8", "B3.8", "G3.8", "-.4", "-.8", "Gb3.8", "F3.8", "-.8", "C4.8", "-.8", "A3.8", "B3.8", "G3.8", "-.4", This is the JSON representation of the Mario Bros Theme. "C3.8", "C3.8", "C3.8", "C3.8", "-.4", "-.4", "-.4", "-.8", "G3.8", "-.4", "C4.8", "-.8", "F3.8", "-.4", "C4.8", "C4.8", "-.8", "F4.8", "-.8", "E3.8", "-.4", "G3.8", "C4.8", "-.2", "-.4", "G3.8", "-.8", "G3.8", "-.4", "C4.8", "-.8", "F3.8", "-.4", "C4.8", "C4.8", "-.8", "F4.8", "-.8", "Ab3.8", "-.4", "Bb3.8", "-.4", "C4.8", "-.4", "G3.8", "G3.8", "-.8", "C3.8", "-.8",
  15. 15. Web Audio API buffers
  16. 16. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  17. 17. 1. 2. 3. 4. 5. AJAX request Decode response on request load Create buffer source Connect source to destination Play
  18. 18. 1. AJAX request
  19. 19. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  20. 20. 2. Decode response on request load
  21. 21. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  22. 22. 3. Create buffer source
  23. 23. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  24. 24. 4. Connect source to destination
  25. 25. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  26. 26. 5. Play
  27. 27. var context = new webkitAudioContext() , request = new XMLHttpRequest() ; request.open("get", "/drums/snare.wav"); request.responseType = "arraybuffer"; request.onload = function () { context.decodeAudioData(request.response, function (buffer) { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }); }; request.send();
  28. 28. Live coding
  29. 29. WEB AUDIO BAND Overview
  30. 30. instrument gain node instrument gain node instrument gain node master gain node output
  31. 31. WEB AUDIO BAND Drum Sequencer
  32. 32. Track 1 Track 2 Track 3 Track 4
  33. 33. Track 1 Track 2 Track 3 Track 4
  34. 34. play track 1 Track 1 Track 2 Track 3 Track 4
  35. 35. Track 1 Track 2 Track 3 Track 4
  36. 36. play track 2 Track 1 Track 2 Track 3 Track 4
  37. 37. Drums.soundsMap = { "snare" : "/sounds/drums/snare.wav", "kick" : "/sounds/drums/kick.wav", "tom_hi" : "/sounds/drums/tom_hi.wav", "tom_low" : "/sounds/drums/tom_low.wav", "hihat_closed" : "/sounds/drums/hihat_closed.wav", "hihat_open" : "/sounds/drums/hihat_open.wav", "trash" : "/sounds/drums/trash.wav" };
  38. 38. SoundsMapLoader.loadSounds = function (audioContext) { var dfds = [] , masterDfd = $.Deferred() ; for (var key in this.soundsMap) { dfds.push(this.loadSound(audioContext, key, this.soundsMap[key])); } $.when.apply($, dfds).then(function () { masterDfd.resolve(); }); return masterDfd; };
  39. 39. SoundsMapLoader.loadSound = function (audioContext, key, url) { var request = new XMLHttpRequest() , dfd = $.Deferred() ; request.open("get", url); request.responseType = "arraybuffer"; request.onload = (function () { audioContext.decodeAudioData(request.response, (function (buffer) { this.sounds[key] = buffer; dfd.resolve(); }).bind(this)); }).bind(this); request.send(); return dfd; };
  40. 40. // // // // // // // Each beat (1/4 note) has 4 divisions (1/16 notes). A full cycle has 32 1/16 notes, which will be called as positions. Something like this: - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - 0 4 8 12 16 20 24 28 31 Looper.fn.cycle = function () { if (!this.playing) { return true; } this.trigger("position-change", [this.position]); this.position = this.position === this.lastPosition ? 0 : this.position + 1; setTimeout(this.cycle.bind(this), this.positionDuration); };
  41. 41. 60bpm = 1bps 1bps = 4 posições p/ segundo 1000ms / 4 => positionDuration = 250ms
  42. 42. Demo (Web Audio Band - Drum Sequencer)
  43. 43. WEB AUDIO BAND Synth Sequencer
  44. 44. Oscillators (sawtooth waves) + Overdrive
  45. 45. oscillator overdrive plugin gain node
  46. 46. Demo (Web Audio Band - Synth Sequencer)
  47. 47. WEB AUDIO BAND Bass Sequencer
  48. 48. SoundFont WAV MP 3
  49. 49. [Tue Nov $ ls -w A0.mp3 A1.mp3 A2.mp3 A3.mp3 A4.mp3 A5.mp3 A6.mp3 19 01:42 ~/Sites/petprojects/webaudio_band/public/sounds/bass] (master) [aws:personal] A7.mp3 Ab1.mp3 Ab2.mp3 Ab3.mp3 Ab4.mp3 Ab5.mp3 Ab6.mp3 Ab7.mp3 B0.mp3 B1.mp3 B2.mp3 B3.mp3 B4.mp3 B5.mp3 B6.mp3 B7.mp3 Bb0.mp3 Bb1.mp3 Bb2.mp3 Bb3.mp3 Bb4.mp3 Bb5.mp3 Bb6.mp3 Bb7.mp3 C1.mp3 C2.mp3 C3.mp3 C4.mp3 C5.mp3 C6.mp3 C7.mp3 C8.mp3 D1.mp3 D2.mp3 D3.mp3 D4.mp3 D5.mp3 D6.mp3 D7.mp3 Db1.mp3 Db2.mp3 Db3.mp3 Db4.mp3 Db5.mp3 Db6.mp3 Db7.mp3 E1.mp3 E2.mp3 E3.mp3 E4.mp3 E5.mp3 E6.mp3 E7.mp3 Eb1.mp3 Eb2.mp3 Eb3.mp3 Eb4.mp3 Eb5.mp3 Eb6.mp3 Eb7.mp3 F1.mp3 F2.mp3 F3.mp3 F4.mp3 F5.mp3 F6.mp3 F7.mp3 G1.mp3 G2.mp3 G3.mp3 G4.mp3 G5.mp3 G6.mp3 G7.mp3 Gb1.mp3 Gb2.mp3 Gb3.mp3 Gb4.mp3 Gb5.mp3 Gb6.mp3 Gb7.mp3
  50. 50. Demo (Web Audio Band - Bass Sequencer)
  51. 51. WEB AUDIO BAND Websockets
  52. 52. /admin?key= / / Host Interface Instrument Interface Instrument Interface
  53. 53. new instrument slot instruments available Host Interface Instrument Interface Instrument Interface
  54. 54. instrument connect instrument select instruments available Host Interface Instrument Interface Instrument Interface
  55. 55. instrument played Host Interface play(sound); instrument play Instrument Interface
  56. 56. Demo (Web Audio Band - Remote Instruments)
  57. 57. Por quê? Why did I develop this projet?
  58. 58. Eu amo música. I love music.
  59. 59. Programar é divertido. Programming is fun.
  60. 60. Aprimorei conceitos de arquitetura. I improved my architecture concepts.
  61. 61. Aprendi e conheci mais sobre: I learned and got to know more about:
  62. 62. JavaScript Sass Web Audio API Bower Grunt NodeJS ExpressJS Socket.IO MIDI/SoundFont
  63. 63. E pra provar que esses caras estão errados: And did it to prove that these guys are wrong:
  64. 64. The Web is not dead. Long live the Web.
  65. 65. And I finish this talk with a picture of my cats Jamie and Lexie. <3
  66. 66. THANKS! slideshare.net/eshiota github.com/eshiota @shiota

×