//
// Created by Alberto on 2020-05-06.
//

#ifndef DataDefine
#define DataDefine

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <float.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <math.h>



#define _GNU_SOURCE 1

#ifdef OMP
#include <omp.h>
#endif

#ifdef MKL
#ifdef CBLAS
    #include <mkl.h>
  #endif
#else
#ifdef CBLAS
#include <cblas.h>
    #include <lapacke.h>
#endif
#endif

#include <complex.h>
#include <fftw3.h>
#include "mt19937ar/mt19937ar.h"

/* Constants */
#define PI    3.141592653589793
#define DosPI 6.283185307179586
#define dEPS  2.220446049250313e-16
#define sEPS  2.2204460e-08
#define eta   10e-5                 // cota de error usada en uNMF

#define coefcoThreshold  0.00
#define energyThreshold  0.85
#define fcThreshold    260.00
#define simThreshold     0.40

#define freqHz     8000
#define seconds    0.064 // (freqHz*mseg)=window size (hanning)
#define secondsHSD 0.125 // (freqHz*mseg)=window size (hanning) para Heart Sound Detection
#define overlap    0.500
#define freqCut    60.0  // [0-freqCut] frecuencias de no solapamiento entre sonidos de corazon y pulmon

#define bcCorazon 55
#define bcPulmon  64
#define lambda    0.73
#define beta      1.0
#define maxIter   400

/* Local types */
#ifdef SIMPLE
#define MyType       float
   #define MyTypecompl  float complex
   #define MyFFTcompl   fftwf_complex
   #define MyFFTCPUType fftwf_plan
#else
#define MyType       double
#define MyTypecompl  double complex
#define MyFFTcompl   fftw_complex
#define MyFFTCPUType fftw_plan
#endif
#define MyFFTGPUType    cufftHandle

struct ValueAndPos
{
    MyType data;
    int    pos;
};
typedef struct ValueAndPos ValueAndPos;

#define WAVHeaderLength 40

struct WAVHeader
{
    unsigned char header[WAVHeaderLength];
    long num_samples;

};
typedef struct WAVHeader WAVHeader;

/* For check errors */
#define OK            0
#define ErrOpenFile  -1
#define ErrReadFile  -2
#define ErrWriteFile -3
#define ErrWavFormat -4
#define ErrNULL      -5

#define CHECKERR(x) do { if((x)<0) { \
   printf("Error %d calling %s line %d\n", x, __FILE__, __LINE__);\
   return x;}} while(0)

#define CHECKNULL(x) do { if((x)==NULL) { \
   printf("NULL (when open file or  memory allocation calling %s line %d\n", __FILE__, __LINE__);\
   return ErrNULL;}} while(0)

#define CUDAERR(x) do { if((x)!=cudaSuccess) { \
   printf("CUDA error: %s : %s, line %d\n", cudaGetErrorString(x), __FILE__, __LINE__);\
   return EXIT_FAILURE;}} while(0)

#define CUBLASERR(x) do { if((x)!=CUBLAS_STATUS_SUCCESS) { \
   printf("CUBLAS error: %s, line %d\n", __FILE__, __LINE__);\
   return EXIT_FAILURE;}} while(0)

#define CUFFTERR(x) do { if((x)!=CUFFT_SUCCESS) { \
   printf("CUFFT error: %s, line %d\n", __FILE__, __LINE__);\
   return EXIT_FAILURE;}} while(0)

#ifndef min
#define min(x,y) ((x < y) ? x : y)
#endif

#ifndef max
#define max(x,y) ((x > y) ? x : y)
#endif

#endif
