📄 tc-8psk-sect.c
字号:
error += (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\n", error_count);
}
#endif
}
printf("%10.5f %10.4e %10ld %10ld %4ld\n",
snr, ( (double) error_count / ((double) indxx * 2.0) ),
indxx, error_count, NUM_SECT);
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 encoder()
{
/*
* ---------------------------------------------------------------------
* Conventional convolutional encoder, rate 1/n2 (fixed k_2=1)
* ---------------------------------------------------------------------
*/
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 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 re_encode()
{
/* Re-encode decoded information bit to obtain coset index */
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);
#endif
#ifdef PRINT
printf("\n");
#endif
}
void find_sect()
{
/* ---------------------------------------------------------------------
* Determine the sector in which the received point lies
* ---------------------------------------------------------------------
*/
register int i;
double ii, phase1, phase2;
received_angle = atan2(received_Q, received_I);
#ifdef SECTOR
printf("atan2(%lf,%lf)=%lf \t",received_I, received_Q,
(180.0/3.0)*received_angle);
#endif
for (i=0; i<NUM_SECT; i++)
{
ii = (double) i;
phase1 = ii*angle_inc;
if ( phase1 > M_PI )
phase1 = phase1 - 2.0*M_PI;
phase2 = (ii+1.0)*angle_inc;
if ( phase2 > M_PI )
phase2 = phase2 - 2.0*M_PI;
if ( (received_angle > phase1) && (received_angle < phase2) )
sector = i;
}
#ifdef SECTOR
printf("--> \tsector = %d\n", sector);
#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 = branch_metric[sector][trellis[i][j].output];
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 sector_table()
{
/*
* ---------------------------------------------------------------------
* Compute sector metric table:
* branch_metric[sector][index_ref_signal]
* ---------------------------------------------------------------------
*/
register int i,j;
double ii, ref_I[512], ref_Q[512];
double phase, metric1, metric2;
for (i=0; i<NUM_SECT; i++) /* The sector number is i */
{
ii = (double) i;
phase = (ii+1.0)*angle_inc;
phase = (ii)*angle_inc;
ref_I[i] = cos(phase);
ref_Q[i] = sin(phase);
for (j=0; j<4; j++) /* The reference signals are 8-PSK */
{
metric1 = ((ref_I[i]-psk_I[j])*(ref_I[i]-psk_I[j]))
+ ((ref_Q[i]-psk_Q[j])*(ref_Q[i]-psk_Q[j]));
metric2 = ((ref_I[i]-psk_I[j+4])*(ref_I[i]-psk_I[j+4]))
+ ((ref_Q[i]-psk_Q[j+4])*(ref_Q[i]-psk_Q[j+4]));
if (metric1 < metric2)
branch_metric[i][j] = metric1;
else
branch_metric[i][j] = metric2;
}
}
#ifdef PRINT_TABLE
printf("--- metric_table --- \n");
for (i=0; i<NUM_SECT; i++)
{
ii = (double) i;
phase = (ii+1.0)*angle_inc;
printf("%7.2lf | ", (180.0/M_PI)*phase);
for (j=0; j<4;j++) printf("%lf ", branch_metric[i][j]);
printf("\n");
}
printf("\n");
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -