📄 channel.c
字号:
/***********************************
*Copyright (C) 2003 FUTURE@NCRL SEU
*All Rights Reserved.
*FileName: _CHANNEL_C_
*Abstract: Get the MIMO Channel's TDL Coef.
*Cur.Ver : 1.0
*Author : Bin Jiang
*Date : 2003-12-8
*Modify :
*Per.Ver :
*Author :
*Date :
*Ref. : D.M. Wang's program.
**********************************/
//Includes Files
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "common.h"
#include "channel.h"
int GenerateCHData(COMPLEX * p_CHData, int n_SampleLen, double * p_Time, CH_PARAMETER * p_CH_Parameter)
{
int n;
int n_Sample;
int n_PathNum;
int Index;
int N0 = 25;
int N = 4*N0;
int n_TotalPathNum = TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM;
double Max_Doppler = 2*PI*VELOCITY*Fc/(3.0e8)*1000.0/3600.0;
COMPLEX temp;
COMPLEX CHtemp;
double * alpha;
double * beta;
double gamma;
//Allocate memory
alpha = (double *)malloc(N0*n_TotalPathNum*sizeof(double));
beta = (double *)malloc(N0*n_TotalPathNum*sizeof(double));
//Intial
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);
}
}
//Compute CHData
for(n_Sample=0; n_Sample<n_SampleLen; n_Sample++)
{
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))/PATH_NUM; //This is a bug!
Index = (n_PathNum%(TxANTENNA_NUM*PATH_NUM))/TxANTENNA_NUM;
*(p_CHData+n_Sample*n_TotalPathNum+n_PathNum) = mul_cmxreal(CHtemp, PATH_GAIN[Index]/sqrt(N0));
}
(*p_Time) += p_CH_Parameter->Tc;
}
//Free memory
free(alpha);
free(beta);
return n_PathNum*n_Sample;
}
//Just for Current use, it should be updated in later.
int GetIdealCHEst(COMPLEX * p_CHData, COMPLEX * p_CHEstimate, BASEBAND_PARM * p_Baseband_Parm)
{
int n_slot;
int n_subslot;
int n_Sample;
int n_Path;
int n_TotalPathNum = TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM;
COMPLEX tmpSum;
for(n_slot=0; n_slot<p_Baseband_Parm->FRAME_SLOTNUM; n_slot++)
{
for(n_subslot=0; n_subslot<SUBSLOT_NUM; n_subslot++)
{
for(n_Path=0; n_Path<n_TotalPathNum; n_Path++)
{
tmpSum.real = tmpSum.image = 0;
for(n_Sample=0; n_Sample<SUBSLOT_LENGTH; n_Sample++)
{
tmpSum = add_cmx( tmpSum, *(p_CHData+(n_slot*SLOT_LENGTH+n_subslot*SUBSLOT_LENGTH+n_Sample)*n_TotalPathNum+n_Path) );
}
*(p_CHEstimate+(n_slot*SUBSLOT_NUM+n_subslot)*n_TotalPathNum+n_Path) = div_cmxreal(tmpSum, (double)n_Sample);
}
}
}
return (n_slot*n_subslot*n_Path);
}
int MIMO_Channel(COMPLEX * InSignal, int InSignalLen, COMPLEX * OutSignal, double * Noise_Variance, double * p_Time, CH_PARAMETER * p_CH_Parameter, BASEBAND_PARM * p_Baseband_Parm)
{
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;
double NoiseVariance;
COMPLEX tmp;
int InLenPerTx = InSignalLen/TxANTENNA_NUM;
int OutLenPerRx = InLenPerTx + MAX_DELAY;
COMPLEX * p_CHData;
//Allocate memory
p_CHData = (COMPLEX *)malloc(TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM*OutLenPerRx*sizeof(COMPLEX));
result = GenerateCHData(p_CHData, OutLenPerRx, p_Time, p_CH_Parameter);
for(n_Rx=0; n_Rx<RxANTENNA_NUM; n_Rx++)
{
for(n_Sample=0; n_Sample<OutLenPerRx; n_Sample++)
{
tmp.real = tmp.image = 0;
for(n_Path=0; n_Path<PATH_NUM; 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_Sample*RxANTENNA_NUM+n_Rx)*PATH_NUM+n_Path)*TxANTENNA_NUM+n_Tx) ) );
}
}
}
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->real = tmp.real;
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->image = tmp.image;
}
}
/*
//Test insignal energy
Energy_Signal = 0;
for(n_Sample=0; n_Sample<InSignalLen; n_Sample++)
{
Energy_Signal += eng_cmx( *(InSignal+n_Sample) );
}
Energy_Signal /= n_Sample;
printf("InEnergy = %f\n", Energy_Signal);
*/
/*
//Add Noise "measured"
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;
*/
Energy_Signal = 4.0;
// SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? 8.028520 : 6.267608); //10*log10(TxANTENNA_NUM*SYMBOL_SLOT*4*INPUT/OUTPUT/SLOT_LENGTH); //OLD SLOT STRUCTURE
SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? 8.2090323 : 6.4481197); //For new slot structure
Energy_Noise = Energy_Signal/pow(10, SNR_Es_N0/10);
NoiseVariance = 0;
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);
NoiseVariance += eng_cmx(tmp);
*(OutSignal+n_Sample) = add_cmx( *(OutSignal+n_Sample), tmp );
}
*Noise_Variance = NoiseVariance/n_Sample;
// printf("SignalEnergy = %f\t NoiseEnergy = %f\t SNR_Es_N0 = %f\t\n", Energy_Signal, Energy_Noise, SNR_Es_N0);
//Free memory
free(p_CHData);
return n_Sample;
}
/*
//Just for Current use, it should be updated in later.
int MIMO_Channel(COMPLEX * InSignal, int InSignalLen, COMPLEX * OutSignal, COMPLEX * p_CHEstimate, double * Noise_Variance, double * p_Time, CH_PARAMETER * p_CH_Parameter, BASEBAND_PARM * p_Baseband_Parm)
{
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;
double NoiseVariance;
COMPLEX tmp;
int InLenPerTx = InSignalLen/TxANTENNA_NUM;
int OutLenPerRx = InLenPerTx + MAX_DELAY;
COMPLEX * p_CHData;
//Allocate memory
p_CHData = (COMPLEX *)malloc(TxANTENNA_NUM*RxANTENNA_NUM*PATH_NUM*OutLenPerRx*sizeof(COMPLEX));
result = GenerateCHData(p_CHData, OutLenPerRx, p_Time, p_CH_Parameter);
result = GetIdealCHEst(p_CHData, p_CHEstimate, p_Baseband_Parm);
for(n_Rx=0; n_Rx<RxANTENNA_NUM; n_Rx++)
{
for(n_Sample=0; n_Sample<OutLenPerRx; n_Sample++)
{
tmp.real = tmp.image = 0;
for(n_Path=0; n_Path<PATH_NUM; 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_Sample*RxANTENNA_NUM+n_Rx)*PATH_NUM+n_Path)*TxANTENNA_NUM+n_Tx) ) );
}
}
}
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->real = tmp.real;
(OutSignal+n_Rx*OutLenPerRx+n_Sample)->image = tmp.image;
}
}
//Add Noise "measured"
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;
SNR_Es_N0 = p_CH_Parameter->SNR + ((OUTPUT==2) ? 8.028520 : 6.267608); //10*log10(TxANTENNA_NUM*SYMBOL_SLOT*4*INPUT/OUTPUT/SLOT_LENGTH);
Energy_Noise = Energy_Signal/pow(10, SNR_Es_N0/10);
NoiseVariance = 0;
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);
NoiseVariance += eng_cmx(tmp);
*(OutSignal+n_Sample) = add_cmx( *(OutSignal+n_Sample), tmp );
}
*Noise_Variance = NoiseVariance/n_Sample;
// printf("SignalEnergy = %f\t NoiseEnergy = %f\t SNR_Es_N0 = %f\t\n", Energy_Signal, Energy_Noise, SNR_Es_N0);
//Free memory
free(p_CHData);
return n_Sample;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -