Superpowered.Analyzer and .Waveform are completely broken?
JohannesKlauss opened this issue · 5 comments
I am trying to evaluate the SDK for a large web audio project, but it is giving me a hard time to get anything donw.
Nothing the analyzer calculates makes any sense.
I have a mono wave file containing a 1kHz sine wave tone for 1s at -3dBFS which I use to check results of the analyzer.
This is my code (running at 44.1 KHz sample rate and it lives inside a worker):
const leftChannel = new Superpowered.Float32Buffer(e.data.inputSabLeftChannel.length);
const rightChannel = new Superpowered.Float32Buffer(e.data.inputSabRightChannel.length);
leftChannel.array = e.data.inputSabLeftChannel.slice();
rightChannel.array = e.data.inputSabRightChannel.slice();
const interleavedArray = new Superpowered.Float32Buffer(e.data.inputSabLeftChannel.length * 2);
Superpowered.Interleave(leftChannel.pointer, rightChannel.pointer, interleavedArray.pointer, leftChannel.length);
const waveform = new Superpowered.Waveform(
e.data.sampleRate,
e.data.duration,
);
waveform.process(
interleavedArray.pointer,
128,
e.data.duration,
);
waveform.makeResult();
const peakWaveform = waveform.getPeakWaveform();
console.log('peaks', peakWaveform.array);First of all the documentation is wrong. The docs tell to access the peak waveform via waveform.peakWaveform which returns undefined. I had to return all the keys of the waveform object to see that I have to call waveform.getPeakWaveform(). But this also returns nonsense.
Because even though I process only 128 frames of the 44100 available frames, the peaksWaveform array has a length of 47312.
The first values are:
[0, 0, 0, 0, 169, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]
Which also makes no sense.
Also there is no documentation on what the third parameter on waveform.process actually does. It doesn't seem to matter, because putting in -1, 0, or 1 returns the same peaks array.
Am I doing something wrong here? For context, this is my init code inside the worker:
importScripts('../superpowered/SuperpoweredGlue.js');
// Create a SuperpoweredGlue instance and load WebAssembly:
let Superpowered;
let isReady = false;
SuperpoweredGlue.fetch('../superpowered/superpowered.wasm').then((res) => {
Superpowered = res;
// Initialize Superpowered.
Superpowered.Initialize({
licenseKey: 'ExampleLicenseKey-WillExpire-OnNextUpdate',
enableAudioAnalysis: true,
enableFFTAndFrequencyDomain: true,
enableAudioTimeStretching: false,
enableAudioEffects: false,
enableAudioPlayerAndDecoder: true,
enableCryptographics: false,
enableNetworking: false
});
isReady = true;
});Thanks discovering the documentation bug. Yes, you need to use getPeakWaveform().
Don't assign values like this: leftChannel.array = e.data.inputSabLeftChannel.slice();
The buffer ("leftChannel") represents a region in WebAssembly linear memory. Overwriting its "array" property points to a regular memory object this way, so WebAssembly can't read that.
How would I assign the array then?
leftChannel.array.set(e.data.inputSabLeftChannel) produces the same result?
Do I have to for loop the assignment? Seems counterproductive to loop through the arrays to be able to use WebAssembly.
Also looping it with
for(let i = 0; i < leftChannel.length; i++) {
leftChannel.array[i] = e.data.inputSabLeftChannel[i];
rightChannel.array[i] = e.data.inputSabRightChannel[i];
}doesn't work and produces the same incorrect result.
waveform.process(interleavedArray.pointer, e.data.inputSabLeftChannel.length, -1);
The size of the result is waveform.waveformSize, not the array length, since it's just a "memory view", not a "true array".
Just updated Superpowered, now the returned typed array has the correct length set.