📄 tc-8psk-iq.c
字号:
printf("\n");
printf("coset = %d, estimate_data2 = %d\toriginal data2 = %d\n",
reconstructed, estimate_data2, data_symbol2[indxx % TRUNC_LENGTH]);
#endif
/* COMPUTE ERRORS */
error = (survivor[0].data[indxx % TRUNC_LENGTH]
^ data_symbol[indxx % TRUNC_LENGTH]) & 0x01;
error_count_1 += error;
error += (estimate_data2 ^ data_symbol2[indxx % TRUNC_LENGTH]);
error_count_2 += (estimate_data2 ^ data_symbol2[indxx % TRUNC_LENGTH]);
if (error)
error_count+=error;
#ifdef SHOW_PROGRESS
if ( (indxx % DELTA) == 0 )
{
printf("index = %ld\n", indxx);
for (i=0; i<TRUNC_LENGTH; i++)
printf("%x", survivor[0].data[i]);
printf("\n--- errors = %ld %ld %ld\n", error_count,
error_count_1, error_count_2);
}
#endif
}
/* PRINT SIMULATION RESULTS */
printf("%10.5f %10.4e %10ld %10ld %10ld %10ld\n",
snr, ( (double) error_count / ((double) indxx * 2.0) ),
indxx, error_count, error_count_1, error_count_2);
fprintf(fp_ber, "%f %20.15f %20.15f %20.15f\n", snr,
( (double) error_count / ((double) indxx * 2.0) ),
( (double) error_count_1 / ((double) indxx) ),
( (double) error_count_2 / ((double) indxx) ));
fflush(stdout);
fflush(fp_ber);
snr += SNR_INC;
}
fclose(fp_ber);
return 0;
}
void build_sector_table()
{
/*
* ---------------------------------------------------------------------
* Look-up table for decoding BIT 2
* ---------------------------------------------------------------------
*/
/* Sector */
/* ------------------------- */
/* COSET 7 6 5 4 3 2 1 0 */
/* ------------------------- */
s[0] = 0x78; /* 00 0 1 1 1 1 0 0 0 */
s[1] = 0xf0; /* 01 1 1 1 1 0 0 0 0 */
s[3] = 0xe1; /* 11 1 1 1 0 0 0 0 1 */
s[2] = 0xc3; /* 10 1 1 0 0 0 0 1 1 */
}
int random_data()
{
/*
* ---------------------------------------------------------------------
* Two-bit random number generator
* ---------------------------------------------------------------------
*/
return( (random() >> 5) & 0x03 );
}
void encoder2()
{
/*
* ---------------------------------------------------------------------
* Convolutional encoder, rate 1/n2 (fixed k_2=1)
* ---------------------------------------------------------------------
*/
register int i, j, result, temp;
temp = memory2;
output = 0;
temp = (temp<<1) ^ data_symbol[indxx % TRUNC_LENGTH];
for (i=0; i<n2; i++)
{
result = 0;
for (j=m2; j>=0; j--)
result ^= ( ( temp & g2[i][0] ) >> j ) & 1;
output = ( output<<1 ) ^ result;
}
memory2 = temp ;
}
void encoder()
{
/*
* ---------------------------------------------------------------------
* Convolutional encoder, rate 1/n2 (fixed k_2=1)
* NOTE: Used in re-encoding coset indexes
* ---------------------------------------------------------------------
*/
register int i, j, result, temp;
temp = memory;
output2 = 0;
temp = (temp<<1) ^ survivor[0].data[indxx % TRUNC_LENGTH];
for (i=0; i<n2; i++)
{
result = 0;
for (j=m2; j>=0; j--)
result ^= ( ( temp & g2[i][0] ) >> j ) & 1;
output2 = ( output2<<1 ) ^ result;
}
memory = temp ;
}
void transmit()
{
/*
* ---------------------------------------------------------------------
* Encode and modulate 2-bit data sequence
* ---------------------------------------------------------------------
*/
int i;
/* Encode BIT 1 */
encoder2();
/* Transmitted is an index. BIT 2 determines opposite 8-PSK symbols */
transmitted = output + 4*data_symbol2[indxx % TRUNC_LENGTH];
}
void re_encode()
{
/*
* ----------------------------------------------------------------------
* Re-encode information bit (BIT 1) from Viterbi decoder to obtain coset
* ----------------------------------------------------------------------
*/
encoder();
reconstructed = output2;
}
void awgn()
{
/*
* ---------------------------------------------------------------------
* Add AWGN to transmitted sequence
* ---------------------------------------------------------------------
*/
double u1,u2,s,noise,randmum;
int i;
#ifdef PRINT
printf("Received = ");
#endif
do
{
randmum = (double)(random())/MAX_RANDOM;
u1 = randmum*2.0 - 1.0;
randmum = (double)(random())/MAX_RANDOM;
u2 = randmum*2.0 - 1.0;
s = u1*u1 + u2*u2;
} while( s >= 1);
noise = u1 * sqrt( (-2.0*log(s))/s ) / amp; /* */
#ifdef NO_NOISE
noise = 0.0;
#endif
received_I = psk_I[transmitted] + noise;
do
{
randmum = (double)(random())/MAX_RANDOM;
u1 = randmum*2.0 - 1.0;
randmum = (double)(random())/MAX_RANDOM;
u2 = randmum*2.0 - 1.0;
s = u1*u1 + u2*u2;
} while( s >= 1);
noise = u1 * sqrt( (-2.0*log(s))/s ) / amp; /* */
#ifdef NO_NOISE
noise = 0.0;
#endif
received_Q = psk_Q[transmitted] + noise;
#ifdef PRINT
printf("%4.2lf %4.2lf ", received_I, received_Q);
printf("\n");
#endif
}
void viterbi()
{
/*
* ---------------------------------------------------------------------
* Viterbi decoder
* ---------------------------------------------------------------------
*/
double aux_metric, surv_metric[NUM_STATES];
register int i,j,k;
for (i=0; i<NUM_STATES; i++) /* Initialize survivor branch metric */
surv_metric[i] = DBL_MAX;
for (i=0; i<NUM_STATES; i++) /* Loop over inital states */
{
for (j=0; j<NUM_TRANS; j++) /* Loop over data */
{
/* Compute metric between received and coded symbols */
aux_metric = ( (qpsk_I[trellis[i][j].output]-transf_I)
* (qpsk_I[trellis[i][j].output]-transf_I) )
+
( (qpsk_Q[trellis[i][j].output]-transf_Q)
* (qpsk_Q[trellis[i][j].output]-transf_Q) );
aux_metric += survivor[i].metric;
#ifdef PRINT
printf("rec_I rec_Q index_coded\n");
printf("%6.2lf %6.2lf %d\n", received_I,received_Q,trellis[i][j].output);
printf("init, data, final, metric = %2d %2d %2d %lf\n", i, j,
trellis[i][j].final, aux_metric);
#endif
/* compare with survivor metric at final state */
if ( aux_metric < surv_metric[trellis[i][j].final] )
{ /* Good candidate found */
surv_metric[trellis[i][j].final] = aux_metric;
/* Update data and state paths */
for (k=0; k<TRUNC_LENGTH; k++)
{
surv_temp[trellis[i][j].final].data[k] =
survivor[i].data[k];
surv_temp[trellis[i][j].final].state[k] =
survivor[i].state[k];
}
surv_temp[trellis[i][j].final].data[indxx%TRUNC_LENGTH] = j;
surv_temp[trellis[i][j].final].state[indxx%TRUNC_LENGTH] =
trellis[i][j].final;
}
}
}
for (i=0; i<NUM_STATES; i++)
{
/* Update survivor metrics */
survivor[i].metric = surv_metric[i];
for (k=0; k<TRUNC_LENGTH; k++)
{
survivor[i].data[k] = surv_temp[i].data[k];
survivor[i].state[k] = surv_temp[i].state[k];
}
}
#ifdef PRINT
for (i=0; i<NUM_STATES; i++)
{
printf("survivor %2d, initial state = %2d metric = %10.5lf, ", i,
survivor[i].state[(indxx-1) % TRUNC_LENGTH], survivor[i].metric);
printf("\t estimate = %d\n", survivor[i].data[indxx % TRUNC_LENGTH]);
}
printf("\n");
#endif
#ifdef DEBUG
printf("Surviving paths (data):\n");
for (i=0; i<NUM_STATES; i++)
{
printf("%2d --> ",i);
for (k=0; k<TRUNC_LENGTH; k++)
printf("%1x", survivor[i].data[k]);
printf("\n");
}
printf("\n");
#endif
}
void find_sect()
{
/* ---------------------------------------------------------------------
* Determine the sector in which the received point lies
* ---------------------------------------------------------------------
*/
register int i, flag;
double ii, received_angle, phase1, phase2;
flag = 0;
received_angle = atan2(received_Q, received_I);
if (received_angle < 0.0)
received_angle += (2.0*M_PI);
if ( ( received_angle > 2.0*M_PI-M_PI/8 ) || (received_angle < M_PI/8.0) )
sector = 0;
else
for (i=1; ( (i<8) && (!flag)); i++)
{
ii = (double) i;
phase1 = (ii*M_PI/4.0) - (M_PI/8.0);
phase2 = (ii*M_PI/4.0) + (M_PI/8.0);
#ifdef DEBUG
printf("phase1, phase2 = %lf %lf\n", (180./M_PI)*phase1,(180./M_PI)*phase2);
#endif
if ( (received_angle > phase1) && (received_angle <= phase2) )
{
flag = 1;
sector = i;
}
}
#ifdef SECTOR
printf("---\nrec_I, rec_Q = %lf, %lf\nangle = %lf, sector = %d\n",
received_I, received_Q, (180./M_PI)*received_angle, sector);
#endif
}
void transform()
{
double amplitude, phase;
amplitude = sqrt (received_I*received_I + received_Q*received_Q);
phase = 2.0*atan(received_Q/received_I);
transf_I = amplitude * cos(phase);
transf_Q = amplitude * sin(phase);
#ifdef IQ
printf("rec_I, rec_Q = (%lf, %lf) \ntransf_I, transf_Q = (%lf, %lf)\n",
received_I,received_Q,transf_I,transf_Q);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -