12 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-04-17T15:50:04.390408+00:00 | zai-org/GLM-5-FP8 | 1 | 2a9358b1fffcd8a5 |
FftSharp Library Documentation
1. Purpose
FftSharp is a .NET library providing Fast Fourier Transform (FFT) operations and related signal processing utilities. It exists to enable frequency-domain analysis of signals through forward/inverse FFT, windowing functions, spectral filtering, and power spectral density calculations. The library serves as a core signal processing component, offering both high-performance production implementations and educational reference implementations of the DFT algorithm.
2. Public Interface
Complex (struct)
A mutable struct representing a complex number with cached magnitude calculations.
Properties:
double Real- Real component (setter invalidates cached magnitude values)double Imaginary- Imaginary component (setter invalidates cached magnitude values)double Magnitude- Computed assqrt(Real² + Imaginary²)(cached)double MagnitudeSquared- Computed asReal² + Imaginary²(cached)
Constructor:
Complex(double real, double imaginary)
Static Methods:
Complex Conjugate(Complex a)- Returns complex conjugate with negated imaginary componentComplex[] FromReal(double[] real)- Creates Complex array from real values (imaginary = 0)double[] GetMagnitudes(Complex[] input)- Extracts magnitude array from Complex array
Operators:
operator +(Complex a, Complex b)- Complex additionoperator -(Complex a, Complex b)- Complex subtractionoperator *(Complex a, Complex b)- Complex multiplicationoperator *(Complex a, double b)- Scalar multiplication
IWindow (interface)
Contract for window function implementations.
Members:
double[] Create(int size, bool normalize = false)- Generate window array of given lengthdouble[] Apply(double[] input, bool normalize = false)- Multiply signal by window, return new arrayvoid ApplyInPlace(double[] input, bool normalize = false)- Multiply signal by window in-placestring Name { get; }- Single-word window namestring Description { get; }- Description of window characteristics and use cases
Window (abstract class)
Base class for window implementations implementing IWindow.
Properties:
abstract string Name { get; }abstract string Description { get; }
Methods:
virtual double[] Create(int size, bool normalize = false)- Creates window array; caches result for reuse if same size/normalize requesteddouble[] Apply(double[] input, bool normalize = false)- Applies window usingParallel.Forvoid ApplyInPlace(double[] input, bool normalize = false)- In-place window application usingParallel.Forstatic IWindow[] GetWindows()- Reflects over assembly to instantiate allIWindowimplementationsstatic IWindow GetWindow(WindowType type)- Factory method returning window by enum type
Obsolete Static Methods (still public):
static double[] Rectangular(int pointCount)static double[] Hanning(int pointCount)static double[] Hamming(int pointCount)- Note: Implementation creates Hanning window, not Hammingstatic double[] Blackman(int pointCount)static double[] BlackmanCustom(int pointCount, double a = .42, double b = .5, double c = .08)static double[] BlackmanHarris(int pointCount)static double[] FlatTop(int pointCount)static double[] Bartlett(int pointCount)static double[] Cosine(int pointCount)static double[] Kaiser(int pointCount, double beta)static double[] Apply(double[] window, double[] signal)static void ApplyInPlace(double[] window, double[] signal)static string[] GetWindowNames()static double[] GetWindowByName(string windowName, int pointCount)
Enums:
WindowType- Bartlett, Blackman, BlackmanHarris, Cosine, FlatTop, Hamming, Hanning, Kaiser, Rectangular, Tukey, WelchWindowAveragingType- Averaging, PeakHoldMax, PeakHoldMin
Transform (static class)
Core FFT transformation operations.
FFT Methods:
void FFT(Complex[] buffer)- In-place FFT on array; validates power-of-2 lengthvoid FFT(Span<Complex> buffer)- In-place FFT on Span; validates power-of-2 lengthComplex[] FFT(double[] input)- Returns FFT of real input as Complex arrayComplex[] RFFT(double[] input)- Returns real FFT (length N/2+1) for real inputvoid RFFT(Span<Complex> destination, Span<double> input)- RFFT into provided destination
Inverse FFT:
void IFFT(Complex[] buffer)- In-place inverse FFT
Frequency Utilities:
double[] FFTfreq(double sampleRate, int pointCount, bool oneSided = true)- Returns frequency values for each FFT bindouble FFTfreqPeriod(int sampleRate, int pointCount)- Returns frequency spacing between bins
Magnitude/Power:
double[] Absolute(Complex[] input)- Returns magnitude arraydouble[] FFTmagnitude(double[] input)- Returns RMS-scaled magnitude spectrum (length N/2+1)void FFTmagnitude(Span<double> destination, Span<double> input)- In-place magnitude calculationdouble[] FFTpower(double[] input)- Returns power spectrum in dBvoid FFTpower(Span<double> destination, double[] input)- In-place power calculation
Power Spectral Density:
double[] PSD_Welch(double[] input, long sampleRate, WindowType windowType, int windowWidth, int overlapPct, WindowAveragingType averagingType, SetReadCalcProgressValueDelegate SetProgress = null)- Welch's method for PSD estimation
Mel Scale:
double MelToFreq(double mel)- Convert Mel to frequency (Hz)double MelFromFreq(double frequencyHz)- Convert frequency (Hz) to Meldouble[] MelScale(double[] fft, int sampleRate, int melBinCount)- Convert FFT to Mel scale
Utilities:
bool IsPowerOfTwo(int x)- Tests if value is power of 2Complex[] MakeComplex(double[] real)- Creates Complex array from real valuesvoid MakeComplex(Span<Complex> com, Span<double> real)- Populates Complex span from real spanT[] SubArray<T>(this T[] array, int offset, int length)- Extension method to extract subarray
Filter (static class)
Frequency-domain filtering operations.
Methods:
double[] LowPass(double[] values, double sampleRate, double maxFrequency)- Attenuates frequencies above thresholddouble[] HighPass(double[] values, double sampleRate, double minFrequency)- Attenuates frequencies below thresholddouble[] BandPass(double[] values, double sampleRate, double minFrequency, double maxFrequency)- Attenuates frequencies outside rangedouble[] BandStop(double[] values, double sampleRate, double minFrequency, double maxFrequency)- Attenuates frequencies inside range
Pad (static class)
Zero-padding utilities for array length adjustment.
Methods:
bool IsPowerOfTwo(int x)- Tests if value is power of 2Complex[] ZeroPad(Complex[] input)- Pads to next power of 2 (centered padding)double[] ZeroPad(double[] input)- Pads to next power of 2 (centered padding)Complex[] ZeroPad(Complex[] input, int finalLength)- Pads to specified length (centered padding)double[] ZeroPad(double[] input, int finalLength)- Pads to specified length (centered padding)
SampleData (static class)
Test data generation utilities.
Methods:
double[] Times(int sampleRate, int pointCount)- Generates time axis valuesdouble[] OddSines(int pointCount = 128, int sineCount = 2)- Sum of odd harmonic sinesvoid AddSin(double[] data, int sampleRate, double frequency, double magnitude = 1)- Adds sine wave to existing datavoid AddOffset(double[] data, double offset = 0)- Adds DC offsetvoid AddWhiteNoise(double[] data, double magnitude = 1, double offset = 0, int? seed = 0)- Adds uniform random noisedouble[] RandomNormal(int pointCount, double mean = .5, double stdDev = .5, int? seed = 0)- Generates normally distributed random values (Box-Muller transform)double[] SampleAudio1()- Returns hardcoded 512-point test signal (sum = 71.52)
Experimental (static class)
Educational reference implementations marked [Obsolete].
Methods:
Complex[] DFT(Complex[] input, bool inverse = false)- Naive O(N²) DFT implementationComplex[] DFT(double[] input, bool inverse = false)- DFT for real input
Private:
Complex[] FFTsimple(Complex[] input)- Recursive FFT implementation (non-optimized, educational)
3. Invariants
-
Power-of-2 Length Requirement: All FFT operations (
FFT,IFFT,RFFT,FFTMagnitude,FFTPpower,PSD_Welch) require input buffer lengths to be powers of 2. This is validated at runtime withArgumentException. -
Non-Empty Buffers:
FFTandIFFTthrowArgumentExceptionif buffer length is 0. -
RFFT Output Size:
RFFToutput length is alwaysinput.Length / 2 + 1. -
Window Caching:
Window.Createcaches the last generated window; subsequent calls with same size and normalize flag return the cached array. -
Centered Padding:
Pad.ZeroPadmethods add zeros centered around the input data (half before, half after). -
Filter Frequency Bounds:
LowPassusesdouble.NegativeInfinityas min;HighPassusesdouble.PositiveInfinityas max in theirBandPassdelegations. -
IFFT Scaling:
IFFTscales output by1/Nwhere N is buffer length. -
Magnitude Scaling:
FFTMagnitudescales DC component by1/Nand all other components by2/Nto account for positive/negative frequency combination.
4. Dependencies
Internal Dependencies (inferred from source):
Windowdepends onIWindowinterfaceFilterdepends onTransform.FFT,Transform.IFFT,Transform.FFTfreq, andComplexTransformdepends onComplex,Window,WindowType,WindowAveragingTypePaddepends onComplex
External Dependencies:
DTS.Common.Interface.SetReadCalcProgressValueDelegate- Used inPSD_Welchfor progress reportingDTS.Common.Strings.Strings- Localization strings used inPSD_Welchprogress messagesSystem.Buffers.ArrayPool<Complex>- Used inRFFT,FFTMagnitude,FFTPowerfor memory pooling
Standard Library Dependencies:
System,System.Linq,System.Reflection,System.Threading.Tasks,System.Buffers
Consumers (inferred):
- Unknown from provided source;
PSD_Welchsignature suggests integration with a larger DTS.Common framework
5. Gotchas
-
Hamming Window Bug: The obsolete
Window.Hamming(int pointCount)method incorrectly instantiatesnew Windows.Hanning(), not a Hamming window. This is a copy-paste error. -
Console Output in DFT:
Experimental.DFTcontainsConsole.WriteLine($"REAL {mult1} {mult2}")which produces unexpected console output when using the experimental DFT. -
Window.Create Returns Empty Array for Invalid Size: When
size <= 0,Window.Createreturnsnew double[0]rather than throwing an exception. -
Cached Window Mutation Risk:
Window.Createreturns the cachedlastWindowarray directly. Callers who mutate the returned array will corrupt the cache for subsequent calls. -
NormalizeInPlace Race Condition:
Window.NormalizeInPlaceusesParallel.Forto sum values into a localsumvariable without synchronization, causing a race condition. The sum calculation is non-deterministic under concurrent execution. -
Obsolete Methods Still Public: Many static methods in
Windowclass are marked[Obsolete]but remain public. The obsoleteApplyandApplyInPlacemethods require window and signal to be same length but throwArgumentException(notArgumentOutOfRangeException) on mismatch. -
PSD_Welch Segment Allocation: Creates
segmentsarray of sizeinput.Length / step, but only populatesinput.Length / stepsegments. May have uninitialized trailing elements if input length is not evenly divisible. -
MelScale Division by Zero:
MelScaledivides bybinScaleSumwhich could be zero ifindexSpanis 0 (whenindexHigh == indexLow). -
Complex Struct Mutability:
Complexis a struct with mutable properties. SettingRealorImaginaryinvalidates cached_magnitudeand_magnitudeSquared, but if the struct is boxed or copied, mutations may not propagate correctly.