📄 turbo_code_log_map.c
字号:
PARAMETERS:
INPUT:
source - Contains pointer to source bits.
len_info - Length of the input information bits.
type_flow - 1 for traffic flow, 0 for suplement flow.
OUTPUT:
send_turbo - Contains pointer to the sequence after encoding and modulation.
RETURN VALUE:
None
---------------------------------------------------------------*/
void encoderm_turbo(int *source, int *send_turbo, int len_info, int type_flow)
{
int i;
int len_total = len_info + M_num_reg;
int *rsc1, *rsc2;
int *input2;
if ((rsc1=(int *)malloc(2*len_total*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of rsc1 \n");
exit(1);
}
if ((rsc2=(int *)malloc(2*len_total*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of rsc2 \n");
exit(1);
}
if ((input2=(int *)malloc(len_info*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of input2 \n");
exit(1);
}
/* the first RSC encoder */
rsc_encode(source, rsc1, 1, len_info);
interleave_int(source, input2, TYPE_INTERLEAVER, len_info, type_flow);
/* the second RSC encoder */
rsc_encode(input2, rsc2, 1, len_info);
for (i=0; i<len_info; i++)
{
*(send_turbo+3*i) = *(rsc1+2*i) *2 - 1;
*(send_turbo+3*i+1) = *(rsc1+2*i+1) *2 - 1;
*(send_turbo+3*i+2) = *(rsc2+2*i+1) *2 - 1;
}
for (i=0; i<2*M_num_reg; i++)
{
*(send_turbo+3*len_info+i) = *(rsc1+2*len_info+i) *2 - 1;
*(send_turbo+3*len_info+2*M_num_reg+i) = *(rsc2+2*len_info+i) *2 - 1;
}
free(rsc1);
free(rsc2);
free(input2);
}
/*---------------------------------------------------------------
FUNCTION:
void rsc_encode(int *source, int *rsc, int terminated, int len_info)
DESCRIPTION:
Encodes a block of data to a recursive systematic convolutional code.
PARAMETERS:
INPUT:
source - Contains pointer to the input data sequence.
terminated - Indicate the encoder terminates the turbo_trellis or not.
1 - terminated
0 - not terminated
len_info - Length of the input data sequencd.
OUTPUT:
rsc - Contains pointer to the output data sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void rsc_encode(int *source, int *rsc, int terminated, int len_info)
{
int i, j;
int *state;
int dk_turbo, ak_turbo, outbit;
int len_total;
if ((state=(int *)malloc(M_num_reg*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of state \n");
exit(1);
}
len_total = len_info+M_num_reg;
for (i=0; i<M_num_reg; i++)
{
*(state+i) = 0;
}
for (i=0; i<len_total; i++) /* encoding bit by bit */
{
if (!terminated || (terminated && i<len_info)) /* for information bits */
{
dk_turbo = *(source+i);
}
else /* terminate the trellis */
{
if (terminated && i>=len_info)
{
dk_turbo = 0;
for (j=1; j<turbo_g.K_num_col; j++)
{
dk_turbo = dk_turbo + (*(turbo_g.g_matrix+j)) * (*(state+j-1));
}
dk_turbo = dk_turbo%2;
}
}
ak_turbo = *(turbo_g.g_matrix+0) * dk_turbo;
for (j=1; j<turbo_g.K_num_col; j++)
{
ak_turbo = ak_turbo + (*(turbo_g.g_matrix+j))*(*(state+j-1));
}
ak_turbo = ak_turbo%2;
outbit = encode_bit(ak_turbo, state);
*(rsc+2*i) = dk_turbo;
*(rsc+2*i+1) = outbit;
} /* end of encoding bit by bit */
free(state);
}
/*---------------------------------------------------------------
FUNCTION:
int encode_bit(int inbit, int *stat)
DESCRIPTION:
This function can get a coded bit from the memory state and the input bit.
The memory state is accordingly modified.
PARAMETERS:
INPUT:
inbit - The input bit.
OUTPUT & INPUT:
stat - Contains pointer to memory state.
RETURN VALUE:
The coded bit.
---------------------------------------------------------------*/
int encode_bit(int inbit, int *stat)
{
int j;
int output;
output = (*(turbo_g.g_matrix+turbo_g.K_num_col+0)) * inbit;
for (j=1; j<turbo_g.K_num_col; j++)
{
output = (output + (*(turbo_g.g_matrix+turbo_g.K_num_col+j)) * (*(stat+j-1)))%2;
}
for (j=turbo_g.K_num_col-2; j>0; j--)
{
*(stat+j)=*(stat+j-1);
}
*(stat+0) = inbit;
return output;
}
/*---------------------------------------------------------------
FUNCTION:
bool gen_mx_punc()
DESCRIPTION:
This function generate the puncture matrix.
PARAMETERS:
RETURN VALUE:
1 - If the matrix was successfully generated.
0 - Error occurred generating the puncture matrix.
---------------------------------------------------------------*/
int gen_mx_punc()
{
int i;
int type_punc;
int *mx_puncture_turbo;
for (type_punc=1; type_punc<5; type_punc++)
{
switch (type_punc)
{
case 1:
mx_puncture_turbo = mx_puncture_turbo_80;
break;
case 2:
mx_puncture_turbo = mx_puncture_turbo_160;
break;
case 4:
mx_puncture_turbo = mx_puncture_turbo_320;
break;
default:
break;
}
if (type_punc==3)
{
continue;
}
for (i=0; i<type_punc*80; i++)
{
*(mx_puncture_turbo+i) = 1;
}
for (i=0; i<type_punc*80; i++)
{
if(i%2)
{
*(mx_puncture_turbo+type_punc*80+i) = 0;
}
else
{
*(mx_puncture_turbo+type_punc*80+i) = 1;
}
}
for (i=0; i<type_punc*80; i++)
{
if(i%2)
{
*(mx_puncture_turbo+type_punc*80*2+i) = 1;
}
else
{
*(mx_puncture_turbo+type_punc*80*2+i) = 0;
}
}
switch (type_punc)
{
case 1:
{
*(mx_puncture_turbo+type_punc*80*2+20) = 0;
*(mx_puncture_turbo+type_punc*80+20) = 0;
*(mx_puncture_turbo+type_punc*80*2+41) = 0;
*(mx_puncture_turbo+type_punc*80+41) = 0;
*(mx_puncture_turbo+type_punc*80*2+62) = 0;
*(mx_puncture_turbo+type_punc*80+62) = 0;
break;
}
case 2:
{
*(mx_puncture_turbo+type_punc*80*2+50) = 0;
*(mx_puncture_turbo+type_punc*80+50) = 0;
*(mx_puncture_turbo+type_punc*80*2+101) = 0;
*(mx_puncture_turbo+type_punc*80+101) = 0;
*(mx_puncture_turbo+type_punc*80*2+152) = 0;
*(mx_puncture_turbo+type_punc*80+152) = 0;
break;
}
case 4:
{
*(mx_puncture_turbo+type_punc*80*2+90) = 0;
*(mx_puncture_turbo+type_punc*80+90) = 0;
*(mx_puncture_turbo+type_punc*80*2+191) = 0;
*(mx_puncture_turbo+type_punc*80+191) = 0;
*(mx_puncture_turbo+type_punc*80*2+272) = 0;
*(mx_puncture_turbo+type_punc*80+272) = 0;
break;
}
default:
{
return 0;
}
}
}
return 1;
}
/*---------------------------------------------------------------
FUNCTION:
puncture(int *data_unpunc, int length_unpunc, int *data_punctured,
int M_mx_punc, int N_mx_punc, int times_punc)
DESCRIPTION:
This function puncture the sending bits.
PARAMETERS:
INPUT:
data_unpunc - Contains pointer to the input sequence.
length_unpunc - Length of "data_unpunc".
mx_puncture_turbo - Puncture matrix.
M_mx_punc - Number of rows of mx_puncture_turbo.
N_mx_punc - Number of columns of mx_puncture_turbo.
times_punc - The times_punc by which the puncture matrix is used to the input sequence "data_unpunc".
OUTPUT:
data_punctured - Contains pointer to the punctured sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void puncture(int *data_unpunc, int length_unpunc, int *data_punctured,
int M_mx_punc, int N_mx_punc, int times_punc)
{
int i, j, k=0, temp_time=0;
int *mx_puncture_turbo;
switch (N_mx_punc)
{
case 80:
{
mx_puncture_turbo = mx_puncture_turbo_80;
break;
}
case 160:
{
mx_puncture_turbo = mx_puncture_turbo_160;
break;
}
case 320:
{
mx_puncture_turbo = mx_puncture_turbo_320;
break;
}
default:
{
printf("error in puncturing!\n");
exit(1);
}
}
for (temp_time=0; temp_time<times_punc; temp_time++)
{
for (j=0; j<N_mx_punc && (temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc)<length_unpunc; j++)
{
for (i=0; i<M_mx_punc && (temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i)<length_unpunc;i++)
{
if (*(mx_puncture_turbo+i*N_mx_punc+j))
{
*(data_punctured+k) = *(data_unpunc+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i);
k++;
}
}
}
}
if (times_punc*M_mx_punc*N_mx_punc<length_unpunc)
{
for (i=times_punc*M_mx_punc*N_mx_punc; i<length_unpunc; i++)
{
*(data_punctured+k) = *(data_unpunc+i);
k++;
}
}
}
/*---------------------------------------------------------------
FUNCTION:
depuncture(float *receive_punc, int length_punc, float *receive_depunced,
int M_mx_punc, int N_mx_punc, int times_punc)
DESCRIPTION:
This function fills in the punctured sequence.
PARAMETERS:
INPUT:
receive_punc - Contains pointer to the punctured input sequence.
length_punc - Length of "receive_punc".
M_mx_punc - Number of rows of mx_puncture_turbo.
N_mx_punc - Number of columns of mx_puncture_turbo.
times_punc - The times_punc by which the puncture matrix is used to the input sequence "receive_punc".
OUTPUT:
receive_depunced - Contains pointer to the filled sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void depuncture(float *receive_punc, int length_punc, float *receive_depunced,
int M_mx_punc, int N_mx_punc, int times_punc)
{
int i, j, k=0, temp_time=0;
int *mx_puncture_turbo;
switch (N_mx_punc)
{
case 80:
{
mx_puncture_turbo = mx_puncture_turbo_80;
break;
}
case 160:
{
mx_puncture_turbo = mx_puncture_turbo_160;
break;
}
case 320:
{
mx_puncture_turbo = mx_puncture_turbo_320;
break;
}
default:
{
printf("error in puncturing!\n");
exit(1);
}
}
for (temp_time=0; temp_time<times_punc; temp_time++)
{
for (j=0; j<N_mx_punc; j++)
{
for (i=0; i<M_mx_punc && k<length_punc; i++)
{
if (*(mx_puncture_turbo+i*N_mx_punc+j))
{
*(receive_depunced+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i) = *(receive_punc+k);
k++;
}
else
{
*(receive_depunced+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i) = 0;
}
}
}
}
if (k<length_punc)
{
for (i=times_punc*M_mx_punc*N_mx_punc; k<length_punc; i++)
{
*(receive_depunced+i) = *(receive_punc+k);
k++;
}
}
}
/*---------------------------------------------------------------
FUNCTION:
void demultiplex(double *rec_turbo, int len_info, double *yk_turbo)
DESCRIPTION:
Demultiplex the receiving data.
PARAMETERS:
INPUT:
rec_turbo - Contains pointer to receiving data.
len_info - Length of the input information bits.
type_flow - 1 for traffic flow, 0 for suplement flow.
OUTPUT:
yk_turbo - Contains pointer to the sequence after demultiplexing.
RETURN VALUE:
None
---------------------------------------------------------------*/
void demultiplex(float *rec_turbo, int len_info, float *yk_turbo, int type_flow)
{
int i;
int len_total = len_info+M_num_reg;
float *info2, *inted_info2;
if ((info2=(float *)malloc(len_info*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of info2 \n");
exit(1);
}
if ((inted_info2=(float *)malloc(len_info*sizeof(float)))==NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -