// MyMonModulesPocsag512.cpp: Implementierung der Klasse CMyMonModulesPocsag512.
//
//////////////////////////////////////////////////////////////////////


#include "MonitorModulePocsag512.h"


#ifdef _DEBUG
#undef THIS_FILE
//static char THIS_FILE[]=__FILE__;
#endif

#define BAUD       512
#define POC512SUBSAMP    1
#define SUBSAMP    1
// war SUBSAMP = 5 
#define FILTLEN    1
//#define GRENZWERT	0.3

//double pocsag_Trigger ;

/* ---------------------------------------------------------------------- */
 

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

MonitorModulePocsag512::MonitorModulePocsag512(XMLNode *pConfig)
{
	int sampleRate=22050 ;
	bool crccheck=getNodeBool(*pConfig,"crc-check",true) ;
	bool errorcorrection=getNodeBool(*pConfig,"ecc",false) ;
	int minpreambel=getNodeInt(*pConfig,"minpreambel",0) ;
	int maxerrors=getNodeInt(*pConfig,"maxerrors",0) ;
	int algorithmus=getNodeInt(*pConfig,"algorithm",0) ;
	MonitorModulePocsag512(	sampleRate,
								crccheck,
								errorcorrection,
								minpreambel,
								maxerrors,
								algorithmus);
	
}

MonitorModulePocsag512::MonitorModulePocsag512(int sampleRate, bool crccheck, bool errorcorrection, int minpreambel, int maxerrors, int algorithmus)
{
	m_bErrorCorrection=errorcorrection ;
	
	MAX_RX_ERRORS=maxerrors ;
	PREAMBEL_MINLEN=minpreambel ;

	m_iAlgorithmus=algorithmus ;
	
	m_PLLFaktor=0.25/100.0 ; // max. Prozent-�nderungen Frq.-�nderung am PLL

	// 0.25
	// 0.2 gut !
	// 0.15 gut !
	// 0.1 auch gut
	// 0.5 war ganz ok
	// 1.5 ging auch gut - asserdem EC f�r SYNC - Wort
	FREQ_SAMP=sampleRate ;

	SPHASEINC=(0x10000u * BAUD * SUBSAMP) / FREQ_SAMP ;
	SPHASEINC_BASE=(0x10000u * BAUD * SUBSAMP) / FREQ_SAMP ;
	m_lpszName="POC 512" ;
	summe=0 ;
	
}

MonitorModulePocsag512::~MonitorModulePocsag512()
{
	
}


void MonitorModulePocsag512::demod_se(float *buffer, int length)
{
	if (subsamp) {
		int numfill = SUBSAMP - subsamp;
		if (length < numfill) {
			subsamp += length;
			return;
		}
		buffer += numfill;
		length -= numfill;
		subsamp = 0;
	}

	int GAP=10 ;
	//pocsag_Trigger=100.0*0.25* (double)maxVal ; // war 0.33
	m_fTrigger=0.25*(float) maxVal  ; // war 0.33


	// vor jedem Lauf auf 50% absenken, damit Lautst�rkeverringerung
	// erkannt werden - Vor allem bei Diskriminatorausg�ngen interessant
	// wo das Rauschen lauter als das Signal ist
	//

	// maxVal=maxVal*0.5 ; 

	for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) {
		dcd_shreg <<= 1;

		// Mit einem Schmitt-Trigger die Flanken ansteilen und Rauschen
		// Eliminieren
		//
		if (lastbit==0)
		{
			if ((*buffer)>m_fTrigger)
			{
				if (length > GAP)
				{
					if (*(buffer+GAP) >m_fTrigger)  // Bleibt das auch in GAP Sampeln ?
					{
						lastbit=1;
					} else {
						// TRACE0("Small GAP!\n") ;
					}
				} else {
					lastbit=1;
				} ;
			} ;
		} else {
			if ( (*buffer) < -m_fTrigger)
			{
				if (length > GAP)
				{
					if (*(buffer+GAP) < -m_fTrigger)
					{
						lastbit=0;
					} else {
						// TRACE0("Small GAP!\n") ;
					} ;
				} else {
					lastbit=0 ;
				} ;
			} ;
		} ;

		dcd_shreg |= (lastbit==1 ? 1 : 0) ;

		if ( (*buffer ) > maxVal) // Neuer Maximalwert ?
		{
			maxVal= (*buffer) ;
		} else { // sonst alten auf 95% absenken, um ggf. Ver�nderungen folgen zu k�nnen
			maxVal *=  0.95 ;
			m_fTrigger=maxVal/3  ;
		} ;


		// Zu sphase: Scheint ja zur Phasensync. zu dienen - findet eine "Transition"
		// statt, so wird sphase entweder um ein achtel der  hochgez�hlt
		// oder verringert
		// 
		//	check if transition
		//
		if ((dcd_shreg ^ (dcd_shreg >> 1)) & 1)
		{
			if (sphase >= 0x8000u)
			{
				float delta=((float) 0x10000u-sphase) / (float) 0x8000u ;

			 	SPHASEINC = (int) (((float) SPHASEINC_BASE) * ( 1.0+(delta * m_PLLFaktor))) ;
			} else {
				float delta=((float) sphase) / (float) 0x8000u ;

				SPHASEINC = (int) ( ( (float) SPHASEINC_BASE) * ( 1.0-(delta * m_PLLFaktor))) ;
			} ;
		} ;

		summe=summe + ( (lastbit==1) ? 1 : -1) ;

		sphase += SPHASEINC ;

		if (sphase>=0x10000u)
		{
			// TRACE1("Adjust to %f\n",  (float)SPHASEINC / (float) SPHASEINC_BASE) ;
			// if (sphase >= 0x10000u) {
			// sphase &= 0xffffu;
			rxbit( summe>0 ? 1 : 0  ) ;
			// rxbit(dcd_shreg & 1);
			summe=0 ;
			sphase &= 0xffffu ;
		}
	}
	subsamp = length;
}



// --------- old function -----------
void MonitorModulePocsag512::demod_mg(float *buffer, int length)
{
	if (subsamp) {
		int numfill = SUBSAMP - subsamp;
		if (length < numfill) {
			subsamp += length;
			return;
		}
		buffer += numfill;
		length -= numfill;
		subsamp = 0;
	}
	for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) {
		dcd_shreg <<= 1;
		dcd_shreg |= ((*buffer) > 0);

		//	check if transition
		if ((dcd_shreg ^ (dcd_shreg >> 1)) & 1) {
			if (sphase < (0x8000u - (SPHASEINC / 2)))
				sphase += SPHASEINC / 8;
			else
				sphase -= SPHASEINC / 8;
		}
		sphase += SPHASEINC;

		if (sphase >= 0x10000u) {
			sphase &= 0xffffu;
			rxbit(dcd_shreg & 1);
		}
	}
	subsamp = length;
}


