/** Shared host-side FFT for Android/JNI and desktop/ctypes; no GUI dependencies. */ #ifndef SET_SPECTRUM_H #define SET_SPECTRUM_H #include "pcan_abi.h" #ifdef __cplusplus extern "C" { #endif #define SET_SPECTRUM_MAX 16384U enum { SET_WINDOW_RECT, SET_WINDOW_HANN, SET_WINDOW_HAMMING, SET_WINDOW_BLACKMAN, SET_WINDOW_FLATTOP }; enum { SET_FILTER_NONE, SET_FILTER_LOW_PASS, SET_FILTER_HIGH_PASS, SET_FILTER_BAND_PASS, SET_FILTER_NOTCH }; enum { SET_SPECTRUM_OK, SET_SPECTRUM_SHORT, SET_SPECTRUM_INVALID, SET_SPECTRUM_TIMING, SET_SPECTRUM_CUTOFF, SET_SPECTRUM_MEMORY }; /** Analyze the last power-of-two block (16 <= N <= max_size). * times are seconds, strictly increasing; values must be finite. Fs is measured * from timestamps, never taken from the requested acquisition rate. Interval * deviations >50% of the mean are rejected; smaller jitter is linearly resampled. * Filter: second-order Butterworth LP/HP, their cascade for band pass, notch Q=30. * low_hz: HP/band lower cutoff or notch center; high_hz: LP/band upper cutoff. * Each block starts the causal filters at steady state for its first sample. * Processing order: resample, optional mean removal, filter, periodic window, FFT. * Output: one-sided PEAK amplitude, normalized by window sum, DC/Nyquist not doubled. * Caller supplies max_size/2+1 amplitudes; meta = {N, Fs, max relative jitter}. * Inputs are immutable. Scratch memory is bounded by 2*N doubles, allocated here. */ PCAN_ABI_API int set_spectrum_analyze(const double *times, const double *values, size_t count, size_t max_size, int window, int filter, double low_hz, double high_hz, int remove_mean, double *amplitudes, size_t capacity, double *meta); /** Find the strongest non-DC local maximum above both the absolute floor and * relative_threshold * median(non-DC amplitudes). The caller supplies scratch * storage of at least count-1 doubles. peak = {frequency_hz, amplitude}. * Returns 1 when found, 0 when no narrow-band peak exists, -1 on invalid input. */ PCAN_ABI_API int set_spectrum_dominant_peak(const double *amplitudes, size_t count, double bin_hz, double relative_threshold, double absolute_floor, double *scratch, size_t scratch_capacity, double *peak, size_t peak_capacity); #ifdef __cplusplus } #endif #endif