Last active
April 25, 2020 17:47
-
-
Save jakubfiala/368e7beeed14dc84abd3 to your computer and use it in GitHub Desktop.
Offline feature extraction in Meyda v2
This file contains 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
//Because meyda v2 doesn't really have an offline extraction API, we need to manually require some stuff | |
var jsfft = require("./node_modules/meyda/node_modules/jsfft/") | |
var complex_array = require("./node_modules/meyda/node_modules/jsfft/lib/complex_array.js") | |
var extractors = require("./node_modules/meyda/dist/node/featureExtractors.js") | |
var meyda_utils = require("meyda").utils | |
//this is a simple class for streaming WAV data as Float32Arrays | |
//available at https://gist.github.com/jakubfiala/cb9de100fdd4f043d46e | |
//we're not going to use its streaming functionality for simplicity | |
var WavManager = require("./wav-manager.js") | |
var fs = require('fs') | |
//extraction parameters | |
var bufSize = 1024 | |
var hopSize = 512 | |
//this is the core of the hack - we circumvent the SPN inside Meyda by calculating the spectrum ourselves (using jsfft) | |
//so we can pass it to the extractor function directly | |
function getSpectrum(_d) { | |
var windowedSignal = meyda_utils.applyWindow(_d, 'hanning') | |
// create complexarray to hold the spectrum | |
var data = new complex_array.ComplexArray(_d.length) | |
// map time domain | |
data.map(function(value, i, n) { | |
value.real = windowedSignal[i] | |
}) | |
// transform | |
var spec = data.FFT() | |
// assign to meyda | |
var ampSpectrum = new Float32Array(_d.length/2) | |
for (var i = 0; i < _d.length/2; i++) { | |
ampSpectrum[i] = Math.sqrt(Math.pow(spec.real[i],2) + Math.pow(spec.imag[i],2)) | |
} | |
return ampSpectrum | |
} | |
var mfccs = [] | |
//the constructor of WavManager takes 2 functions as args | |
//one to handle the stream chunk by chunk, | |
//and one to handle the full final data | |
// it's not very elegant or efficient, but whatever | |
var wm = new WavManager(function(data){}, | |
function(fulldata){ | |
//callback for stream end | |
//we iterate through the data frame by frame | |
for (var i = 0; i < fulldata.length-bufSize; i += hopSize) { | |
//get the chunk | |
var chunk = fulldata.subarray(i, i+bufSize) | |
//call the extractor function and pass in the spectrum of the chunk | |
mfccs.push(extractors.mfcc({ | |
ampSpectrum: getSpectrum(chunk), | |
bufferSize: bufSize, | |
sampleRate: 44100 //change this if needed | |
})) | |
} | |
} | |
) | |
console.log("results:", mfccs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
HELPPPPPPPPPPPPP!!!!!!!