// BKSoundDevice.h: interface for the CBKSoundDevice class.
//


#pragma once

#include "BKSound_Defines.h"

constexpr auto AUTOGAIN_BUFFER_MASK = 0xff;
constexpr auto AUTOGAIN_BUFFER_LEN = (AUTOGAIN_BUFFER_MASK + 1);

//длина ких фильтра. нечётная
constexpr auto FIR_LENGTH = 127;

class CBKSoundDevice
{
		enum FILTER_WINDOW_TYPE
		{
			RECTANGULAR = 0,    // Rectangular window function
			BARTLETT,           // Bartlett (triangular) window
			HANNING,            // Hanning window
			HAMMING,            // Hamming window
			BLACKMAN,           // Blackman window
			BLACKMAN_HARRIS,    // Blackman-Harris window
			BLACKMAN_NUTTAL,    // Blackman-Nuttal window
			NUTTAL              // Nuttal window
		};

	protected:
		enum FILTER_TYPE
		{
			NONE = 0,
			LOWPASS,    //ФНЧ
			HIGHPASS,   //ФВЧ
			BANDSTOP,   //ФПЗ
			BANDPASS    //ФПП
		};
		bool            m_bEnableSound;     //флаг разрешения звука
		bool            m_bFilter;          //флаг включения фильтрации звука
		bool            m_bStereo;

		int             m_nBufferPosL, m_nBufferPosR;
		double          m_dAvgL, m_dAvgR;
		double         *m_pdBufferL;
		double         *m_pdBufferR;

		double          *m_pH;              //коэффициенты КИХ

		double          m_LeftBuf[FIR_LENGTH];  //буферы для фильтра
		double          m_RightBuf[FIR_LENGTH]; //в перспективе - динамические
		int             m_nLeftBufPos;      //позиции в буферах фильтра
		int             m_nRightBufPos;

		//накопители значения сэмпла, значимо только последнее на момент выборки значение
		double          m_dLeftAcc, m_dRightAcc;

		double          AutoGain(register double sample, register double &fAvg, register double *pBuf, register int &nBufPos);
		void            CalcFIR(double *pH, int nN, double dFs1, double dFs2, FILTER_TYPE nFilterType);
		double          getWindow(int i, int n, FILTER_WINDOW_TYPE window);
		double          FIRFilter(register double sample, register double *pBuf, register int &nBufPos);

	public:
		CBKSoundDevice();
		virtual ~CBKSoundDevice();
		virtual void    ReInit();
		virtual void    Reset();

		inline void     EnableSound(bool bEnable)
		{
			m_bEnableSound = bEnable;
		}
		inline bool     IsSoundEnabled()
		{
			return m_bEnableSound;
		}

		inline void     SetFilter(bool bEnable)
		{
			m_bFilter = bEnable;
		}
		inline bool     GetFilter()
		{
			return m_bFilter;
		}
		inline void         SetStereo(bool bEnable)
		{
			m_bStereo = bEnable;
		};
		inline bool         IsStereo()
		{
			return m_bStereo;
		};
		virtual void    SetSample(uint16_t inVal);
		virtual void    GetSample(register SAMPLE_INT &sampleL, register SAMPLE_INT &sampleR);

};
