SlideShare uma empresa Scribd logo
1 de 60
Baixar para ler offline
RETROJS
Party like it's 1983
@shiota 2013
OH HAI!slideshare.net/eshiota
github.com/eshiota
@shiota
+ +
Tudo começou na palestra do @almirfilho no OlhóSEO em Floripa sobre Web Audio API. O
@fnando falou "Cara, dá pra fazer o JavaScript tocar o tema do Mario, imagina que foda?".
Challenge accepted.
Web Audio API
// Vendor prefixed
var context = new webkitAudioContext();
context.createOscillator() context.destination
connect()
var oscillator = context.createOscillator();
oscillator.connect(context.destination);
frequência
duração
oscillator.frequency.value = 780;
oscillator.start(0);
oscillator.stop(context.currentTime + 0.5);
about me
Estudei piano dos 8 aos 15 anos. Sou apaixonado por música clássica, e gosto de ler
partituras. Nada como juntar um hobby antigo com uma paixão. =)
Voltando ao assunto: challenge accepted, né? =)
o projeto
&
?
4
4
4
4
Piano
Allegro q»™ºº
œ
œ#
œ
œ ‰
J
œ
œ ‰ œ
œ
œ
œ ‰
œ œ ‰
J
œ ‰ œ œ ‰
J
œ
œœ ‰ Œ j
œ ‰ Œ
Ó J
œ ‰ Œ
&
?
..
..
A3
j
œ
œ
‰ ‰ j
œ
œ
Πj
œ
œ
‰
J
œ ‰ ‰
J
œ Œ
j
œ ‰
‰ œ
œ
‰ œ
œ
‰ œ
œ
b
b
œ
œ
‰
‰ œ ‰ œ ‰ œb œ ‰
œ
œ
œ
œ
œ
œ
J
œ
œ ‰
œ
œ
œ
œ
3
œ
œ œ
J
œ
‰
œ œ
3
‰ œ
œ ‰ œ
œ
œ
œ œ
œ
Œ
‰
œ ‰ œ œ œ Œ
&
?
7
j
œ
œ
‰ ‰ j
œ
œ
Πj
œ
œ
‰
J
œ ‰ ‰
J
œ Œ
j
œ ‰
‰ œ
œ
‰ œ
œ
‰ œ
œ
b
b
œ
œ
‰
‰ œ ‰ œ ‰ œb œ ‰
œ
œ
œ
œ
œ
œ
J
œ
œ ‰
œ
œ
œ
œ
3
œ
œ œ
J
œ
‰
œ œ
3
‰ œ
œ ‰ œ
œ
œ
œ œ
œ
Œ
‰
œ ‰ œ œ œ Œ
&
?
B11
Œ
œœ œœ## œœnn œœ# ‰
J
œœ
j
œ ‰ ‰ J
œ Œ J
œ
‰
‰ œœ# œœ
œœn ‰ œ
œ
œ
œ
œ
œ
J
œ ‰ ‰ J
œ œ
‰ œ ‰
Œ
œœ œœ## œœnn œœ# ‰
J
œœ
j
œ ‰ ‰
J
œ Œ œ œ
‰
œœœ ‰
œœœ
J
œœœ
‰ Œ
Ó Œ J
œ ‰
Overworld Theme
From Super Mario Bros.
Koji Kondo
Transcribed by BLUESCD
http://www.gamemusicthemes.com/
primeira ideia
= 60
oscillator.frequency.value = 391;
oscillator.start(0);
oscillator.stop(context.currentTime + 1);
= 60
setTimeout(function () {
oscillator.frequency.value = 391;
oscillator.start(0);
oscillator.stop(context.currentTime + 1);
}, 1000);
= 60
setTimeout(function () {
oscillator.frequency.value = 391;
oscillator.start(0);
oscillator.stop(context.currentTime + 1);
}, 2000);
problemas
manter track do tempo
oscillator tem vida curta
impraticável de escrever
solução
criar notação musical
criar loop de execução
criar estrutura para lidar com tracks e notas
notação musical
&
?
4
4
4
4
Piano
Allegro q»™ºº
œ
œ#
œ
œ ‰
J
œ
œ ‰ œ
œ
œ
œ ‰
œ œ ‰
J
œ ‰ œ œ ‰
J
œ
œœ ‰ Œ j
œ ‰ Œ
Ó J
œ ‰ Œ
&
?
..
..
A3
j
œ
œ
‰ ‰ j
œ
œ
Πj
œ
œ
‰
J
œ ‰ ‰
J
œ Œ
j
œ ‰
‰ œ
œ
‰ œ
œ
‰ œ
œ
b
b
œ
œ
‰
‰ œ ‰ œ ‰ œb œ ‰
œ
œ
œ
œ
œ
œ
J
œ
œ ‰
œ
œ
œ
œ
3
œ
œ œ
J
œ
‰
œ œ
3
‰ œ
œ ‰ œ
œ
œ
œ œ
œ
Œ
‰
œ ‰ œ œ œ Œ
Overworld Theme
From Super Mario Bros.
Koji Kondo
Transcribed by BLUESCD
http://www.gamemusicthemes.com/
{
"title" : "Imperial March",
"tempo" : 120,
"time_signature" : "4/4",
"score" : [
{
"instrument" : "oscillator-square",
"volume" : 0.5,
"sheet" : [
"G.8D", "-.16", "G.8D", "-.16", "G.8D", "-.16", "Eb.8D", "Bb.16",
"G.8D", "-.16", "Eb.8D", "Bb.16", "G.4", "-.4"
]
}
]
}
Uma partitura, bem simplificada, tem o título, tempo, assinatura de tempo, e as notas. A
implementação em JSON que bolei ficou assim.
[
"G.8D", "-.16", "G.8D", "-.16", "G.8D", "-.16", "Eb.8D", "Bb.16",
"G.8D", "-.16", "Eb.8D", "Bb.16", "G.4", "-.4"
]
Uma música é um array de notas. Mas como é a sintaxe dessas notas?
"G.4"
frequência (391)
duração (1/4)
Uma função `getFrequency` interpreta a nota e retorna a frequência, dada uma fórmula
matemática.
"G5.4"
frequência (783)
duração (1/4)
"G5.4D"
frequência (783)
duração (1/4 + 1/8)
"-.4" duração (1/4)
Pausas são representadas com um "-".
criando o loop
conceito
dividir a música nas menores
marcações possíveis, e usar como
marcação para iniciar as notas
&
?
4
4
4
4
Piano
Allegro q»™ºº
œ
œ#
œ
œ ‰
J
œ
œ ‰ œ
œ
œ
œ ‰
œ œ ‰
J
œ ‰ œ œ ‰
J
œ
œœ ‰ Œ j
œ ‰ Œ
Ó J
œ ‰ Œ
&
?
..
..
A3
j
œ
œ
‰ ‰ j
œ
œ
Πj
œ
œ
‰
J
œ ‰ ‰
J
œ Œ
j
œ ‰
‰ œ
œ
‰ œ
œ
‰ œ
œ
b
b
œ
œ
‰
‰ œ ‰ œ ‰ œb œ ‰
œ
œ
œ
œ
œ
œ
J
œ
œ ‰
œ
œ
œ
œ
3
œ
œ œ
J
œ
‰
œ œ
3
‰ œ
œ ‰ œ
œ
œ
œ œ
œ
Œ
‰
œ ‰ œ œ œ Œ
&
?
7
j
œ
œ
‰ ‰ j
œ
œ
Πj
œ
œ
‰
J
œ ‰ ‰
J
œ Œ
j
œ ‰
‰ œ
œ
‰ œ
œ
‰ œ
œ
b
b
œ
œ
‰
‰ œ ‰ œ ‰ œb œ ‰
œ
œ
œ
œ
œ
œ
J
œ
œ ‰
œ
œ
œ
œ
3
œ
œ œ
J
œ
‰
œ œ
3
‰ œ
œ ‰ œ
œ
œ
œ œ
œ
Œ
‰
œ ‰ œ œ œ Œ
&
?
B11
Œ
œœ œœ## œœnn œœ# ‰
J
œœ
j
œ ‰ ‰ J
œ Œ J
œ
‰
‰ œœ# œœ
œœn ‰ œ
œ
œ
œ
œ
œ
J
œ ‰ ‰ J
œ œ
‰ œ ‰
Œ
œœ œœ## œœnn œœ# ‰
J
œœ
j
œ ‰ ‰
J
œ Œ œ œ
‰
œœœ ‰
œœœ
J
œœœ
‰ Œ
Ó Œ J
œ ‰
Overworld Theme
From Super Mario Bros.
Koji Kondo
Transcribed by BLUESCD
http://www.gamemusicthemes.com/
semibreve
1
=
semínima
1/4
colcheia
1/8
=
semínima
1/4
semicolcheia
1/16
=
semínima
1/4
fusa
1/32
=
semínima
1/4
semifusa
1/64
= 60
=
semínima
1/4
semifusa
1/64
1000ms = 16 cycles de 62.5ms
Se uma música tem 60 bpm, uma semínima (uma "batida") tem um segundo. Uma semínima
tem 16 semifusas, então tem 16 ciclos. Cada ciclo, portanto, tem 1000/16 = 62.5ms
parsedTrack["0"] = new Note("C.4");
parsedTrack["16"] = new Note("D.4");
parsedTrack["32"] = new Note("E.4");
parsedTrack["64"] = new Note("F.4");
Tracks são hashes que contêm como índice o ciclo, e a nota que deve ser tocada nesse ciclo.
parsedTrack["0"] = new Note("C.4");
parsedTrack["16"] = new Note("D.4");
parsedTrack["32"] = new Note("E.4");
parsedTrack["64"] = new Note("F.4");
var cycleDuration = 62.5
, currentCycle = 0
;
function renderCycle () {
parsedTrack[currentCycle].play()
currentCycle = currentCycle + 1;
setTimeout(renderCycle, cycleDuration);
};
Uma loop incrementa os ciclos e checa se há notas a serem tocadas ali.
tracks múltiplos
parsedTrack0["0"] = new Note("C.4");
parsedTrack0["16"] = new Note("D.4");
parsedTrack0["32"] = new Note("E.4");
parsedTrack0["64"] = new Note("F.4");
parsedTrack1["0"] = new Note("G.4");
parsedTrack1["16"] = new Note("A.4");
tracks[0] = parsedTrack0;
tracks[1] = parsedTrack1;
var cycleDuration = 62.5
, currentCycle = 0
;
function renderCycle () {
for (var i = 0, l = tracks.length; i < l; i++) {
tracks[i][currentCycle].play();
}
currentCycle = currentCycle + 1;
setTimeout(renderCycle, cycleDuration);
};
Se o parâmetro de indexação de uma nota na música é o mesmo entre todos os tracks, é fácil
fazer músicas com múltiplos tracks.
dificuldades e adaptações
no caminho
oscillator tem vida curta
cada nota é uma nova instância
quartifusas (1/128)
performance ficou baixa
Com múltiplos tracks, executar ciclos tomando uma nota quartifusa (1/128) de duração
como base ficou muito pesado. Tive que voltar para uma semifusa (1/64).
notações não planejadas
notas pontuadas, tercinas, acordes
estrutura adaptável
novos instrumentos, controles modificáveis
futuro
melhorar performance
mais instrumentos,
usando samples
melhorias de interface
keep having fun =)
https://github.com/eshiota/retro-audio-js
Mas e o mario?
E nessa hora, foi tocado o tema do Mario completo, apenas com JavaScript. Achievement
unlocked. ;D
thanks!slideshare.net/eshiota
github.com/eshiota
@shiota

Mais conteúdo relacionado

Mais de Eduardo Shiota Yasuda

Desafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerceDesafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerceEduardo Shiota Yasuda
 
Arquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga EscalaArquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga EscalaEduardo Shiota Yasuda
 
Responsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebResponsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebEduardo Shiota Yasuda
 
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire JapanSushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire JapanEduardo Shiota Yasuda
 
O Design e a Interface no mundo da Programação
O Design e a Interface no mundo da ProgramaçãoO Design e a Interface no mundo da Programação
O Design e a Interface no mundo da ProgramaçãoEduardo Shiota Yasuda
 

Mais de Eduardo Shiota Yasuda (6)

Desafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerceDesafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerce
 
Arquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga EscalaArquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga Escala
 
Responsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebResponsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da Web
 
User Experience para Developers
User Experience para DevelopersUser Experience para Developers
User Experience para Developers
 
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire JapanSushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
 
O Design e a Interface no mundo da Programação
O Design e a Interface no mundo da ProgramaçãoO Design e a Interface no mundo da Programação
O Design e a Interface no mundo da Programação
 

RETROJS: Party like it's 1983