Я пытаюсь извлечь информацию о частоте простого 16-битного pcm wav-файла, содержащего только один чистый тон (750 Гц, созданный с помощью Audacity) в JavaScript с nodejs.
, который я использую:
Вот код, который я придумал:
const wav = require('node-wav');
const FFT = require('fft.js');
const fs = require('fs');
const plotlib = require('nodeplotlib');
let size = 4096; //fft size
let fft = new FFT(size); //create fft object
let realOutput = new Array(size); // to store final result
let complexOutput = fft.createComplexArray(); // to store fft output
let buffer = fs.readFileSync('750hz.wav'); // open a 1s wav file(mono 16bit pcm file at 32000hz) containing only a 750hz sinusoidal tone
let result = wav.decode(buffer); // read wav file data
let audioData = Array.prototype.slice.call( result.channelData[0]); // convert Float32Array to normal array
realInput = audioData.slice(0,size); // use only 4096 sample from the buffer.
fft.realTransform(complexOutput, realInput); // compute fft
// fft.completeSpectrum(complexOutput);
fft.fromComplexArray(complexOutput,realOutput); // get rid of the complex value and keep only real
let x =[];
for(let i=0;i<size;i++) x.push(i); //create a simple dumb x axis for the fft plot
plotlib.plot( // plotting the input data
[{
x: x,
y: realInput,
type: 'line',
name:'input'
}]
);
plotlib.plot( // plotting the fft output
[{
x: x,
y: realOutput,
type: 'line',
name:'output'
}]
);
Построение входных данных из кода выше дает мне:
И результат выглядит следующим образом:
Пока я ожидал получить только один spike, что-то вроде этого:
- Что-то не так с моим кодом или вывод должен выглядеть так, и я что-то пропустил о том, как генерировать частотный спектр из БПФ?
- Может ли БПФ работать со значением с плавающей запятой или его нужно сначала преобразовать в целое число?
- Нужна ли мне сложная часть вывода fft в моем случае?