void CSt4285::tx_psk8( int tribit )
{
	FComplex   symbol;

	tx_frame_state();
		
	symbol.re = cmultReal(symbol_psk8[tribit],scrambler_table[tx_scramble_count]);
	symbol.im = cmultImag(symbol_psk8[tribit],scrambler_table[tx_scramble_count]);

	tx_scramble_count++;
	
	tx_symbol( symbol );
}
void CSt4285::tx_bpsk( int bit )
{
	FComplex   symbol;

	tx_frame_state();
	
	// BPSK because the data is a single bit. But the scrambler_table is an
	// 8-PSK symbol, so the result is also 8-PSK.
	symbol.re = cmultReal(symbol_psk2[bit],scrambler_table[tx_scramble_count]);
	symbol.im = cmultImag(symbol_psk2[bit],scrambler_table[tx_scramble_count]);

	tx_scramble_count++;
	
	tx_symbol( symbol );
}
FDemodulate CSt4285::demodulate_bpsk( FComplex symbol )
{
	FDemodulate symd;
	FComplex    sym;

	sym.re = cmultRealConj(symbol,scrambler_table[rx_scramble_count]);
	sym.im  = cmultImagConj(symbol,scrambler_table[rx_scramble_count]);

	save_constellation_symbol( sym );

	if( sym.re > 0.0 )
	{
		symd.data           = 0;
		/* Soft decision information */
		sd[soft_index++]    =  sym.re*get_mse_divisor();
		symd.dx_symbol.re = (float)0.01;		
		symd.dx_symbol.im = (float)0.0;		
	}
	else
	{
		symd.data           =  1;
		/* Soft decision information */
		sd[soft_index++]    =  sym.re*get_mse_divisor();
		symd.dx_symbol.re = -(float)0.01;		
		symd.dx_symbol.im =  (float)0.0;		
	}

	sym.re = cmultReal(symd.dx_symbol,scrambler_table[rx_scramble_count]);
	sym.im = cmultImag(symd.dx_symbol,scrambler_table[rx_scramble_count]);

	symd.dx_symbol = sym;

	/* Calculate the error */
	symd.error.re = sym.re - symbol.re;  
	symd.error.im = sym.im - symbol.im;  

	update_mse_average( symd.error );

	/* Save the actual symbol */
	symd.rx_symbol = symbol;

	return symd;	
}
FDemodulate CSt4285::demodulate_qpsk( FComplex symbol )
{
	FDemodulate symd;
	FComplex    sym;
	float       rabs,iabs;
	float       soft;
	
	sym.re  = cmultRealConj(symbol,scrambler_table[rx_scramble_count]);
	sym.im  = cmultImagConj(symbol,scrambler_table[rx_scramble_count]);

	save_constellation_symbol( sym );

	rabs = (float)fabs( sym.re );
	iabs = (float)fabs( sym.im );
	
	
	if( rabs > iabs )
	{
		/* Real component greater */
		soft =  (rabs - iabs) * get_mse_divisor();
		if( sym.re >= 0.0 )
		{
			symd.data           = 0;
		    sd[soft_index++]    = soft;
		    sd[soft_index++]    = soft;
			symd.dx_symbol.re = (float)0.01;		
			symd.dx_symbol.im = (float)0.00;		
		}
		else
		{
			symd.data           =  3;
		    sd[soft_index++]    = -soft;
		    sd[soft_index++]    = -soft;
			symd.dx_symbol.re = -(float)0.01;		
			symd.dx_symbol.im =  (float)0.00;		
		}
	}
	else
	{
		/* Imaginary component greater */

		soft =  (iabs - rabs) * get_mse_divisor();

		if( sym.im >= 0.0 )
		{
			symd.data           =  1;
		    sd[soft_index++]    =  soft;
		    sd[soft_index++]    = -soft;
			symd.dx_symbol.re =  (float)0.00;		
			symd.dx_symbol.im =  (float)0.01;		
		}
		else
		{
			symd.data           =  2;
		    sd[soft_index++]    = -soft;
		    sd[soft_index++]    =  soft;
			symd.dx_symbol.re =  (float)0.00;		
			symd.dx_symbol.im = -(float)0.01;		
		}
	} 
	/* Calculate the perfect symbol */

	sym.re = cmultReal(symd.dx_symbol,scrambler_table[rx_scramble_count]);
	sym.im = cmultImag(symd.dx_symbol,scrambler_table[rx_scramble_count]);

	symd.dx_symbol =  sym;

	/* Calculate the error */
	symd.error.re = sym.re - symbol.re;  
	symd.error.im = sym.im - symbol.im;  

	update_mse_average( symd.error );

	/* Save the actual symbol */
	symd.rx_symbol = symbol;

	return symd;	
}
FDemodulate CSt4285::demodulate_8psk( FComplex symbol )
{
	FDemodulate symd;
	float       val;
	float       rabs,iabs;
	float       soft;
	int         angle;
	FComplex    sym;


	sym.re  = cmultRealConj(symbol,scrambler_table[rx_scramble_count]);
	sym.im  = cmultImagConj(symbol,scrambler_table[rx_scramble_count]);

	save_constellation_symbol( sym );
	
	rabs = (float)fabs(sym.re);
	iabs = (float)fabs(sym.im);

	val = iabs/rabs;
	
	if( val <= 0.41421356237 ) /* 22.5 deg */
	{
		soft  = (float)0.38268343237*rabs - (float)0.92387953251*iabs; /* Metric */		
		angle = 0;	
	}
	else
	{
		if( val <=1 ) /* 45 deg */
		{
				soft  = (float)0.92387953251*iabs - (float)0.38268343237*rabs; /* Metric */		
				angle = 45;		
		}
		else
		{
			if( val <= 2.4142135624 ) /* 67.5 deg */
			{
				soft  =  (float)(0.92387953251*rabs - 0.38268343237*iabs); /* Metric */		
				angle = 45;	
			}
			else
			{
				soft  = (float)(0.38268343237*iabs - 0.92387953251*rabs); /* Metric */		
				angle = 90;	
			}
		}
	}
	soft = soft*get_mse_divisor();		
	
	/* Find region */

	if( sym.re >= 0.0 )
	{
		if( sym.im < 0.0 )
		{
			angle = 360 - angle;
		}
	}
	else
	{
		if( sym.im >= 0.0 )
		{
			angle = 180 - angle;
		}
		else
		{
			angle = 180 + angle;
		}
	}
	
	switch( angle )
	{
		case 0:
		case 360:
			symd.data           =  1;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re =  (float)0.01000000;
			symd.dx_symbol.im =  (float)0.00000000;
			break;
		case 45:
			symd.data           =  0;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re =  (float)0.00707107;
			symd.dx_symbol.im =  (float)0.00707107;
			break;
		case 90:
			symd.data           =  2;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re =  (float)0.00000000;
			symd.dx_symbol.im =  (float)0.01000000;
			break;
		case 135:
			symd.data           =  3;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re = -(float)0.00707107;
			symd.dx_symbol.im =  (float)0.00707107;
			break;
		case 180:
			symd.data           =  7; 
			sd[soft_index++]    = -soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re = -(float)0.01000000;
			symd.dx_symbol.im =  (float)0.00000000;
			break;
		case 225:
			symd.data           =  6;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re = -(float)0.00707107;
			symd.dx_symbol.im = -(float)0.00707107;
			break;
		case 270:
			symd.data		    =  4;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re =  (float)0.00000000;
			symd.dx_symbol.im = -(float)0.01000000;
			break;
		case 315:
			symd.data      		=  5;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  soft;
			sd[soft_index++]    = -soft;
			sd[soft_index++]    =  0;
			symd.dx_symbol.re =  (float)0.00707107;
			symd.dx_symbol.im = -(float)0.00707107;
			break;
		default:
			break;
	}

	sym.re = cmultReal(symd.dx_symbol,scrambler_table[rx_scramble_count]);
	sym.im = cmultImag(symd.dx_symbol,scrambler_table[rx_scramble_count]);

	symd.dx_symbol = sym;

	/* Calculate the error */
	symd.error.re = sym.re - symbol.re;  
	symd.error.im = sym.im - symbol.im;  

	update_mse_average( symd.error );

	/* Save the actual symbol */
	symd.rx_symbol = symbol;

	return symd;	
}