/* SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * Frv - Frame vector library
 *
 * Copyright © 2001-2021 Laboratoire d'Annecy de physique des particules - CNRS
 * Copyright © 2019-2021 Institut pluridisciplinaire Hubert CURIEN - CNRS
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef FRVFFT
#define FRVFFT

#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
/*---------------------------------------------------------------------------*/
/*  Author : F. Marion, B.Mours and D.Buskulic LAPP (Annecy) Mar 01, 2005    */
/*---------------------------------------------------------------------------*/

#include "FrameL.h"
#include "FrvBuf.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct FrvBandRms FrvBandRms;
typedef struct FrvRFFT    FrvRFFT;

struct FrvBandRms {
  FrvRFFT *fft;             /* fourrier transform object                     */
  char *channel;            /* first channel                                 */
  int nAverage;             /* number of FFT averaged                        */
  double freqMin;           /* frequency start for the band                  */
  double freqMax;           /* band frequency stop;                          */
  double rms;               /* signal rms in that band                       */
  double GTime;             /* GPS time expected for the next frame          */
};

void        FrvBandRmsFree(FrvBandRms *rms);
FrvBandRms* FrvBandRmsNew(char *channel, double FFTduration, int nAverage,
                         double freqMin, double freqMax);
int         FrvBandRmsProc(FrvBandRms* rms, FrameH *frame);

struct FrvRFFT {
                             /*--------------------- input data -------------*/
  long nAverage;             /* # of requested average                       */
  int fftSize;               /* fftsize fft vector size (number of samples)  */
  int decimate;              /* decimation apply (no decimate if set to 0)   */
  double duration;           /* FFT length in seconds                         */
  int medianPeriod;          /* the median is computed every medianPeriod FFT*/
                             /*------------------- internal data ------------*/
  FRBOOL  optionA;           /* if = FR_YES compute the average amplitude    */
  FRBOOL  optionM;           /* if = FR_YES compute the median amplitude    */
  FRBOOL  optionH;           /* if = FR_YES apply an hanning window          */
  FRBOOL  optionO;           /* if = FR_YES overlapp data by half a vector   */
  FRBOOL  optionN;           /* if = FR_YES normalized the result by sqrt(Hz)*/
  FRBOOL  optionP;           /* if = FR_YES suppress the pedestal(mean value)*/
  FRBOOL  optionS;           /* if = FR_YES compute the amplitude spectrum   */
  FRBOOL  optionR;           /* if = FR_YES keep the raw hermitian order     */
  FRBOOL  optionF;           /* if = FR_YES use a 32 bits version of fft     */
  long   nData;              /* number of data points used by the fft        */
  long   nDataP2;            /* nearest log base2 of nBin                    */
  double dt;                 /* time sampling frequency                      */
  double dnu;                /* frequency bin size                           */
  struct FrVect *window;     /* vector to hold the window                    */
  struct FrVect *temp;       /* vector to hold a working space               */
  struct FrvBuf *buffer;     /* internal buffer for vector resizing          */
  char   *name;              /* name of the input vector                     */
  void*  plan;               /* FFTW plan(type is fftw_plan)                 */
  double *array_for_sorting;
  double **array_for_median;
                             /* ------------output-------------------------  */
  double mean;               /* time serie mean value                        */
  struct FrVect *output;     /* vector to hold the complex FFT               */
  struct FrVect *amplitude;  /* vector to hold the last amplitude spectrum   */
  struct FrVect *amplitudeA; /* vector to hold the averaged amplitude        */
  long nFFT;                 /* number of fft computed                       */
  char err[256];             /* hold error message if any                    */
};

void     FrvRFFTFree(FrvRFFT* fft);
int      FrvRFFTInit(FrvRFFT *fft, FrVect *vect);
FrvRFFT* FrvRFFTNew(char* option, int fftSize, int decimate);
FrvRFFT* FrvRFFTNewT(char* option, double duration, int nAverage);
FrvRFFT* FrvRFFTFor(FrvRFFT *fft, FrVect *vect);
int      FrvRFFTSetMedianPeriod(FrvRFFT* fft, int medianPeriod);

void     FrvFFTD704(double *a, long msign);

double MedianBias( int nn );

#ifdef __cplusplus
}
#endif

#endif
