📄 cvoicems.cpp
字号:
//////////////////////////////////////////////////////////////////////////
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;//获得功率值(此激活扇区对此Ms的发射功率)
pSector=
m_pServiceArea->GetSector(pTempActiveSector->stSectorID);
//得到扇区指针
pSector->VoicePowerCumulate(fTempPower); //累加各个Sector的话音业务总功率
}
}
//////////////////////////////////////////////////////////////////////////
//TITLE: Clean(通话结束清除链表函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 通话结束后,释放VoiceMs的激活集链表和软切换消息链表
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//NOTES: 1.这个函数还是放在话音移动台中实现,而不放在基类中。因为是满
// buffer业务,数据链表中的用户不需要释放,当当前包传完后,直
// 接又产生新的包就行了。
// 数据移动台只有在5秒钟内都接纳失败时,才可能要进行重撒。而这种
// 情况下,数据移动台的激活集链表、软切换消息链表都还是空的,
// 也就是说不需要调用这个clean函数。
//
// 2.在释放激活链表前先要将话音用户激活集中的话音功率从相应的激活
// 扇区中释放
//
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::Clean()
{
CSector* pTempSector=NULL; //临时扇区指针
POSITION posTemp; //临时位置指针
float fTempTrafficPower;
posTemp=m_ActiveSetList.GetHeadPosition(); //取得链表的头指针
while(posTemp!=NULL) //到链表尾则结束循环
{
pTempSector=
m_pServiceArea->GetSector(m_ActiveSetList.GetAt(posTemp)->stSectorID);
//获得激活扇区的指针
fTempTrafficPower=
(float)((m_ActiveSetList.GetAt(posTemp)->fTrafficPower));
fTempTrafficPower*=(-1);
//delete the voice power from the active sectors
pTempSector->VoicePowerCumulate(fTempTrafficPower);
//update the total power of the sector
pTempSector->TxPowerUpdate();
delete m_ActiveSetList.GetNext(posTemp); //释放内存
}
m_ActiveSetList.RemoveAll(); //移去指针
posTemp=m_SoftHandoffMessageList.GetHeadPosition(); //取得链表的头指针
while(posTemp!=NULL) //到链表尾则结束循环
{
delete m_SoftHandoffMessageList.GetNext(posTemp);//释放内存
}
m_SoftHandoffMessageList.RemoveAll(); //移去指针
}
//////////////////////////////////////////////////////////////////////////
//TITLE: BLERPrediction(误块率估计函数)
//
//PARAMETERS:
//
//PURPOSE AND ALGORITHMS:
// 每个TTI结束后,根据接收到的平均C/I值,查BLER vs C/I表得到
// 当前用户这个TTI时间内的BLER,从而用于误块估计
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//NOTES: 在进行误块率估计的时候,要考虑不同激活因子的因素
//
//////////////////////////////////////////////////////////////////////////
float CVoiceMs::BLERPrediction(float TTIMeanC2I)
{
float x1,x2,y1,y2,x,y;
switch(m_iFwdFrameRate) //实际上,这里是不是应该要考虑两帧的激活速率(这一帧和
{ //前一帧)。因为一个TTI的时间包含两帧。以后考虑这个问题。
case HALF_RATE : TTIMeanC2I+=3.0;
break;
case QUARTER_RATE : TTIMeanC2I+=6.0;
break;
case EIGHTH_RATE : TTIMeanC2I+=9.0;
break;
default : break;
}
for (int ii=1;ii<26;ii++)
//查找TTIMeanC2I在BLER vs C/I表中的位置
{
if (TTIMeanC2I<m_pfC2IIndex[ii])
break;
}
if (ii==26)
//TTIMeanC2I大于表中最大的C2I值
{
x2=m_pfC2IIndex[25];
y2=(float)log(m_pfBLER[25]);
x1=m_pfC2IIndex[24];
y1=(float)log(m_pfBLER[24]);
}
else
{
x2=m_pfC2IIndex[ii];
y2=(float)log(m_pfBLER[ii]);
x1=m_pfC2IIndex[ii-1];
y1=(float)log(m_pfBLER[ii-1]);
}
x=TTIMeanC2I;
y=((x2-x)*y1+(x-x1)*y2)/(x2-x1);
m_fTTIBLER=(float)exp(y);
//得到TTI内的误块率
return m_fTTIBLER;
}
//////////////////////////////////////////////////////////////////////////
//TITLE: OuterLoopPowerControl(外环功控函数)
//
//PARAMETERS:当前TTI是否有误块
//
//PURPOSE AND ALGORITHMS:
// 每个TTI结束后,根据误块情况调整功控目标值
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//DATE: 20040921
//
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::OuterLoopPowerControl(bool sign)
{
float fMinC2ITarget;//目标C/I下限
float fMaxC2ITarget;//目标C/I上限
fMinC2ITarget=(float)-25;
fMaxC2ITarget=(float)-19;
if(sign)
{
m_fC2ITarget-=(float)0.00505; //当前功率控制目标值下调0.00505dB
if(m_fC2ITarget<fMinC2ITarget) //如果超过了功率控制目标值的下限
m_fC2ITarget=fMinC2ITarget; //则将功率控制目标设为下限
}
else
{
m_fC2ITarget+=(float)0.5; //当前功率控制目标值上调0.5dB
if(m_fC2ITarget>fMaxC2ITarget) //如果超过了功率控制目标值的上限
m_fC2ITarget=fMaxC2ITarget; //则将功率控制目标设为上限
}
}
//////////////////////////////////////////////////////////////////////////
//TITLE: UpdateGeometry(Geometry更新函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 每次慢衰更新后,更新移动台的Geometry,并调用功控目标值确定函数
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//DATE: 20040921
//
//////////////////////////////////////////////////////////////////////////
/*void CVoiceMs::UpdateGeometry()
{
float fFastFading; //快衰值
float fOtherChannelPower; //本扇区其他信道的干扰,单位:mw
float fOtherSectorInterference; //从别的扇区来的干扰
float fIor2Ioc;
fFastFading=(m_aMonitorSector[m_iBestSectorIndex].fFastFading[0]
+m_aMonitorSector[m_iBestSectorIndex].fFastFading[1]
+m_aMonitorSector[m_iBestSectorIndex].fFastFading[2]
+m_aMonitorSector[m_iBestSectorIndex].fFastFading[3])/(float)4;
fOtherChannelPower=m_pServiceArea->GetSector(m_stBestSector)->
GetTxPower()*m_aMonitorSector[m_iBestSectorIndex].fPropagationLoss*fFastFading;
fOtherSectorInterference=m_aMonitorSector[m_iBestSectorIndex].fInterferenceFromOtherSector;
fIor2Ioc=fOtherChannelPower/fOtherSectorInterference;
fIor2Ioc=(float)(10*log10(fIor2Ioc));
DeterminePowerControlTarget(fIor2Ioc);
}*/
//////////////////////////////////////////////////////////////////////////
//TITLE: DeterminePowerControlTarget(功控目标值确定函数)
//
//PARAMETERS:Ior/Ioc值
//
//PURPOSE AND ALGORITHMS:
// 每次慢衰更新后,更新移动台的Geometry,并更新功控目标值
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//DATE: 20040921
//
//////////////////////////////////////////////////////////////////////////
/*void CVoiceMs::DeterminePowerControlTarget(float Ior2Ioc)
{
switch(m_iChannelType)
{
case 1 :
if(Ior2Ioc<-3)
m_fC2ITarget=(float)-17.3;
else if(Ior2Ioc<3)
m_fC2ITarget=(float)-24.2;
else if(Ior2Ioc<9)
m_fC2ITarget=(float)-24.6;
else
m_fC2ITarget=(float)-21.6;
break;
case 2 :
if(Ior2Ioc<-3)
m_fC2ITarget=(float)-18.1;
else if(Ior2Ioc<3)
m_fC2ITarget=(float)-25.5;
else if(Ior2Ioc<9)
m_fC2ITarget=(float)-22.5;
else
m_fC2ITarget=(float)-19.0;
break;
case 3 :
if(Ior2Ioc<-3)
m_fC2ITarget=(float)-22.7;
else if(Ior2Ioc<3)
m_fC2ITarget=(float)-24.4;
else if(Ior2Ioc<9)
m_fC2ITarget=(float)-23.2;
else
m_fC2ITarget=(float)-22.0;
break;
case 4 :
if(Ior2Ioc<-3)
m_fC2ITarget=(float)-22.0;
else if(Ior2Ioc<3)
m_fC2ITarget=(float)-24.1;
else if(Ior2Ioc<9)
m_fC2ITarget=(float)-23.5;
else
m_fC2ITarget=(float)-22.0;
break;
case 5 :
if(Ior2Ioc<-3)
m_fC2ITarget=(float)-24.6;
else if(Ior2Ioc<3)
m_fC2ITarget=(float)-24.9;
else if(Ior2Ioc<9)
m_fC2ITarget=(float)-24.7;
else
m_fC2ITarget=(float)-24.1;
break;
}
}*/
//////////////////////////////////////////////////////////////////////////
// 以下为get(),set()接口函数 //
//////////////////////////////////////////////////////////////////////////
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;
}
float CVoiceMs::GetVoiceActiveFactor()
{
return m_fVoiceActiveFactor;
}
void CVoiceMs::SetVoiceActiveFactor(float i_inputVoiceActiveFactor)
{
m_fVoiceActiveFactor=i_inputVoiceActiveFactor;
}
int CVoiceMs::GetTotalOutageWindow()
{
return m_iTotalOutageWindow;
}
void CVoiceMs::SetTotalOutageWindow(int i_inputTotalOutageWindow)
{
m_iTotalOutageWindow=i_inputTotalOutageWindow;
}
int CVoiceMs::GetTotalWindow()
{
return m_iTotalWindow;
}
void CVoiceMs::SetTotalWindow(int i_inputTotalWindow)
{
m_iTotalWindow=i_inputTotalWindow;
}
float CVoiceMs::GetOutageRatio()
{
return m_fOutageRatio;
}
void CVoiceMs::SetOutageRatio(float f_inputOutageRatio)
{
m_fOutageRatio=f_inputOutageRatio;
}
bool CVoiceMs::IsDropped()
{
return m_bIsDropped;
}
void CVoiceMs::SetIsDropped(bool flag)
{
m_bIsDropped=flag;
}
int CVoiceMs::GetDropTimer()
{
return m_iDropTimer;
}
void CVoiceMs::SetDropTimer(int a)
{
m_iDropTimer=a;
}
//end of CVoiceMs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -