Changing live audio with the web-audio-api



Changing live audio with the web-audio-api

0 1


pedalboard-presentation

A presentation about the web-audio-api and web-midi-api

On Github Sambego / pedalboard-presentation

Changing live audio with the web-audio-api

Sam Bellen

  • madewithlove
  • @sambego
  • github.com/sambego

I ❤️ guitar pedals!

So, is this possible in in the browser?

1. Get the guitar's sound in the browser

const audioContext = new AudioContext();
navigator.getUserMedia({
    audio: true
}, stream => {
    // We've got a stream of the user's audio input device.
}, error => {
    // Errors, gotta catch 'em all!
});
                    
navigator.mediaDevices.getUserMedia({
    audio: true
}).then(stream => {
    // We've got a stream of the user's audio input device.
}, error => {
    // Errors, gotta catch 'em all!
});

Only works in Firefox and, Chrome!

const inputNode = audioContext.createMediaStreamSource(stream);
      inputNode.connect(audioContext.destination);

2. Add effects to the guitar's sound

Volume pedal

const gainNode = audioContext.createGain();
      gainNode.gain.value = .5; // The volume is 50%

inputNode.connect(gainNode);
gainNode.connect(audioContext.destination);
100% 50% 150%

Distortion pedal

const waveShaperNode = audioContext.createWaveShaper();
      waveShaperNode.oversample = '4x';
      waveShaperNode.curve = fancyMathToCalculateCurve();

An example of an algorithm to calculate a distortion curve can be found here.

Toggle waveshaper

Delay pedal

const delayNode = audioContext.createDelay();
      delayNode.delayTime.value = 1; // 1 second delay

Flanger pedal

const oscillatorNode = audioContext.createOscillator();
      oscillatorNode.type = 'sine';
      oscillatorNode.frequency.value = 1000; // 1000Hz
Sine Square Triangle Sawtooth 400Hz 1000Hz 2000Hz Sound

Reverb pedal

const convolverNode = audioContext.createConvolver();

fetch('path/to/impulse-response-file', {
    method: 'get'
}).then(response => {
    return response.arrayBuffer();
}).then(buffer => {
    audioContext.decodeAudioData(buffer, buffer => {
        convolverNode.buffer = buffer;
    };
});

Impulse response file by Chris Wilson

Other nodes

  • AnalyserNode
  • BiquadFilterNode
  • ChannelSplitterNode
  • ChannelMergerNode
  • PannerNode
  • DynamicsCompressorNode
  • ...

audio-effects

https://github.com/sambego/audio-effects
import {Input, Distortion, Delay, Output} from 'audio-effects';

const audioContext = new AudioContext();
const input = new Input(audioContext);
const distortion = new Distortion(audioContext);
const delay = new Delay(audioContext);
const output = new Output(audioContext);

// Get the user's audio input
input.getUserMedia();

// Chain it all together
input.connect(distortion).connect(delay).connect(output);

Test test, one two, test

What if we don't have our hands available to controll the mouse?

web-midi-api

navigator.requestMIDIAccess().then(midi => {
    const inputs = midi.inputs.values(),
          devices = [],
          i;

    for (i = inputs.next(); i && !i.done; i = inputs.next()) {
        devices.push(i.value);
    }

    devices[0].onmidimessage = message => {
        // Incomming message from the first midi-device
    };
});

Thank you!

https://github.com/sambego/audio-effectshttps://sambego.github.io/pedalboardhttps://sambego.github.io/oscilloscope.jshttps://sambego.github.io/pedalboard-presentation
@sambego Sambego
Changing live audio with the web-audio-api