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; }