📄 ofdm_receiver.c
字号:
if (tap_power[j] >= thresh_v) {
tap_idx[tap_count] = j;
tap_count++;
for (i = 0; i < repeat_M; i++) {
pilot_proc1[j+i*inter_K*PILOT_LENGTH].real = pilot_rev[j+i*inter_K*PILOT_LENGTH].real;
pilot_proc1[j+i*inter_K*PILOT_LENGTH].imag = pilot_rev[j+i*inter_K*PILOT_LENGTH].imag;
}
}
else {
for (i = 0; i < repeat_M; i++) {
pilot_proc1[j+i*inter_K*PILOT_LENGTH].real = 0;
pilot_proc1[j+i*inter_K*PILOT_LENGTH].imag = 0;
pilot_proc2[j+i*inter_K*PILOT_LENGTH].real = 0;
pilot_proc2[j+i*inter_K*PILOT_LENGTH].imag = 0;
}
}
}
/* search for max point */
max_idx = tap_idx[0];
max_value = tap_power[max_idx];
for (j = 1; j < tap_count; j++) {
if (tap_power[tap_idx[j]] > max_value) {
max_idx = tap_idx[j];
max_value = tap_power[max_idx];
}
}
}
else {
/* MST search according to tap number */
tap_count = MST_TAP_LEN;
/* search for most significant taps */
pow_s = 0;
for (j = 0; j < tap_count; j++) {
max_idx = 0;
max_value = tap_power[max_idx];
for (i = 1; i < PILOT_LENGTH; i++) {
if (tap_power[i] > max_value) {
max_value = tap_power[i];
max_idx = i;
}
}
pow_s = pow_s + tap_power[max_idx]; // signal power
tap_idx[j] = max_idx;
tap_power[max_idx] = 0;
}
max_idx = tap_idx[0];
/* zero force at none MST */
/*
for (j = 0; j < PILOT_LENGTH; j++) {
for (i = 0; i < repeat_M; i++) {
pilot_proc1[j+i*inter_K*PILOT_LENGTH].real = 0;
pilot_proc1[j+i*inter_K*PILOT_LENGTH].imag = 0;
pilot_proc2[j+i*inter_K*PILOT_LENGTH].real = 0;
pilot_proc2[j+i*inter_K*PILOT_LENGTH].imag = 0;
}
}
*/
for (j = 0; j < PILOT_LENGTH; j++) {
for (i = 0; i < sub_clk_size; i++) {
pilot_proc1[j+i*PILOT_LENGTH].real = 0;
pilot_proc1[j+i*PILOT_LENGTH].imag = 0;
pilot_proc2[j+i*PILOT_LENGTH].real = 0;
pilot_proc2[j+i*PILOT_LENGTH].imag = 0;
}
}
for (j = 0; j < tap_count; j++) {
for (i = 0; i < repeat_M; i++) {
pilot_proc1[tap_idx[j]+i*inter_K*PILOT_LENGTH].real = pilot_rev[tap_idx[j]+i*inter_K*PILOT_LENGTH].real;
pilot_proc1[tap_idx[j]+i*inter_K*PILOT_LENGTH].imag = pilot_rev[tap_idx[j]+i*inter_K*PILOT_LENGTH].imag;
}
}
}
for (tmp_i = 0; tmp_i < repeat_M; tmp_i++ ){
for (tmp_j = 1; tmp_j < inter_K; tmp_j++){
for (tmp_k = 0; tmp_k < PILOT_LENGTH; tmp_k++){
pilot_proc1[tmp_k+tmp_i*inter_K*PILOT_LENGTH+tmp_j*PILOT_LENGTH].real = pilot_proc1[tmp_k+tmp_i*inter_K*PILOT_LENGTH].real;
pilot_proc1[tmp_k+tmp_i*inter_K*PILOT_LENGTH+tmp_j*PILOT_LENGTH].imag = pilot_proc1[tmp_k+tmp_i*inter_K*PILOT_LENGTH].imag;
}
}
}
// write_file(target1_file, pilot_proc1, sub_clk_size, PILOT_LENGTH);
/* polymial algorithm*/
filename = matrix_file;
fp = fopen(filename,"r");
for (tmp_i = 0; tmp_i < poly_g+1;tmp_i++){
for (tmp_j = 0; tmp_j < repeat_M;tmp_j++){
if (!feof(fp)){
fscanf(fp,"%f",&tmp_fv);
multi_matrix[tmp_i][tmp_j] = (double)tmp_fv;
}
}
}
fclose(fp);
// write_file_double(target1_file, multi_matrix[0], poly_g+1, repeat_M);
for (tmp_i = 0; tmp_i < poly_g+1;tmp_i++){
for (tmp_j = 0; tmp_j < tap_count;tmp_j++){
tmp_real = 0;
tmp_imag = 0;
for (tmp_k = 0; tmp_k < repeat_M; tmp_k++){
tmp_real = tmp_real + multi_matrix[tmp_i][tmp_k]*pilot_proc1[tmp_k*inter_K*PILOT_LENGTH+tap_idx[tmp_j]].real;
tmp_imag = tmp_imag + multi_matrix[tmp_i][tmp_k]*pilot_proc1[tmp_k*inter_K*PILOT_LENGTH+tap_idx[tmp_j]].imag;
}
factor_matrix[tmp_i][tmp_j].real = tmp_real;
factor_matrix[tmp_i][tmp_j].imag = tmp_imag;
}
}
// write_file(target2_file, factor_matrix[0], poly_g+1, tap_count);
/* for (tmp_j = 0; tmp_j < poly_g+1;tmp_j++){
if (tmp_j == 0){
recov_matrix[0][tmp_j] = 1;
}
else{
recov_matrix[0][tmp_j] = 0;
}
}
*/
for (tmp_i = 0; tmp_i < tmp_clk_size;tmp_i++){
tmp_v = 1;
for (tmp_j = 0; tmp_j < poly_g+1;tmp_j++){
recov_matrix[tmp_i][tmp_j] = tmp_v;
tmp_v = tmp_v*tmp_i;
}
}
// write_file_double(target_file, recov_matrix[0], tmp_clk_size, poly_g+1);
for (tmp_i = 0; tmp_i < tmp_clk_size;tmp_i++){
for (tmp_j = 0; tmp_j < tap_count; tmp_j++){
tmp_real = 0;
tmp_imag = 0;
for (tmp_k = 0; tmp_k < poly_g+1; tmp_k++){
tmp_real = tmp_real + recov_matrix[tmp_i][tmp_k]*factor_matrix[tmp_k][tmp_j].real;
tmp_imag = tmp_imag + recov_matrix[tmp_i][tmp_k]*factor_matrix[tmp_k][tmp_j].imag;
}
pilot_proc2[tap_idx[tmp_j]+tmp_i*PILOT_LENGTH].real = tmp_real;
pilot_proc2[tap_idx[tmp_j]+tmp_i*PILOT_LENGTH].imag = tmp_imag;
}
}
// write_file(target2_file, pilot_proc2, sub_clk_size, PILOT_LENGTH);
/* log each tap's avarage power to file
{
FILE *log_fp;
log_fp = fopen(LOG_TAP_STP2, "a+");
fprintf(log_fp, "%d\n", win_len);
fclose(log_fp);
}*/
}
/*function : MST + polynomial algorithm*/
void channel_poly(pilot_rev, pilot_proc1, pilot_proc2)
Complex *pilot_rev;
Complex *pilot_proc1;
Complex *pilot_proc2;
{
int i,j,k;
int poi_ind;
Complex sub_blk_plt_rev[sub_clk_size][PILOT_LENGTH];
Complex sub_blk_plt_tar1[sub_clk_size][PILOT_LENGTH];
Complex sub_blk_plt_tar2[sub_clk_size][PILOT_LENGTH];
int sub_blk_num;
int tmp_blk;
tmp_blk = sub_clk_size;
sub_blk_num = (int)(floor(1024/tmp_blk));
initial_matrix(sub_clk_size,PILOT_LENGTH,sub_blk_plt_tar1[0]);
initial_matrix(sub_clk_size,PILOT_LENGTH,sub_blk_plt_tar2[0]);
for (i = 0 ;i < sub_blk_num + 1; i++){
if ( (1024 - tmp_blk*i) >= tmp_blk ){
poi_ind = i*tmp_blk;
}
else{
poi_ind = 1024 - tmp_blk;
}
for (j = 0; j < tmp_blk ; j++){
for (k = 0; k < PILOT_LENGTH ; k ++){
sub_blk_plt_rev[j][k].real = pilot_rev[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].real;
sub_blk_plt_rev[j][k].imag = pilot_rev[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].imag;
}
}
sub_esti_poly(sub_blk_plt_rev[0],sub_blk_plt_tar1[0],sub_blk_plt_tar2[0]);
// write_file(source_file, sub_blk_plt_rev[0], sub_clk_size, PILOT_LENGTH);
// write_file(target1_file, sub_blk_plt_tar1[0], sub_clk_size, PILOT_LENGTH);
// write_file(target2_file, sub_blk_plt_tar2[0], sub_clk_size, PILOT_LENGTH);
for (j = 0; j < tmp_blk ; j++){
for (k = 0; k < PILOT_LENGTH ; k ++){
pilot_proc1[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].real=sub_blk_plt_tar1[j][k].real;
pilot_proc1[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].imag=sub_blk_plt_tar1[j][k].imag;
pilot_proc2[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].real=sub_blk_plt_tar2[j][k].real;
pilot_proc2[poi_ind*PILOT_LENGTH+j*PILOT_LENGTH+k].imag=sub_blk_plt_tar2[j][k].imag;
}
}
}
write_file(source_file, sub_blk_plt_rev[0], sub_clk_size, PILOT_LENGTH);
write_file(target_file, pilot_proc2, 1024, PILOT_LENGTH);
write_file(target1_file, sub_blk_plt_tar1[0], sub_clk_size, PILOT_LENGTH);
write_file(target2_file, sub_blk_plt_tar2[0], sub_clk_size, PILOT_LENGTH);
tmp_blk = sub_clk_size;
}
/* function : caculate mse */
void mse_caculate(pilot_true, pilot_proc, mse, index)
Complex *pilot_true;
Complex *pilot_proc;
double * mse;
int index;
{
int i;
double impuls_mse;
Complex abs_erros;
impuls_mse = 0;
for (i = 0; i < PILOT_LENGTH; i++) {
abs_erros = c_sub(pilot_true[i], pilot_proc[i]);
impuls_mse = impuls_mse + abs_erros.real * abs_erros.real + abs_erros.imag * abs_erros.imag;
}
// impuls_mse = impuls_mse / PILOT_LENGTH;
mse[index] = impuls_mse;
}
/* function : channel equalize */
void chn_equalize(pilot_proc, data_org, data_rev, ber, index)
Complex *pilot_proc;
Complex *data_org;
Complex *data_rev;
double * ber;
int index;
{
int i, j, d_idx, nelem, p_dist, error_count;
Complex fre_shift, w_tmp;
double bas_phase, regbit1, regbit2;
Complex dat_chn[DATA_SUBC_LEN];
Complex data_tmp[DATA_SUBC_LEN];
int tmp_t;
double tmp_ber;
double xreal[SUBCARRIERS], ximag[SUBCARRIERS],
yreal[SUBCARRIERS], yimag[SUBCARRIERS];
double bit_rev[MODULATE_ORDER*DATA_SUBC_LEN],
bit_org[MODULATE_ORDER*DATA_SUBC_LEN];
bas_phase = PI2 * PILOT_PHASE / SUBCARRIERS;
/* frequency shift cause by pilot insert phase */
for (i = 0; i < PILOT_LENGTH; i++) {
fre_shift.real = cos(i*bas_phase);
fre_shift.imag = sin(i*bas_phase);
w_tmp = c_mul(pilot_proc[i], fre_shift);
xreal[i] = w_tmp.real;
ximag[i] = w_tmp.imag;
}
/* zeros pad */
for (i = PILOT_LENGTH; i < SUBCARRIERS; i++) {
xreal[i] = 0;
ximag[i] = 0;
}
/* transform into frequency domain */
fft(SUBCARRIERS, xreal, ximag, yreal, yimag);
/* extract frequency response at data position */
d_idx = 0;
for (i = 0; i < SUBCARRIERS; i++) {
if ((i-PILOT_PHASE) % PILOT_GAP != 0) {
if (i >= FREQ_GUARD_LEN && i < (SUBCARRIERS-FREQ_GUARD_LEN)) {
dat_chn[d_idx].real = yreal[i];
dat_chn[d_idx].imag = yimag[i];
d_idx++;
}
}
}
/* correct the reveived data */
for (i = 0; i < DATA_SUBC_LEN; i++) {
data_tmp[i] = c_dvd(data_rev[i], dat_chn[i]);
}
/* demap received data */
nelem = MODULATE_ORDER/2;
p_dist = 2;
for (i = 0; i < DATA_SUBC_LEN; i++) {
regbit1 = data_tmp[i].imag;
regbit2 = data_tmp[i].real;
for (j = 0; j < nelem; j++) {
bit_rev[MODULATE_ORDER*i+j] = (regbit1>=0)? 1:0;
bit_rev[MODULATE_ORDER*i+j+nelem] = (regbit2>=0)? 1:0;
regbit1 = fabs(regbit1) - (nelem-j-1)*p_dist;
regbit2 = fabs(regbit2) - (nelem-j-1)*p_dist;
}
}
/* demap orignal data */
nelem = MODULATE_ORDER/2;
p_dist = 2;
for (i = 0; i < DATA_SUBC_LEN; i++) {
regbit1 = data_org[i].imag;
regbit2 = data_org[i].real;
for (j = 0; j < nelem; j++) {
bit_org[MODULATE_ORDER*i+j] = (regbit1>=0)? 1:0;
bit_org[MODULATE_ORDER*i+j+nelem] = (regbit2>=0)? 1:0;
regbit1 = fabs(regbit1) - (nelem-j-1)*p_dist;
regbit2 = fabs(regbit2) - (nelem-j-1)*p_dist;
}
}
/* ber count */
error_count = 0;
for (i = 0; i < MODULATE_ORDER*DATA_SUBC_LEN; i++) {
if (bit_org[i] != bit_rev[i]) {
error_count++;
}
}
tmp_t = TOTAL_BIT_PER_SYM;
tmp_ber = ((double)error_count)/tmp_t;
ber[index] = tmp_ber;
}
/*function average the input number*/
void average_func(in, out, average_num, index)
double * in;
double * out;
int average_num;
int index;
{
int i;
double tmp_v = 0;
for (i = 0; i < average_num; i++){
tmp_v = tmp_v + in[i];
}
out[index] = tmp_v/average_num;
}
/* write file function*/
void write_file(filename, vector, row, column)
char * filename;
Complex * vector;
int row;
int column;
{
FILE * fp;
int i,j;
fp = fopen(filename,"w");
for (i = 0; i < row; i++){
for(j = 0; j < column; j++){
fprintf(fp,"%f ,%f\n",vector[i*column+j].real,vector[i*column+j].imag);
}
}
fclose(fp);
}
void write_file_double(filename, vector, row, column)
char * filename;
double * vector;
int row;
int column;
{
FILE * fp;
int i,j;
float tmp_v;
fp = fopen(filename,"w");
for (i = 0; i < row; i++){
for(j = 0; j < column; j++){
tmp_v = vector[i*column+j];
fprintf(fp,"%f\n",tmp_v);
}
}
fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -