📄 turbo_code_log_map.c
字号:
*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*i));
}
/* decoder two: */
/* get extrinsic information from decoder one */
interleave_float(Le_turbo, La_turbo, TYPE_INTERLEAVER, length_info, 0);
for (i=length_info; i<length_total; i++)
{
*(La_turbo+i) = 0;
}
switch(TYPE_DECODER)
{
case 1:
Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
break;
case 2:
MAX_Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
break;
default:
break;
}
/* caculate the extrinsic information */
for(i=0; i<length_total; i++)
{
*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*length_total+2*i));
}
/* end of decoder two */
}
/* get the decision bits from LLR gained from these decoder */
decision(LLR_all_turbo, length_total, tempout);
de_interleave_int(supflow_decoded, tempout, TYPE_INTERLEAVER, length_info, 0);
*supflow_length = length_info;
free(receive_punc);
free(yk_turbo);
free(La_turbo);
free(Le_turbo);
free(LLR_all_turbo);
free(tempout);
}
/*---------------------------------------------------------------
FUNCTION:
TurboCodingInit(int *traffic_source_length)
DESCRIPTION:
Initialize the parameters of coding.
PARAMETERS:
INPUT:
traffic_source_length - The pointer that give out the length of the source bits.
RETURN VALUE:
None.
---------------------------------------------------------------*/
void TurboCodingInit()
{
turbo_g.N_num_row = 2; /* initialize number of rows and columns of g */
turbo_g.K_num_col = COLUMN_OF_G;
/* caculate the coding rate */
rate_coding = TURBO_PUNCTURE? (float)(0.5) : (float)(0.333333);
if ((turbo_g.g_matrix=(int *)malloc(turbo_g.N_num_row*turbo_g.K_num_col*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of turbo_g\n");
exit(1);
}
/* generate the code generator matrix */
if (!gen_g_matrix(turbo_g.K_num_col, G_ROW_1, G_ROW_2, turbo_g.g_matrix))
{
printf("error number of G\n");
exit(1);
}
/* generate puncture matrix */
if (TURBO_PUNCTURE)
{
if ((mx_puncture_turbo_80=(int *)malloc(sizeof(int)*3*80))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_80\n");
exit(1);
}
if ((mx_puncture_turbo_160=(int *)malloc(sizeof(int)*3*160))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_160\n");
exit(1);
}
if ((mx_puncture_turbo_320=(int *)malloc(sizeof(int)*3*320))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_320\n");
exit(1);
}
if (!gen_mx_punc()) /* generate the matrix for puncture */
{
printf("\nError! Can not generate the puncture matrix properly!\n");
exit(1);
}
}
/* initialize the trellis struct */
if ((turbo_trellis.mx_lastout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_lastout \n");
exit(1);
}
if ((turbo_trellis.mx_laststat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_laststat \n");
exit(1);
}
if ((turbo_trellis.mx_nextout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_nextout \n");
exit(1);
}
if ((turbo_trellis.mx_nextstat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_nextstat \n");
exit(1);
}
gen_trellis();
/* malloc memory for the index of random interleaver */
if (TYPE_INTERLEAVER==2)
{
if ((index_randomintlvr=(int *)malloc(MAX_FRAME_LENGTH*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of index_randomintlvr \n");
exit(1);
}
if ((index_randomintlvr_sup=(int *)malloc(SUP_FRAME_LENGTH*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of index_randomintlvr_sup \n");
exit(1);
}
}
}
/*---------------------------------------------------------------
FUNCTION:
TurboCodingFinish()
DESCRIPTION:
Free the memory of turbo coding.
PARAMETERS:
None.
RETURN VALUE:
None.
---------------------------------------------------------------*/
void TurboCodingRelease()
{
free(turbo_g.g_matrix);
if (TURBO_PUNCTURE)
{
free(mx_puncture_turbo_80);
free(mx_puncture_turbo_160);
free(mx_puncture_turbo_320);
}
free(turbo_trellis.mx_lastout);
free(turbo_trellis.mx_laststat);
free(turbo_trellis.mx_nextout);
free(turbo_trellis.mx_nextstat);
if (TYPE_INTERLEAVER==2)
{
free(index_randomintlvr);
free(index_randomintlvr_sup);
}
}
/*---------------------------------------------------------------
FUNCTION:
int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
DESCRIPTION:
This function generate the code generater g for the random interleaver.
PARAMETERS:
INPUT:
k - Number of columns of g matrix.
g_row1 - An octal number indicate the first row of turbo_g.
g_row2 - An octal number indicate the second row of turbo_g.
OUTPUT:
mx_g - Contains pointer to g matrix.
RETURN VALUE:
1 - If the matrix was successfully generated.
0 - Error occurred generating the g matrix.
---------------------------------------------------------------*/
int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
{
int i, position;
int high_num, low_num;
/* for the first row */
high_num = g_row1;
position = 1;
while (high_num>0)
{
low_num = high_num%10;
if (low_num>7)
{
return 0;
}
high_num = high_num/10;
for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
{
*(mx_g_turbo+i) = low_num%2;
low_num = low_num/2;
}
position++;
if (i<0)
{
break;
}
}
/*for the second row */
high_num = g_row2;
position = 1;
while (high_num>0)
{
low_num = high_num%10;
if (low_num>7)
{
return 0;
}
high_num = high_num/10;
for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
{
*(mx_g_turbo+k_column+i) = low_num%2;
low_num = low_num/2;
}
position++;
if (i<0)
{
break;
}
}
return 1;
}
/*---------------------------------------------------------------
FUNCTION:
void gen_trellis()
DESCRIPTION:
This function generate the turbo_trellis structure.
PARAMETERS:
None
RETURN VALUE:
None
---------------------------------------------------------------*/
void gen_trellis()
{
int i, j, k;
int dk_turbo, ak_turbo, outbit;
int *tempstat;
if ((tempstat=(int *)malloc(sizeof(int)*M_num_reg))==NULL)
{
printf("\n fail to allocate memory of tempstat \n");
exit(1);
}
/* generate next output and next state matrix */
for (i=0; i<n_states; i++)
{
for (j=0; j<2; j++)
{
int2bin(i, tempstat, M_num_reg);
dk_turbo = j;
ak_turbo = (*(turbo_g.g_matrix+0)) * dk_turbo;
for (k=1; k<turbo_g.K_num_col; k++)
{
ak_turbo = ak_turbo + (*(turbo_g.g_matrix+k)) * (*(tempstat+k-1));
}
ak_turbo = ak_turbo % 2;
outbit = encode_bit(ak_turbo, tempstat);
*(turbo_trellis.mx_nextout+i*4+2*j)=2*dk_turbo-1;
*(turbo_trellis.mx_nextout+i*4+2*j+1)=2*outbit-1;
*(turbo_trellis.mx_nextstat+i*2+j)=bin2int(tempstat, M_num_reg);
}
}
/* generate last output and last state matrix */
for (i=0; i<n_states; i++)
{
for (j=0; j<2; j++)
{
*(turbo_trellis.mx_laststat+(*(turbo_trellis.mx_nextstat+i*2+j))*2+j) = i;
*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j)
= *(turbo_trellis.mx_nextout+i*4+2*j);
*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j+1)
= *(turbo_trellis.mx_nextout+i*4+2*j+1);
}
}
free(tempstat);
}
/*---------------------------------------------------------------
FUNCTION:
void int2bin(int intstat, int *tempstat, int length)
DESCRIPTION:
This function turn a decimal integer to a binary sequence.
PARAMETERS:
INPUT:
intstat - Decimal integer needed to be changed.
length - Length of binary sequence.
OUTPUT:
tempstat - Contains pointer to the binary sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void int2bin(int intstat, int *tempstat, int length)
{
int i, temp;
temp = intstat;
for (i=length-1; i>=0; i--)
{
*(tempstat+i) = temp%2;
temp = temp/2;
}
}
/*---------------------------------------------------------------
FUNCTION:
int bin2int(int *binseq, int length)
DESCRIPTION:
This function turn a binary sequence to a decimal integer.
PARAMETERS:
INPUT:
binseq - Contains pointer to the binary sequence.
length - Length of binary sequence.
RETURN VALUE:
The decimal integer corresponding to the binary sequence.
---------------------------------------------------------------*/
int bin2int(int *binseq, int length)
{
int i, j, temp;
int sum = 0;
for (i=0; i<length; i++)
{
temp = 1;
for (j=1; j<=i; j++)
{
temp = temp * 2;
}
sum = sum + temp * (*(binseq+length-1-i));
}
return sum;
}
/*---------------------------------------------------------------
FUNCTION:
random_turbo()
DESCRIPTION:
Generate a random number between 0 and 1.
RETURN VALUE:
The random number between 0 and 1.
---------------------------------------------------------------*/
float random_turbo()
{
long z,k;
static long s1 = 12345L;
static long s2 = 1234546346L;
k= s1 / 53668L;
s1 = 40014L * (s1 - k*53668L) - k*12211L;
if (s1<0)
s1 = s1 + 2147483563L;
k = s2 / 52774;
s2 = 40692L * (s2 - k*52774L) - k*3791L;
if (s2<0)
s2 = s2 + 2147483399L;
z=s1 - s2;
if (z<1)
z = z + 2147483562L;
return (float) z / (float) 2147483563.0;
}
/*---------------------------------------------------------------
FUNCTION:
void gen_rand_index(int length)
DESCRIPTION:
This function generate the index for the random interleaver.
PARAMETERS:
INPUT:
length - Length of interleaver.
type_flow - 1 for traffic flow, 0 for suplement flow.
RETURN VALUE:
None
---------------------------------------------------------------*/
void gen_rand_index(int length, int type_flow)
{
int *index_random;
float *tempindex;
float tempmax;
int selectedscr;
int i, j;
if ((tempindex=(float *)malloc((length)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of tempindex \n");
exit(1);
}
index_random = type_flow? index_randomintlvr : index_randomintlvr_sup;
for (i=0; i<length; i++)
{
*(tempindex+i) = random_turbo();
}
for (i=0; i<length; i++)
{
tempmax = 0.0;
for (j=0; j<length; j++)
{
if (*(tempindex+j) >= tempmax)
{
tempmax = *(tempindex+j);
selectedscr = j;
}
}
*(index_random+i) = selectedscr;
*(tempindex+selectedscr) = 0.0;
}
free(tempindex);
}
/*---------------------------------------------------------------
FUNCTION:
void randominterleaver_int(int *data_unintlvr, int *interleaverddata,
int length, int type_flow)
DESCRIPTION:
Random interleaver of int.
PARAMETERS:
INPUT:
data_unintlvr - Contains pointer to data_unintlvr before interleavered.
length - Length of interleaver.
type_flow - 1 for traffic flow, 0 for suplement flow.
OUTPUT:
interleaverddata - Contains pointer to interleavered data_unintlvr.
RETURN VALUE:
None
---------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -