joeylib2/tests/gate/common/gateFft.h

70 lines
2.4 KiB
C

// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
// See LICENSE.md for license information.
// SPDX-License-Identifier: MIT
//
// gateFft.h - numpy's spectral arithmetic for the gate tools: the discrete
// Fourier transform of any length, and the pieces of numpy around it that
// the graders lean on (its sum, its Hann window, its bin frequencies), each
// computed in the order numpy computes it so a grade reads as it did.
#ifndef GATE_FFT_H
#define GATE_FFT_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
// Prime factors a length can have (2^64 needs 64).
#define GATE_FFT_FACTORS_MAX 64u
// A transform of n points: mixed radix over its prime factors (the roots
// of unity, and a butterfly's twiddled inputs, its spokes), or, when one of
// them is too large for a direct butterfly, Bluestein's chirp through a
// power-of-two transform (inner).
typedef struct GateFftT {
size_t n;
size_t factorCount;
size_t factors[GATE_FFT_FACTORS_MAX];
double *rootRe;
double *rootIm;
double *inRe;
double *inIm;
double *outRe;
double *outIm;
double *spokeRe;
double *spokeIm;
struct GateFftT *inner;
double *chirpRe;
double *chirpIm;
double *filterRe;
double *filterIm;
} GateFftT;
// numpy.abs(numpy.fft.rfft(in[0..inLen), fft->n)): the n / 2 + 1 bins'
// magnitudes (hypot, as numpy takes them).
void gateFftAbs(GateFftT *fft, const double *in, size_t inLen, double *magnitude);
void gateFftFree(GateFftT *fft);
// A plan for transforms of n (at least 1) points. Running out of memory is
// fatal (toolFail).
void gateFftInit(GateFftT *fft, size_t n);
// numpy.fft.rfft(in[0..inLen), fft->n): the n / 2 + 1 bins, the input
// zero-padded (or cut) to n points.
void gateFftReal(GateFftT *fft, const double *in, size_t inLen, double *re, double *im);
// numpy.hanning(n): the symmetric Hann window.
void gateHanning(double *window, size_t n);
// numpy.mean of n doubles: gateSum / n.
double gateMean(const double *x, size_t n);
// numpy.fft.rfftfreq(n, 1.0 / rate)[bin].
double gateRfftFreq(size_t bin, size_t n, uint32_t rate);
// numpy.sum of n doubles: pairwise (eight running sums, halved past 128),
// a buffer (8192) at a time, the buffers' sums added in turn.
double gateSum(const double *x, size_t n);
#endif