1- #include < algorithm>
21#include < cstddef>
3- #include < limits>
42#include < math.h>
53#include < rnexecutorch/data_processing/FFT.h>
64#include < rnexecutorch/data_processing/dsp.h>
@@ -18,48 +16,4 @@ std::vector<float> hannWindow(size_t size) {
1816 return window;
1917}
2018
21- std::vector<float > stftFromWaveform (std::span<const float > waveform,
22- size_t fftWindowSize, size_t hopSize) {
23- // Initialize FFT
24- FFT fft (fftWindowSize);
25-
26- const auto numFrames = 1 + (waveform.size () - fftWindowSize) / hopSize;
27- const auto numBins = fftWindowSize / 2 ;
28- const auto hann = hannWindow (fftWindowSize);
29- auto inBuffer = std::vector<float >(fftWindowSize);
30- auto outBuffer = std::vector<std::complex <float >>(fftWindowSize);
31-
32- // Output magnitudes in dB
33- std::vector<float > magnitudes;
34- magnitudes.reserve (numFrames * numBins);
35- const auto magnitudeScale = 1 .0f / static_cast <float >(fftWindowSize);
36- constexpr auto epsilon = std::numeric_limits<float >::epsilon ();
37- constexpr auto dbConversionFactor = 20 .0f ;
38-
39- for (size_t t = 0 ; t < numFrames; ++t) {
40- const size_t offset = t * hopSize;
41- // Clear the input buffer first
42- std::ranges::fill (inBuffer, 0 .0f );
43-
44- // Fill frame with windowed signal
45- const size_t samplesToRead =
46- std::min (fftWindowSize, waveform.size () - offset);
47- for (size_t i = 0 ; i < samplesToRead; i++) {
48- inBuffer[i] = waveform[offset + i] * hann[i];
49- }
50-
51- fft.doFFT (inBuffer.data (), outBuffer);
52-
53- // Calculate magnitudes in dB (only positive frequencies)
54- for (size_t i = 0 ; i < numBins; i++) {
55- const auto magnitude = std::abs (outBuffer[i]) * magnitudeScale;
56- const auto magnitude_db =
57- dbConversionFactor * log10f (magnitude + epsilon);
58- magnitudes.push_back (magnitude_db);
59- }
60- }
61-
62- return magnitudes;
63- }
64-
6519} // namespace rnexecutorch::dsp
0 commit comments