📄 tcm_8psk.c
字号:
error = survivor[0].data[indxx % TRUNC_LENGTH]
^ data_symbol[indxx % TRUNC_LENGTH];
error += survivor[0].data2[indxx % TRUNC_LENGTH]
^ data_symbol2[indxx % TRUNC_LENGTH];
if (error)
error_count+=error;
error_coded += (survivor[0].data[indxx % TRUNC_LENGTH]
^ data_symbol[indxx % TRUNC_LENGTH]);
error_uncoded += (survivor[0].data2[indxx % TRUNC_LENGTH]
^ data_symbol2[indxx % TRUNC_LENGTH]);
#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("\nErrors = %ld %ld %ld\n", error_count, error_coded,
error_uncoded);
}
#endif
}
printf("%f %10.4e\n",snr, ((double) error_count/((double) indxx*2.0) ) );
fprintf(fp_ber, "%f %20.15f\n", snr,
((double) error_count / ((double) indxx*2.0) ) );
fflush(stdout);
fflush(fp_ber);
snr += SNR_INC;
}
fclose(fp_ber);
return 0;
}
/****************************************************************************/
int random_data()
{
/* Random two-bit number generator */
return( (random() >> 5) & 3 );
}
/****************************************************************************/
void encoder2()
{
/* Conventional 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 transmit()
{
/* Encode and modulate a 1-bit data sequence */
int i;
encoder2(); /* */
#ifdef DEB
printf("memory2 = %x\n", memory2);
#endif
transmitted = output + 4*data_symbol2[indxx % TRUNC_LENGTH];
}
/****************************************************************************/
void awgn()
{
/* Add AWGN to transmitted sequence */
double u1,u2,s,noise,randmum;
int i;
#ifdef PRINT
printf("Received = ");
#endif
#ifdef NO_NOISE
received_I = psk_I[transmitted];
received_Q = psk_Q[transmitted];
return;
}
#else
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;
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;
received_Q = psk_Q[transmitted] + noise;
#ifdef PRINT
printf("%4.2lf %4.2lf ", received_I, received_Q);
#endif
#ifdef PRINT
printf("\n");
#endif
}
#endif
/****************************************************************************/
void viterbi()
{ /* Viterbi decoding */
double aux_metric, surv_metric[NUM_STATES];
register int i,j,k;
double metrics[4];
int estimated[4];
/* Branch metric computation and uncoded bit */
for (i=0; i<4; i++)
{
metrics[i] = comp_metric(received_I,received_Q,i);
estimated[i] = estimate_data2;
}
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 = comp_metric(received_I,received_Q,trellis[i][j].output);
aux_metric += survivor[i].metric;
**/
aux_metric = survivor[i].metric + metrics[trellis[i][j].output];
#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].data2[k] =
survivor[i].data2[k];
surv_temp[trellis[i][j].final].state[k] =
survivor[i].state[k];
}
#ifdef PRINT
printf("estimate_data2 = %d\n", estimate_data2);
#endif
surv_temp[trellis[i][j].final].data[indxx%TRUNC_LENGTH] = j;
/**
surv_temp[trellis[i][j].final].data2[indxx%TRUNC_LENGTH] = estimate_data2;
**/
surv_temp[trellis[i][j].final].data2[indxx%TRUNC_LENGTH] = estimated[trellis[i][j].output];
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].data2[k] = surv_temp[i].data2[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
}
/****************************************************************************/
double comp_metric(double rec_I, double rec_Q, int ref)
{ /* Gaussian metric between received and reference symbols */
double aux, aux2;
#ifdef ABS
/* Uncoded bit = 0 */
aux = fabs(rec_I-psk_I[ref]) + fabs(rec_Q-psk_Q[ref]);
/* Uncoded bit = 1 */
aux2 = fabs(rec_I-psk_I[ref+4]) + fabs(rec_Q-psk_Q[ref+4]);
#else
/* Uncoded bit = 0 */
aux = ( (rec_I-psk_I[ref])*(rec_I-psk_I[ref])
+ (rec_Q-psk_Q[ref])*(rec_Q-psk_Q[ref]) );
/* Uncoded bit = 1 */
aux2 =( (rec_I-psk_I[ref+4])*(rec_I-psk_I[ref+4])
+ (rec_Q-psk_Q[ref+4])*(rec_Q-psk_Q[ref+4]) );
#endif
if (aux < aux2)
{
estimate_data2 = 0;
return(aux);
}
else
{
estimate_data2 = 1;
return(aux2);
}
}
/****************************************************************************/
double comp_correl(double rec_I, double rec_Q, int ref)
{ /* Gaussian metric between received and reference symbols */
double aux, aux2;
/* Uncoded bit = 0 */
aux = - ( rec_I*psk_I[ref] + rec_Q*psk_Q[ref] );
/* Uncoded bit = 1 */
aux2 = - ( rec_I*psk_I[ref+4] + rec_Q*psk_Q[ref+4] );
if (aux < aux2)
{
estimate_data2 = 0;
return(aux);
}
else
{
estimate_data2 = 1;
return(aux2);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -