📄 cvoicems.cpp
字号:
//(本扇区的业务信道接受功率
///(本扇区其他信道的干扰值*正交因子+其他扇区的干扰值+热噪声))
//并转化为dB
m_ActiveSetList.GetNext(posTemp); //获得链表中的下一个激活扇区
}
}
//end of UpdateActiveSet()
///////////////////////////////////////////////////
// 功率控制函数,
//根据计算得到的C/I与功率控制目标C/I的关系,
//调整激活集内各个扇区的发射功率。需要考虑功控误差。
///////////////////////////////////////////////////
void CVoiceMs::PowerControl()
{ //定义必要的变量
float fPowerDelta=(float)(-1*m_pMsManager->m_fPowerControlStep);
//业务信道功率增量,单位:dB
float fMinTrafficPower; //业务信道最小值,单位:mw
float fTotalC2I=0; //总的C/I,初值为零
float frv; //(0,1)分布的随机数
float fTempTrafficPower; //业务信道功率,单位:dBm
float fTargetC2I;
POSITION posTemp; //临时位置指针
CSector* pTempSector=NULL; //临时扇区指针
fTotalC2I=m_fC2I; //获得当前时隙的C/I
switch(m_iFwdFrameRate)
{
case FULL_RATE : fTargetC2I=/*m_pMsManager->*/m_fC2ITarget;
break;
case HALF_RATE : fTargetC2I=/*m_pMsManager->*/m_fC2ITarget-(float)3.0;
break;
case QUARTER_RATE : fTargetC2I=/*m_pMsManager->*/m_fC2ITarget-(float)6.0;
break;
case EIGHTH_RATE : fTargetC2I=/*m_pMsManager->*/m_fC2ITarget-(float)9.0;
break;
}
if(fTotalC2I<=fTargetC2I)
//如果当前时隙的C/I小于目标C/I
fPowerDelta*=(-1);//调整步长为正(增加)
frv=xUniform(0.0,1.0);//产生一个(0,1)分布的随机数,用来模拟功控误差
if(frv<m_pMsManager->m_fBEROfPC)
//如果随机数小于功控比特差错概率
fPowerDelta*=(-1);//功控出错,原来的加变成了减
posTemp=m_ActiveSetList.GetHeadPosition();
//取得链表头,并令临时指针指向链表头
while(posTemp!=NULL) //到达链表尾则结束循环
{
pTempSector=
m_pServiceArea->GetSector(m_ActiveSetList.GetAt(posTemp)->stSectorID);
//获得激活扇区的指针
fTempTrafficPower=
(float)(10*log10(m_ActiveSetList.GetAt(posTemp)->
fTrafficPower));
fTempTrafficPower+=fPowerDelta; //调整业务信道功率值
m_ActiveSetList.GetAt(posTemp)->fTrafficPower=
(float)(pow(10,(fTempTrafficPower/10)));
if(m_ActiveSetList.GetAt(posTemp)->fTrafficPower>
pTempSector->GetMaxPower()
*m_pMsManager->m_fMaxFractionOfTrafficPower)
//如果业务信道功率大于最大值
m_ActiveSetList.GetAt(posTemp)->fTrafficPower=
pTempSector->GetMaxPower()*m_pMsManager->
m_fMaxFractionOfTrafficPower;
//就将业务信道功率置为最大值
fMinTrafficPower=
(float)((pTempSector->GetMaxPower()*
m_pMsManager->m_fMaxFractionOfTrafficPower)
/pow(10,(m_pMsManager->m_fDynamicRangeOfTrafficPower/10)));
//将dB转化为mw
if(m_ActiveSetList.GetAt(posTemp)->fTrafficPower<
fMinTrafficPower)
//如果业务信道功率小于动态范围
m_ActiveSetList.GetAt(posTemp)->fTrafficPower=
fMinTrafficPower;
//就将业务信道功率置为最小值(动态范围)
m_ActiveSetList.GetNext(posTemp);
//获得链表的下一个激活扇区结构
}
}
//end of PowerControl()
//////////////////////////////////////////////////////////////////////////
// 话音激活特性设置函数, //
// 根据话音激活因子,设置话音激活标志。 //
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::SetVoiceActivity()
{ //定义必要的变量
m_fFwdLastActiveFactor=m_fFwdCurrentActiveFactor;
if(m_iSlotCount%16==1)//modified by cqm, May.14
{
m_iFwdFrameRate=m_cFwdMarkovState.GetNextState()%4;
switch(m_iFwdFrameRate)
{
case FULL_RATE : m_fFwdCurrentActiveFactor=1.0;
break;
case HALF_RATE : m_fFwdCurrentActiveFactor=0.5;
break;
case QUARTER_RATE : m_fFwdCurrentActiveFactor=0.25;
break;
case EIGHTH_RATE : m_fFwdCurrentActiveFactor=0.125;
break;
}
}
}
//end of SetVoiceActivity()
//////////////////////////////////////////////////////////////////////////
// 服务时长到时的判断函数, //
// 判断服务时长是否到时,到时返回TRUE。 //
//////////////////////////////////////////////////////////////////////////
bool CVoiceMs::IsServiceOver()
{
if(m_iServiceLength<=0) //如果服务到时
return true; //返回true
else
return false; //返回false
}
//end of IsServiceOver()
//////////////////////////////////////////////////////////////////////////
// 更新激活集功率函数, //
// 得到激活集的总功率 //
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::UpdateActiveSetPower()
{ //定义必要的变量
POSITION posTemp; //位置变量
ACTIVESECTOR_TYPE* pTempActiveSector=NULL;//临时激活扇区结构体
CSector* pSector=NULL; //扇区指针
float fTempPower; //临时功率,单位:mw
posTemp=m_ActiveSetList.GetHeadPosition();//获得链表头指针
while(posTemp!=NULL) //到达链表尾则结束循环
{
pTempActiveSector=m_ActiveSetList.GetNext(posTemp);
//获得当前激活扇区
fTempPower=pTempActiveSector->fTrafficPower;//获得功率值
pSector=
m_pServiceArea->GetSector(pTempActiveSector->stSectorID);
//得到扇区指针
pSector->VoicePowerCumulate(fTempPower); //累加话音业务总功率
}
}
//end of UpdateActiveSetPower()
void CVoiceMs::Clean()
{
POSITION posTemp; //临时位置指针
posTemp=m_ActiveSetList.GetHeadPosition(); //取得链表的头指针
while(posTemp!=NULL) //到链表尾则结束循环
{
delete m_ActiveSetList.GetNext(posTemp); //释放内存
}
m_ActiveSetList.RemoveAll(); //移去指针
posTemp=m_SoftHandoffMessageList.GetHeadPosition(); //取得链表的头指针
while(posTemp!=NULL) //到链表尾则结束循环
{
delete m_SoftHandoffMessageList.GetNext(posTemp);//释放内存
}
m_SoftHandoffMessageList.RemoveAll(); //移去指针
}
//end of Clean()
//...... added by cqm, Apr.9 ......//
//FER预测函数,根据接收到的Eb/Nt值,查短期FER vs Eb/Nt表得到当前用户的FER
void CVoiceMs::FERPrediction()
{
float x1,x2,y1,y2,x,y;
switch(m_iFwdFrameRate)
{
case HALF_RATE : m_fMeanC2IofLastFrame+=3.;
break;
case QUARTER_RATE : m_fMeanC2IofLastFrame+=6.;
break;
case EIGHTH_RATE : m_fMeanC2IofLastFrame+=9.;
break;
default : break;
}
for (int ii=1;ii<26;ii++)
{
if (m_fMeanC2IofLastFrame<m_pfC2IIndex[ii])
break;
}
if (ii==26)
{
x2=m_pfC2IIndex[25];
y2=(float)log(m_pfFER[25]);
x1=m_pfC2IIndex[24];
y1=(float)log(m_pfFER[24]);
}
else
{
x2=m_pfC2IIndex[ii];
y2=(float)log(m_pfFER[ii]);
x1=m_pfC2IIndex[ii-1];
y1=(float)log(m_pfFER[ii-1]);
}
x=m_fMeanC2IofLastFrame;
y=((x2-x)*y1+(x-x1)*y2)/(x2-x1);
m_fFER=(float)exp(y);
}
//end of FERPrediction()
//帧质量判断函数,判断当前slot话音帧是否正确
void CVoiceMs::FrameQualityDecision()
{
Random R;
float fRand;
fRand=(float)R.Next();
if(fRand>m_fFER)
m_bIsFrameCorrect=true;
else
m_bIsFrameCorrect=false;
}
//end of FrameQualityDecision()
//服务质量判断函数,如果短期FER大于15%,m_iFERIndicator加一
void CVoiceMs::GOSDecision()
{
float fFER;
// bsFrameErrorFlagSet <<= 1; //标志位全部左移1位(好像是左移),末位补0
// if(m_bIsFrameCorrect) //如果当前帧正确
// bsFrameErrorFlagSet.flip(0);//末位补1(即代表帧正确)
// uiCountErrorFrame=WindowSize - bsFrameErrorFlagSet.count();//计算窗口中0的个数
// m_fFER = (float)uiCountErrorFrame/WindowSize;//计算短期误码率
//for test(cqm)
// if(m_iMsID==10)
// cout<<uiCountErrorFrame<<" "<<WindowSize<<" "<<m_fFER<<endl;
//////////////
if(!m_bIsFrameCorrect)
m_iBadFrameCounter++;
if(m_iSlotCount%320==0)
{
// if(!m_bIsFrameCorrect)
// m_iBadFrameCounter++;
fFER=(float)m_iBadFrameCounter/WindowSize;
if(fFER>=0.15)
m_iFERIndicator++;
m_iBadFrameCounter=0;
}
}
//end of GOSDecision()
//判断用户是否中断函数,在用户通话结束或drop结束时由CMsManager调用
//void CVoiceMs::IsUserOutage()
//{
//}
//.................................//
//////////////////////////////////////////////////////////////////////////
// get(),set() //
//////////////////////////////////////////////////////////////////////////
//...... added by cqm, Apr.9 ......//
int CVoiceMs::GetFERIndicator()
{
return m_iFERIndicator;
}
void CVoiceMs::SetFERIndicator(int i_inputFERIndicator)
{
m_iFERIndicator=i_inputFERIndicator;
}
int CVoiceMs::GetActiveSetSize()
{
return m_iActiveSetSize;
}
void CVoiceMs::SetActiveSetSize(int i_inputActiveSetSize)
{
m_iActiveSetSize=i_inputActiveSetSize;
}
int CVoiceMs::GetServiceLength()
{
return m_iServiceLength;
}
void CVoiceMs::SetServiceLength(int i_inputServiceLength)
{
m_iServiceLength=i_inputServiceLength;
}
int CVoiceMs::GetServiceTime()
{
return m_iServiceTime;
}
void CVoiceMs::SetServiceTime(int i_inputServiceTime)
{
m_iServiceTime=i_inputServiceTime;
}
int CVoiceMs::GetSHOMsgNum()
{
return m_iSHOMsgNum;
}
void CVoiceMs::SetSHOMsgNum(int i_inputSHOMsgNum)
{
m_iSHOMsgNum=i_inputSHOMsgNum;
}
int CVoiceMs::GetDropTimer()
{
return m_iDropTimer;
}
void CVoiceMs::SetDropTimer(int i_inputDropTimer)
{
m_iDropTimer=i_inputDropTimer;
}
int CVoiceMs::GetUnsatisfiedTimer()
{
return m_iUnsatisfiedTimer;
}
void CVoiceMs::SetUnsatisfiedTimer(int i_inputUnsatisfiedTimer)
{
m_iUnsatisfiedTimer=i_inputUnsatisfiedTimer;
}
float CVoiceMs::GetVoiceActiveFactor()
{
return m_fVoiceActiveFactor;
}
void CVoiceMs::SetVoiceActiveFactor(float i_inputVoiceActiveFactor)
{
m_fVoiceActiveFactor=i_inputVoiceActiveFactor;
}
float CVoiceMs::GetC2I()
{
return m_fC2I;
}
void CVoiceMs::SetC2I(float f_inputC2I)
{
m_fC2I=f_inputC2I;
}
//bool CVoiceMs::IsServiceActive()
//得到当前时隙的话音激活标志,TRUE激活
//{
// return m_bIsServiceActive;
//}
bool CVoiceMs::IsC2IEnough()
//得到当前C/I是否超过门限值,TRUE为超过
{
return m_bIsC2IEnough;
}
//end of get and set
//end of CVoiceMs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -