Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Making Music with the Web Audio API, JSConf Col...
Search
Steve Kinney
November 16, 2023
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Making Music with the Web Audio API, JSConf Colombia 2023
Steve Kinney
November 16, 2023
Transcript
55 slides
Steve Kinney — JSConf Colombia 2023 Making Music with the
Web Audio API.
Hi, I’m Steve. I work at Temporal.
https:// synthesizzler.vercel.app Also, you can scan this code at any
time.
Someone snuck a synthesizer into your web browser.
None
None
None
None
const context = new AudioContext();
None
const oscillator = context.createOscillator();
None
oscillator.connect(context.destination);
oscillator.connect(context.destination); const context = new AudioContext(); const oscillator = context.createOscillator();
None
None
oscillator.connect(context.destination); const context = new AudioContext(); const oscillator = context.createOscillator();
oscillator.connect(volume); const context = new AudioContext(); const oscillator = context.createOscillator();
const volume = context.createGain(); volume.connect(context.destination);
const oscillator = context.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.value = 440;
oscillator.connect(context.destination); oscillator.start();
oscillator.start(); oscillator.stop(); oscillator.start(); This won’t work.
oscillator.stop(); oscillator.disconnect(); oscillator = null;
None
Let’s take a look at this in action.
None
A3 220 Hz A4 440 Hz A5 880 Hz
A3 220 Hz A4 440 Hz B4 C5 C#5 D5
D#5 E5 F5 F#5 G5 G#5
https://synthesizzler.vercel.app/ notes
const A4 = 440; const A4_NOTE_NUMBER = 69; const TWELFTH_ROOT_OF_TWO
= Math.pow(2, 1 / 12); export function getFrequency() { const noteNumber = noteToNumber(note); return A4 * Math.pow(TWELFTH_ROOT_OF_TWO, noteNumber - A4_NOTE_NUMBER); }
Note Frequency (hz) A 440.00 A̅ 476.67 B 513.33 C
550.00 C̅ 586.67 D 623.33 D̅ 660.00 E 696.67 F 733.33 F̅ 770.00 G 806.67 G̅ 843.33 A 880.00
Note Frequency (hz) Frequency (hz) A 440.00 A̅ 476.67 B
513.33 C 550.00 550.00 C̅ 586.67 595.83 D 623.33 641.67 D̅ 660.00 687.50 E 696.67 733.33 F 733.33 779.17 F̅ 770.00 825.00 G 806.67 870.83 G̅ 843.33 916.67 A 880.00 962.50 A̅ 1008.33 B 1054.17 C 1100.00
None
const oscillator = context.createOscillator(); const gain = context.createGain(); oscillator.connect(gain); gain.connect(context.destination);
oscillator.type = waveType; oscillator.frequency.value = frequency; gain.gain.setValueAtTime(0, startTime); gain.gain.linearRampToValueAtTime(1, startTime + duration / 100); gain.gain.exponentialRampToValueAtTime(0.0001, startTime + duration); oscillator.start(startTime); oscillator.stop(startTime + duration + 0.05);
const startTime = context.currentTime; const duration = 1; gain.gain.setValueAtTime(0, startTime);
gain.gain.linearRampToValueAtTime(1, startTime + duration / 100); gain.gain.exponentialRampToValueAtTime(0.0001, startTime + duration); oscillator.start(startTime); oscillator.stop(startTime + duration + 0.05);
None
None
const startOscillator = ( context, note, ): OscillatorAndGain = {
const oscillator = context.createOscillator(); const gain = context.createGain(); oscillator.frequency.value = getFrequency(note); gain.gain.value = 0.01; oscillator.connect(gain); gain.connect(context.destination); gain.gain.linearRampToValueAtTime(1, context.currentTime + 0.1); oscillator.start(); return { oscillator, gain }; };
Emits a keyDown event
https://synthesizzler.vercel.app/ keys
⏰ Keeping time.
None
get secondsPerBeat() { return 60 / this.beatsPerMinute; }
public start() { if (this.on) return; this.on = true; this.currentBeat
= 0; this.tick(); } public stop() { this.on = false; this.nextScheduledBeat = null; if (this.interval) clearTimeout(this.interval); }
public tick = () = { if (!this.on) return; if
(!this.nextScheduledBeat) { this.nextScheduledBeat = this.context.currentTime; } this.incrementBeat(); this.onTick(this.currentBeat, this.nextScheduledBeat); this.interval = setTimeout(this.tick, this.secondsPerBeat * 1000); this.nextScheduledBeat += this.secondsPerBeat; };
https://synthesizzler.vercel.app/ metronome
https://synthesizzler.vercel.app/ step-sequencer
Someone snuck a synthesizer into your web browser.
Someone snuck a web browser into your synthesizer.
+
https://synthesizzler.vercel.app/ theremin
None
None
Music is pretty awesome.
The web is pretty awesome.
Music and the web are even more awesome when their
together.
Thank you! @stevekinney https://temporal.io
More Decks by Steve Kinney
See All by Steve Kinney
Enterprise UI, v2
stevekinney
0
330
React_Performance__2022.pdf
stevekinney
0
56
React Performance v2
stevekinney
0
99
Introduction to Testing
stevekinney
0
210
Web Security, Frontend Masters
stevekinney
0
4.5k
React and TypeScript, Turing School
stevekinney
0
400
Redux Workshop, 2021-05-05
stevekinney
2
2.3k
TypeScript and React Utility Types
stevekinney
1
250
A Gentle Introduction to GraphQL Resolvers
stevekinney
1
210
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
470
The Curious Case for Waylosing
cassininazir
1
610
WENDY [Excerpt]
tessaabrams
15
40k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
620
Building Applications with DynamoDB
mza
96
7.3k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.6k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
430
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
520
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
630
Highjacked: Video Game Concept Design
rkendrick25
PRO
2
560