70 lines
2.4 KiB
C
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
|