
#include "kernel.cuh"

#include "healpixkernel_sds.h"
#include "micarray_sds.h"

#define NOMINMAX
#define _USE_MATH_DEFINES
#include <cmath>

#include <nlohmann/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#define HEALPixOrder 2
#define MicNumber 32
#define MaxSphericalHarmonicsOrder 4
#define AngleDiff 0.79
#define RENTThreshold 0.5
#define PI 3.14159
#define RENTIIteration 3;

using json = nlohmann::json;
struct RENTData {
	float* Histogram;
	float* MaxValuedHistogram;
	int NofPixels;
	int PlaneDim;
	int NofFrequencybinAnalysis;
};

struct DOA_Data {
	int hpnumber;
	float theta;
	float phi;
	float distance;
	float x;
	float y;
	float z;
	bool firstin;
	int activeframe;
	string uuid;
};

struct complex_num {
	float* real = 0;
	float* imag = 0;
	float* pressurelevel = 0;
};


class  speechdetectionandseparation
{
public:
	speechdetectionandseparation(char microphone_array_geometry[],int blocksize);
	void* initialization(int windowsize);
	int RENTComputation(float* stft_ch_real, float* stft_ch_imag);
	complex_num SpeechSeparation();
	complex_num Return_BlockSRF();
	json audioscenegeometry_out();
	void hammingwindow(int windowLength);
private:

	int* SortInDescendingOrder(int NofPixels, int* inp_mt, float average);
	int healpix_samplingpoints;
	float* magkernels;
	float* magkernels_img;
	float* multiplicationres;
	float* multiplicationres_imag;
	float* kr_1_real;
	float* kr_1_imag;
	float* srf_magkernels;
	float* srf_magkernels_img;
	vector<float> micanglestheta;
	vector<float> micanglesphi;
	float* hammingwin;


	healpixkernel_sds* hp_kernel;
	micarray_sds micarr;
	vector<DOA_Data> source_doas;

	//json file parameters
	int nofmicrophones;
	int nofsamples;
	ArrayType_sds array_type;
	ArrayScattering_sds array_scattering_type;
	int sampling_rate;
	int sample_type;
	int block_size;
	int samplingrates[8] = { 16000,24000,32000,44100,48000,64000,96000,192000 };
	int sampletypes[3] = { 16,24,32 };
	int blocksizes[8] = { 64,128,256,512,1024,2048,4096,8192 };
	int AudioBlockSize;
	int MaxNumberofSeparatedObjects;
	int FrequencybinAnalysisStart = 0;
	int NumberofFrequencybins; // = 1024;
	int RENT_iteration; // = RENTIIteration;
	float* max_hist;
// Block information parameters
	int BlockIndex;
	int BlockStart;
	int BlockEnd;



	// GPU device malloc parameters
	const float* dev_a = 0;
	const float* dev_b = 0;
	const float* dev_c = 0;
	const float* dev_kernel = 0;
	const float* dev_kernels_vonmises = 0;
	const float* dev_input = 0;

	const float* dev_histogram = 0;
	const float* dev_RENT_histogram = 0;
	const float* dev_magnitudes = 0;
	const float* dev_magnitudes_im = 0;
	const float* dev_input_im = 0;

	const float* dev_magnitudes_final = 0;
	const float* dev_magnitudes_im_final = 0;

	const float* dev_general_histogram = 0;
	const float* dev_multiplication_kernel = 0;
	const float* dev_multiplication_kernel_imag = 0;

	const float* dev_a_im = 0;
	const float* dev_b_im = 0;
	const float* dev_c_im = 0;
	const float* dev_kernel_im = 0;

	const float* dev_result;
	const float* dev_result_im;

	const float* dev_res_kernel = 0;
	const float* dev_pinv_kernel = 0;
	const float* dev_kr_matrix = 0;

	const float* dev_pressure_level = 0;

	const float* source_doa_hp = 0;
	const float* dev_hammingwin = 0;

	int DD_InputDataFormat;
	int PartitionedSamples;
	int NofFrequencyBins;

	float* RENThist;

	float* c_hist;
	float* c_hist_im;

	int DD_ResultDataFormat;

	float* actual_result;
	float* actual_result_im;

	float* host_source_doa_hp;

	int WindowSize;
	float* kr_matrix;

	float* SRF_real;
	float* SRF_imag;
};

