41 const float *window,
size_t window_capacity,
42 const float *cos_table,
const float *sin_table,
size_t table_capacity,
43 float *output,
size_t output_capacity,
size_t output_stride,
44 float *scratch,
size_t scratch_capacity,
45 size_t samples_count,
size_t n_fft,
size_t hop,
size_t frames,
46 double *complex_trace,
size_t complex_trace_capacity) {
47 size_t required_frames, spectral_elements, span, bins, table_need;
49 hop, &required_frames, &spectral_elements);
51 if (frames != required_frames || output_stride < frames ||
54 table_need = bins * n_fft;
57 if (samples_capacity < samples_count || window_capacity < n_fft ||
58 table_capacity < table_need || output_capacity < span ||
82 if (complex_trace_capacity < spectral_elements)
93 const size_t center = n_fft / 2;
94 for (
size_t frame = 0; frame < frames; ++frame) {
95 for (
size_t bin = 0; bin < bins; ++bin) {
96 double real = 0.0, imag = 0.0;
97 for (
size_t tap = 0; tap < n_fft; ++tap) {
99 const int64_t unreflected = (int64_t)(frame * hop + tap) -
102 if (unreflected < 0) source = (size_t)(-unreflected);
103 else if ((uint64_t)unreflected >= samples_count)
104 source = 2 * (samples_count - 1) - (size_t)unreflected;
105 else source = (size_t)unreflected;
106 const double value = (double)samples[source] * window[tap];
107 real += value * cos_table[bin * n_fft + tap];
108 imag += value * sin_table[bin * n_fft + tap];
113 if (bin == bins - 1) imag = 0.0;
114 const float magnitude = (float)hypot(real, imag);
115 const float phase = (float)atan2(imag, real);
116 if (!isfinite(magnitude) || !isfinite(phase))
119 const size_t index = 2 * (bin * frames + frame);
120 complex_trace[index] = real;
121 complex_trace[index + 1] = imag;
123 scratch[bin * frames + frame] = magnitude;
124 scratch[(bins + bin) * frames + frame] = phase;
127 for (
size_t row = 0; row < 2 * bins; ++row)
128 memcpy(output + row * output_stride, scratch + row * frames,
129 frames *
sizeof(
float));
148 size_t samples_capacity,
const float *window,
size_t window_capacity,
149 const float *cos_table,
const float *sin_table,
size_t table_capacity,
150 float *output,
size_t output_capacity,
size_t output_stride,
151 float *scratch,
size_t scratch_capacity,
152 size_t samples_count,
size_t n_fft,
size_t hop,
size_t frames,
153 double *complex_trace,
size_t complex_trace_capacity) {
156 window_capacity, cos_table, sin_table, table_capacity, output,
157 output_capacity, output_stride, scratch, scratch_capacity,
158 samples_count, n_fft, hop, frames, complex_trace,
159 complex_trace_capacity);
int audio_stft_mag_phase_checked_f32(const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames)
int audio_stft_mag_phase_trace_checked_f32(const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames, double *complex_trace, size_t complex_trace_capacity)
static int stft_mag_phase_impl(const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames, double *complex_trace, size_t complex_trace_capacity)