calculateSpectrogram function
Computes the power spectrogram via Short-Time Fourier Transform (STFT).
Returns a list of Float64List, where each element represents the power spectrum of a frame.
samples: The audio signal.
hopSize: Number of samples between frames. Defaults to fftSize / 4.
fftSize: Size of the FFT window.
Implementation
List<Float64List> calculateSpectrogram(
List<double> samples, {
int? hopSize,
int fftSize = 2048,
}) {
final hop = hopSize ?? fftSize ~/ 4;
final padAmount = fftSize ~/ 2;
if (samples.length < padAmount) {
throw ArgumentError(
'Signal length (${samples.length}) must be >= fftSize // 2 ($padAmount).',
);
}
final paddedSamples = Float64List.fromList(_padReflect(samples, padAmount));
final window = Float64List(fftSize);
for (int i = 0; i < fftSize; i++) {
window[i] = 0.5 * (1.0 - cos(2.0 * pi * i / fftSize));
}
final stft = STFT(fftSize, window);
final spectrogram = <Float64List>[];
stft.run(paddedSamples, (Float64x2List freq) {
final bins = freq.discardConjugates();
final expectedBins = fftSize ~/ 2 + 1;
if (bins.length != expectedBins) {
throw StateError('STFT bin mismatch.');
}
final mags = bins.magnitudes();
for (int i = 0; i < mags.length; i++) {
mags[i] *= mags[i];
}
spectrogram.add(mags);
}, hop);
return spectrogram;
}