📄 channel.c
字号:
/***********************************
*Copyright (C) 2004 FUTURE@NCRL SEU
*All Rights Reserved.
*FileName: _CHANNEL_C_
*Abstract: Get the MIMO Channel's TDL Coef.
*Cur.Ver : 2.0
*Author : Bin Jiang
*Date : 2004-04-13
*Modify : To save memory, the channel coef is
computed online for one sample time.
*Per.Ver : 1.0
*Author : Bin Jiang
*Date : 2003-12-8
*Ref. : D.M. Wang's program.
**********************************/
//Includes Files
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "common.h"
#include "channel.h"
int GenCommonData(double * alpha, double * beta)
{
int n;
int n_PathNum;
int N0 = 25;
int N = 4*N0;
int n_TotalPathNum = TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM_MC;
double Max_Doppler = 2*PI*VELOCITY*Fc/(3.0e8)*1000.0/3600.0;
double gamma;
for(n_PathNum=0; n_PathNum<n_TotalPathNum; n_PathNum++)
{
for(n=0; n<N0; n++)
{
gamma = PI*( (double)2*n + (double)2*n_PathNum/n_TotalPathNum + (double)1/(2*n_TotalPathNum) )/N;
*(alpha+n_PathNum*N0+n) = Max_Doppler*cos(gamma);
*(beta+n_PathNum*N0+n) = Max_Doppler*sin(gamma);
}
}
return n*n_PathNum;
}
int GenCurCHData(double * alpha, double * beta, double * p_Time, COMPLEX * p_CHData, CH_PARAMETER * p_CH_Parameter)
{
int n;
int n_PathNum;
int Index;
int N0 = 25;
int N = 4*N0;
int n_TotalPathNum = TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM_MC;
COMPLEX temp;
COMPLEX CHtemp;
for(n_PathNum=0; n_PathNum<n_TotalPathNum; n_PathNum++)
{
CHtemp.real = CHtemp.image = 0;
for(n=0; n<N0; n++)
{
temp.real = cos((*(alpha+n_PathNum*N0+n))*(*p_Time) + p_CH_Parameter->Phase_R);
temp.image = sin( (*(beta+n_PathNum*N0+n))*(*p_Time) + p_CH_Parameter->Phase_I);
CHtemp = add_cmx(CHtemp, temp);
}
Index = (n_PathNum%(TxANTENNA_NUM*PATH_NUM_MC))/TxANTENNA_NUM;
*(p_CHData+n_PathNum) = mul_cmxreal(CHtemp, PATH_GAIN[Index]/sqrt(N0));
}
(*p_Time) += p_CH_Parameter->Tc;
return n_PathNum;
}
int New_MIMO_Channel(COMPLEX * InSignal, int InSignalLen, COMPLEX * OutSignal, double * p_Time, CH_PARAMETER * p_CH_Parameter)
{
int result;
int n_Tx;
int n_Rx;
int n_Path;
int n_Sample;
int Index;
double Energy_Signal;
double Energy_Noise;
double SNR_Es_N0;
COMPLEX tmp;
int N0 = 25;
int N = 4*N0;
int n_TotalPathNum = TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM_MC;
int InLenPerTx = InSignalLen/TxANTENNA_NUM;
int OutLenPerRx = InLenPerTx + MAX_DELAY;
//Memory
double * alpha;
double * beta;
COMPLEX * p_CHData;
//Allocate memory
alpha = (double *)malloc(N0*n_TotalPathNum*sizeof(double));
beta = (double *)malloc(N0*n_TotalPathNum*sizeof(double));
p_CHData = (COMPLEX *)malloc(n_TotalPathNum*sizeof(COMPLEX));
//Main
result = GenCommonData(alpha, beta);
for(n_Sample=0; n_Sample<OutLenPerRx; n_Sample++)
{
result = GenCurCHData(alpha, beta, p_Time, p_CHData, p_CH_Parameter);
for(n_Rx=0; n_Rx<RxANTENNA_NUM; n_Rx++)
{
tmp.real = tmp.image = 0;
for(n_Path=0; n_Path<PATH_NUM_MC; n_Path++)
{
Index = n_Sample-p_CH_Parameter->Path_Delay[n_Path];
if( Index>=0 && Index<InLenPerTx)
{
for(n_Tx=0; n_Tx<TxANTENNA_NUM; n_Tx++)
{
tmp = add_cmx( tmp, mul_cmx( *(InSignal+n_Tx*InLenPerTx+Index), *(p_CHData+(n_Rx*PATH_NUM_MC+n_Path)*TxANTENNA_NUM+n_Tx) ) );
}
}
}
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->real = tmp.real;
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->image = tmp.image;
}
}
/*
//The first method:
//Add Noise "measured"
//Measure output signal energy
Energy_Signal = 0;
for(n_Sample=0; n_Sample<RxANTENNA_NUM*OutLenPerRx; n_Sample++)
{
Energy_Signal += eng_cmx( *(OutSignal+n_Sample) );
}
Energy_Signal /= n_Sample;
printf("OutEnergy = %f\n", Energy_Signal);
SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? 7.1175876 : 5.3566750); //For new slot structure
*/
//The second method:
Energy_Signal = 4.0; //MC is the same with SC!
SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? 8.2090323 : 6.4481197); //For new slot structure
// SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? (8.2090323+0.3437498) : (6.4481197+0.3437498));
Energy_Noise = Energy_Signal/pow(10, SNR_Es_N0/10);
for(n_Sample=0; n_Sample<RxANTENNA_NUM*OutLenPerRx; n_Sample++)
{
tmp.real = generate_gaussian_source(Energy_Noise)/sqrt(2);
tmp.image = generate_gaussian_source(Energy_Noise)/sqrt(2);
*(OutSignal+n_Sample) = add_cmx( *(OutSignal+n_Sample), tmp );
}
// printf("SignalEnergy = %f\t NoiseEnergy = %f\t SNR_Es_N0 = %f\t\n", Energy_Signal, Energy_Noise, SNR_Es_N0);
//Free memory
free(alpha);
free(beta);
free(p_CHData);
return n_Sample;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -