JavaScript, JavaScript…. Rocks You!

JavaScript, JavaScript…. Rocks You!

After so many years sitting with the computer you can take your old scratched Les Paul or Stratocaster from the case and fill all the space around with warm riffs. I’m going to show how to transform the code into Kirk Hammett’s wah-wah, Stevie Ray Vaughan’s overdrive and Kurt Cobain’s distortion. You’ll learn how to parse audio input in real-time using JavaScript and the Web Audio API.

I’ll be jamming live on stage with my guitar to demo every code example and we’ll also use WebRTC to jam with friends across the world! After this talk, you will be familiar with the principles behind pedal sound effects and how to create them in code. Let’s rock the Web!

4f0880beebecf17d29eb709246055e14?s=128

Vitalii Bobrov

June 01, 2019
Tweet

Transcript

  1. JavaScript, JavaScript… Rocks You!

  2. Vitalii Bobrov Lead JS Engineer @ EPAM @AngularWroclaw organizer Guitar

    player @bobrov1989 https://bobrov.dev
  3. Web Audio

  4. a uni-directed graph containing audio nodes https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API

  5. Uni-directed Graph input output effects

  6. Guitar Stack input output

  7. Guitar Stack input output effects

  8. Connect a Guitar

  9. Stream Source https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamAudioSourceNode try { const context = new AudioContext();

    const stream = await navigator.mediaDevices .getUserMedia({ audio: true }); } catch (err) { console.error(err); }
  10. None
  11. Media Stream Constraints https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints/audio const stream = await navigator.mediaDevices .getUserMedia({

    audio: true });
  12. Media Stream Constraints https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints/audio const stream = await navigator.mediaDevices .getUserMedia({

    audio: { echoCancellation: false, autoGainControl: false, noiseSuppression: false, latency: 0 } });
  13. Connect to Destination https://developer.mozilla.org/en-US/docs/Web/API/AudioDestinationNode const lineInSource = context.createMediaStreamSource(stream); lineInSource.connect(context.destination);

  14. Volume Control

  15. Gain Control sin(x) 0.5sin(x)

  16. Gain Node https://developer.mozilla.org/en-US/docs/Web/API/GainNode const gainNode = new GainNode(context); gainNode.gain.value =

    0.5; source.connect(gainNode).connect(context.destination);
  17. Distortion

  18. group of effects shaping a sound wave

  19. Overdrive Distortion Fuzz Effects

  20. None
  21. Wave Shape sin(x) (PI + k) * x / (PI

    + k * abs(x))
  22. Distortion vs Overdrive vs Fuzz

  23. Wave Shaper Node https://developer.mozilla.org/en-US/docs/Web/API/WaveShaperNode const waveShaper = new WaveShaperNode(context); waveShaper.curve

    = makeDistortionCurve(amount1); function makeDistortionCurve(amount) { const k = amount * 150 + 50; const n = 8096; const curve = new Float32Array(n + 1); for (let i = 0, x: number; i <= n; ++i) { x = i * 2 / n - 1; curve[i] = (Math.PI + k) * x / (Math.PI + k * Math.abs(x)); } return curve; }
  24. Biquad Filter Node https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode const toneNode = new BiquadFilterNode(context, {

    type: 'lowpass', frequency: 350 }); toneNode.frequency.value = tone; // 350 - 22050
  25. Cabinet

  26. Impulse Response a short sample with impulse characteristics record

  27. Convolver Node https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode const convolver = new ConvolverNode(context); fetch('impulse.wav') .then(response

    => response.arrayBuffer()) .then(buffer => { context.decodeAudioData(buffer, decoded => { convolver.buffer = decoded; }); });
  28. Equalizer

  29. Three Band Equalizer Bass < 500 Hz Middle ~1500 Hz

    Treble > 3000 Hz
  30. Biquad Filter Nodes https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode const bassNode = new BiquadFilterNode(context, {

    type: 'lowshelf', frequency: 500 }); const midNode = new BiquadFilterNode(context, { type: 'peaking', frequency: 1500 }); const trebleNode = new BiquadFilterNode(context, { type: 'highshelf', frequency: 3000 });
  31. Reverb

  32. Reverb Graph Channel Splitter Node Channel Merger Node “Dry”
 Gain

    Node “Wet”
 Gain Node Delay Node Biquad Filter Node Convolver Node
  33. Reverb Nodes https://developer.mozilla.org/en-US/docs/Web/API/ChannelSplitterNode https://developer.mozilla.org/en-US/docs/Web/API/DelayNode const splitter = new ChannelSplitterNode(context); const

    delayNode = new DelayNode(context); const toneNode = new BiquadFilterNode(context); const convolver = new ConvolverNode(context); const wet = new GainNode(context); const dry = new GainNode(context); const merger = new ChannelMergerNode(context);
  34. Connect Nodes https://developer.mozilla.org/en-US/docs/Web/API/ChannelMergerNode splitter.connect(delayNode); delayNode.connect(toneNode); toneNode.connect(convolver); convolver.connect(wet); wet.connect(merger); splitter.connect(dry, 1).connect(merger,

    0, 1);
  35. Connect line to destination Gain Node Distortion Wave Shaper Node

    Biquad Filter Node Cabinet Convolver Node Reverb Channel Merger/Splitter Node Delay Node Recap
  36. Rock it!

  37. @bobrov1989 https://bobrov.dev https://github.com/vitaliy-bobrov/js-rocks https://bobrov.dev/js-rocks/