Created
April 11, 2016 00:55
-
-
Save sleexyz/51d3d7e13321c786a6e1cf923c5e0233 to your computer and use it in GitHub Desktop.
mfcc?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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