Skip to content

Instantly share code, notes, and snippets.

@sleexyz
Created April 11, 2016 00:55
Show Gist options
  • Save sleexyz/51d3d7e13321c786a6e1cf923c5e0233 to your computer and use it in GitHub Desktop.
Save sleexyz/51d3d7e13321c786a6e1cf923c5e0233 to your computer and use it in GitHub Desktop.
mfcc?
const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;
let multiplied = false;
let canvas = document.getElementById("canvas");
canvas.width = WIDTH;
canvas.height = HEIGHT;
let canvasCtx = canvas.getContext("2d");
// navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
let drawVisual = null;
console.log(WIDTH);
function hzToMel (f) {
return 1127 * Math.log(1 + f/700);
}
function melToHz (m) {
return 700 * (Math.exp(m/1127) - 1);
}
navigator.mediaDevices.getUserMedia( {audio: true})
.then((stream) => {
let audioCtx = new (window.AudioContext || window.webkitAudioContext)();
let source = audioCtx.createMediaStreamSource(stream);
// source.connect(audioCtx.destination);
let analyser = audioCtx.createAnalyser();
source.connect(analyser);
analyser.fftSize = 2048;
let bufferLength = analyser.frequencyBinCount;
let dataArray = new Uint8Array(bufferLength);
const fftBinWidth = audioCtx.sampleRate/analyser.fftSize;
console.log(fftBinWidth);
const numBins = 40;
const numPoints = numBins + 2;
const numSections = numBins + 1;
const melDataArray = new Float32Array (numBins);
const buffer = [];
const melWidth = hzToMel(8000)/numSections;
const fromFFTTri = (input) => {
for (let i = 0; i < melDataArray.length; i++) {
let multipliers = [];
let minHz = melToHz (i * melWidth);
let centerHz = melToHz ((i+1) * melWidth);
let maxHz = melToHz ((i+2) * melWidth);
let slopeAscending = 1/(centerHz - minHz);
let slopeDescending = 1/(centerHz - maxHz);
let minInputIndex = (minHz/fftBinWidth);
let maxInputIndex = (maxHz/fftBinWidth);
if (!multiplied) console.log(minHz, centerHz, maxHz);
melDataArray[i] = 0.0;
for (let inputIndex = minInputIndex; inputIndex < maxInputIndex; inputIndex++) {
let mult;
let hz = inputIndex * fftBinWidth;
if (hz < centerHz ) {
mult = (hz - minHz) * slopeAscending;
} else {
// hz > centerHz
mult = 1 + (hz - centerHz) * slopeDescending;
}
let incrementBy = mult * input[Math.floor(inputIndex)];
multipliers.push(mult);
melDataArray[i] += incrementBy;
}
melDataArray[i] = Math.log((melDataArray[i]) + 1);
if (!multiplied) console.log(multipliers);
}
multiplied = true;
};
// console.log(fromFFTTri(dataArray));
canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
function color (r, g, b, a) {
let colorStr = "rgba(" + Math.floor(r * 255) + "," + Math.floor(g * 255) + "," + Math.floor(b* 255) + "," + a + ")";
canvasCtx.fillStyle = colorStr;
};
function draw () {
drawVisual = requestAnimationFrame(draw);
analyser.getByteFrequencyData(dataArray);
fromFFTTri(dataArray);
let dct =DCT (melDataArray);
if (buffer.length > 40) {
buffer.shift();
}
buffer.push(dct);
color(1, 1, 1, 0);
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
color(0, 0, 0, 1);
for (let i = 0; i< buffer.length; i++) {
for (let j = 0; j < buffer[i].length; j++) {
v = buffer[i][j]* 0.5 + 0.5;
color(v, v, v, 1);
canvasCtx.fillRect(i*WIDTH/buffer.length
, j * HEIGHT/buffer[i].length
, (i+1) * WIDTH/buffer.length
, (j+1) * HEIGHT/buffer[i].length);
}
}
if (!poop) {
console.log(buffer);
}
poop = true;
};
draw();
})
.catch((err) => {console.log(err);});
const DCTSize = 11;
function DCT (input) {
let N = input.length;
let output = new Float32Array(DCTSize);
let incrementBy = [];
for (let i = 2; i < 2 + DCTSize; i++) {
k = i-2;
output[k] = 0;
for (let n = 0; n < N; n++) {
let inc = input[n] * Math.cos ((Math.PI/N) * (n +0.5) * k);
incrementBy.push(input[n]);
output[k] += inc;
}
// output[k] = output[k];
}
return output;
}
function Copy (input) {
let output = new Float32Array(input.length);
for (let i = 0; i< output.length; i++) {
output[i] = input[i];
}
return output;
}
poop = false;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment