#ifndef PDM_MICS_H_
#define PDM_MICS_H_

#include "udi_audio_conf.h"


#define PDM_OVERSAMPLING_RATIO		(64UL)
#define PDM_CLK_FREQ				(UDI_AUDIO_FREQ*PDM_OVERSAMPLING_RATIO)
#define PDM_GAIN					(2UL)
#define PDM_FRACTIONAL_GAIN			(0x5FFF) // Value of ~0.75. Final gain is then 2*0.75 = 1.5

typedef struct  
{
	uint8_t initialized;
	uint16_t buffer_length;
	int16_t* left_buffer;
	int16_t* right_buffer;
} PDM_Mic_T;

#define PDM_MIC_T_DEFAULT		{0,0,0,0}
	
/*
 * Size of each PCM sample.
 * 3 MHz PDM clock, decimation of 64 -> Sampling rate 48kHz
 * 960 samples gives us 20 milliseconds of data.
 */
#define NB_SAMPLES_1MS	(UDI_AUDIO_FREQ / 1000UL)
#define BUF_LENGTH_MS	5
#define PCM_BUF_SIZE	NB_SAMPLES_1MS * BUF_LENGTH_MS

typedef enum {
	MIX_STATE_STEREO,
	MIX_STATE_ADD
} Mixing_State_T;

// Initialize the PDM peripheral
void init_pdm(void);
void disable_pdm(void);
// Set data buffers to transfer converted microphone samples into
void set_pdm_buffers(int16_t* leftbuf, int16_t* rightbuf, uint16_t buflen);
// Start transferring data from PDM microphones into data buffers
void start_pdm_transfer(void);
// Stop the transfer of data
void stop_pdm_transfer(void);
// Get the current position of the PDM buffer (next spot to be written to)
uint16_t get_pdm_buffer_position(void);
// Set the value of PDM mic gain (1 to 32767).
void set_pdm_gain(uint16_t newgain);
// Set the fractional gain - done in fixed point math
void set_pdm_fractional_gain(int16_t newgain);

void pdmmic_set_mixstate(Mixing_State_T mix);
Mixing_State_T pdmmic_get_mixstate(void);
int16_t* pdmmic_get_audio_left_buffer(void);
int16_t* pdmmic_get_audio_right_buffer(void);
void pdmmic_audio_enable(void);
void pdmmic_audio_disable(void);

void task_usbload(void *pvParameters);

#endif /* PDM_MICS_H_ */
