Skip to content

Instantly share code, notes, and snippets.

@mattdesl
Last active September 29, 2023 20:08
Show Gist options
  • Save mattdesl/c78327967c351d3867e4dedade08c4cd to your computer and use it in GitHub Desktop.
Save mattdesl/c78327967c351d3867e4dedade08c4cd to your computer and use it in GitHub Desktop.
canvas-sketch + audio example https://microphone-circle.surge.sh/
const canvasSketch = require('canvas-sketch');
// A handy module to compute the average signal between two frequencies
// https://www.npmjs.com/package/analyser-frequency-average
const frequencyAverage = require('analyser-frequency-average');
const settings = {
// Animate the sketch
animate: true
};
const sketch = async () => {
// Try to get a browser audio context
const AudioContext = (window.AudioContext || window.webkitAudioContext);
if (AudioContext == null) throw new Error("Your browser doesn't support Web Audio");
// Create a new audio context
const audioContext = new AudioContext();
// Grab a microphone stream
const stream = await getAudioStream();
// Wrap the stream in an audio node
const node = audioContext.createMediaStreamSource(stream);
// Create an analyser
const analyser = audioContext.createAnalyser();
const frequencies = new Uint8Array(analyser.frequencyBinCount);
// Connect the node to the analyser
node.connect(analyser);
// Optionally connect the microphone to output
// Warning: Might result in loud feedback!
// node.connect(audioContext.destination);
return ({ context, width, height }) => {
// White background
context.fillStyle = 'white';
context.fillRect(0, 0, width, height);
// Fill array with new FFT data
analyser.getByteFrequencyData(frequencies);
// The range of frequencies we want to listen for
const minHz = 100;
const maxHz = 5000;
const signal = frequencyAverage(analyser, frequencies, minHz, maxHz);
// Base of circle
const dimension = Math.min(width, height) * 0.25;
const radius = dimension + signal * dimension;
// Draw circle
context.fillStyle = 'red';
context.beginPath();
context.arc(width / 2, height / 2, radius, 0, Math.PI * 2, false);
context.fill();
};
};
canvasSketch(sketch, settings);
async function getAudioStream () {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
return navigator.mediaDevices.getUserMedia({ audio: true, video: false });
} else {
if (window.location.protocol === 'http:' && window.location.hostname !== 'localhost') {
console.warn(`🚨 getUserMedia requires HTTPS or local host.\nTry opening to http://localhost:${window.location.port}/ instead`);
}
throw new Error('getUserMedia not supported or disabled in this browser session');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment