⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvoicems.cpp

📁 此程序为wcdma系统当中ftp/video业务模型的c++程序仿真 通过此程序 能得到此两种业务在多种条件下的吞吐量和无码率的性能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////
//                             WCDMA TEAM                        //
//                      BUPT Radio Research Center               //
///////////////////////////////////////////////////////////////////
//
//                          CVoiceMs.cpp
//
//////////////////////////////////////////////////////////////////////
//                                                                  //
//               话音移动台CVoiceMs的成员函数的声明                 //
//                                                                  //
// Written by:     李晶                                             //
// Date:      200404                                                // 
//                                                                  //
//////////////////////////////////////////////////////////////////////


#include "CVoiceMs.h"
#include "systemsim.h"
#include "iostream.h"
#include "sys_random.h"
#include "CMsManager.h"
#include "CLinkPrediction.h"


//////////////////////////////////////////////////////////////////////////
//				构造函数							
//                          将各属性赋予初始值							
//////////////////////////////////////////////////////////////////////////
CVoiceMs::CVoiceMs()
{
}
//end of CVoiceMs()


//////////////////////////////////////////////////////////////////////////
//				析构函数								
//			      释放内存空间								
//////////////////////////////////////////////////////////////////////////
CVoiceMs::~CVoiceMs()
{
	Clean();
}
//end of ~CVoiceMs()


//////////////////////////////////////////////////////////////////////////
//TITLE:      VoiceInitialization(话音移动台初始化函数)				        
//
//PARAMETERS:NULL              
//
//PURPOSE AND ALGORITHMS:
//            初始化m_iServiceLength、m_eUsertype、m_iUnsatisfiedTimer、
//            m_iDropTimer等参数 
//            实际上,每一次初始化话音移动台的时候,都是先调用基类的
//            MobileInitialization函数,再调用此函数进行初始化    
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//            CMarkovVoice::initRan()
//            CMobile::ObtainBestSector()
//            CMobile::InitActiveSet()
//            CMobile::ObtainC2I()    
//                                                                
//////////////////////////////////////////////////////////////////////////
void   CVoiceMs::VoiceInitialization(CLinkPrediction *pLinkPrediction)
{
//Modified by Li Jing,20040713	
	m_pLinkPrediction = pLinkPrediction;//指向链路预测对象
	POSITION pos;
	pos=m_pLinkPrediction->m_pstRateTable.GetHeadPosition();
	RATE2CI_TYPE *pRate = new RATE2CI_TYPE;
	pRate=m_pLinkPrediction->m_pstRateTable.GetNext(pos);

	while ((pos!=NULL)&&(pRate->fDataRate!=(float)12.2||pRate->iChannelType!=m_iChannelType))
	{
		pRate=m_pLinkPrediction->m_pstRateTable.GetNext(pos);
    }
	m_pstTFI=pRate->pTFI; 
	m_fC2ITarget=pRate->fTargetC2I;

	m_eUsertype=voice;                  //初始化m_eUsertype为voice,表示为话音用户

	m_bIsDropped=false;
	m_iDropTimer=0;

	m_fVoiceActiveFactor=m_pMsManager->m_fVoiceActiveFactor;
	                                    //话音激活因子初始化
	
	m_iServiceTime=0;                   //已经服务的时长清0
	m_iServiceLength=0;                 //用slot数表示的已经服务的时长
	
	m_iTotalOutageWindow=0;             //中断的窗口数清为0
	m_iTotalWindow=0;                   //总的通话窗口清为0
	m_fOutageRatio=0;                   //中断率清为0
	m_fC2IThreshold=m_pMsManager->m_fC2IThreshold;
	
	//at present,consider full_rate only
	m_fFwdCurrentActiveFactor=1.0;      //本slot话音激活因子为1
	m_fFwdLastActiveFactor=1.0;         //上一slot话音激活因子为1
	m_iFwdFrameRate=FULL_RATE;


	m_pfC2IIndex=&(m_pMsManager->m_fC2IIndex[0]);      //C/I指针
	switch(m_iChannelType)          //determine the C/I target
	{
		case 1 :            
		//MsVelocity=3
			m_pfBLER=&(m_pMsManager->m_fBLER_1[0]);
			break;
		case 2 :
		//MsVelocity=10
			m_pfBLER=&(m_pMsManager->m_fBLER_2[0]);
			break; 
		case 3 :
		//MsVelocity=30 
			m_pfBLER=&(m_pMsManager->m_fBLER_3[0]);
			break;
		case 4 : 
		//MsVelocity=120
			m_pfBLER=&(m_pMsManager->m_fBLER_4[0]);
			break;
	    case 5 :           
		//MsVelocity=0
			m_pfBLER=&(m_pMsManager->m_fBLER_5[0]); 
			break;			
	}
		
	ObtainBestSector();                 //在移动台的监测集中根据导频情况找出最佳扇区
	InitActiveSet();                    //初始化激活集。话音移动台与数据DCH状态的移动台的激活集初始化过程是相同的,而
                                            //DSCH状态的移动台则不要初始化激活集。所以这个函数在实现时要加以区分!
                                            //另外,初始化激活集与2000中有较大的区别:现在初始化时移动台只是与最佳扇区进行
                                            //接纳控制,也就是说初始化时最多只有最佳扇区可能进入激活集
	ObtainC2I();                        //获得当前时隙的C/I

}



//////////////////////////////////////////////////////////////////////////
//TITLE:      PowerControl(功率控制函数)				        
//
//PARAMETERS:NULL              
//
//PURPOSE AND ALGORITHMS:
//            功率控制函数,根据计算得到的C/I与功率控制目标C/I的关系,调整
//            激活集内各个扇区的发射功率。需要考虑功控误差,暂时不考虑功控时延
//            (在基类中用的是纯虚函数,此处给出实现)   
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//                                                                
//////////////////////////////////////////////////////////////////////////
void   CVoiceMs::PowerControl()
{                                 
	/*	CStdioFile f;
	char buf[50];
	char FileName[40];
    CString sp;
	sp="Exception.txt";
	strcpy(FileName,sp);*/

//Modified by Li Jing,20041012
	float fPowerDelta_T;
	float fPowerDelta_R;

    float fPowerIncrement;
	float fMinTrafficPower;       //业务信道最小值,单位:mw
	float fTotalC2I=0;            //总的C/I,初值为零
	float frv;                    //(0,1)分布的随机数
	float fOldTrafficPower;       //功控前业务信道功率,单位:mW
	float fTempTrafficPower;      //业务信道功率,单位:dBm
	float fTargetC2I;
	POSITION posTemp;             //临时位置指针
	CSector* pTempSector=NULL;    //临时扇区指针
	bool  bDecision;
    
	fPowerDelta_T=(float)(-1*m_pMsManager->m_fPowerControlStep);
    
	fTotalC2I=m_fC2I;             //当前时隙的C/I
	
	fTargetC2I=m_fC2ITarget;
	
	if(fTotalC2I<=fTargetC2I) 
	//如果当前时隙的C/I小于目标C/I
		fPowerDelta_T*=(-1);//调整步长为正(增加)

/*	if(m_iMsID==90)
	{
		    if(!f.Open(FileName,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
			{
	            #ifdef _DEBUG
	    	        afxDump<<"Unable to open file"<<"\n";	//exception handling
	            #endif
			}
            f.SeekToEnd();
	        //使文件指针指向文件尾部,输出数据可以在文件尾部接着写
	        f.WriteString("\nthe mobile has done one power control");
	}*/
	
	posTemp=m_ActiveSetList.GetHeadPosition();
	//取得链表头,并令临时指针指向链表头
	while(posTemp!=NULL)           //到达链表尾则结束循环
	{
		pTempSector=
			m_pServiceArea->GetSector(m_ActiveSetList.GetAt(posTemp)->stSectorID);
		    //获得激活扇区的指针
		fOldTrafficPower=m_ActiveSetList.GetAt(posTemp)->fTrafficPower;
		    //retrieve the transmit power before the power control
		fTempTrafficPower=(float)(10*log10(fOldTrafficPower));

		frv=xUniform(0.0,1.0);//产生一个(0,1)分布的随机数,用来模拟功控误差
	    if(frv<m_pMsManager->m_fBEROfPC)
	    //如果随机数小于功控比特差错概率
		    fPowerDelta_R=fPowerDelta_T*(-1);//功控出错,原来的加变成了减
		else
			fPowerDelta_R=fPowerDelta_T;

		fTempTrafficPower+=fPowerDelta_R;   //调整此目标扇区对此移动台业务信道功率值
        fTempTrafficPower=(float)(pow(10,(fTempTrafficPower/10)));

		if(fTempTrafficPower>pTempSector->GetMaxPower()
		    *m_pMsManager->m_fMaxFractionOfTrafficPower)      
		//如果业务信道功率大于最大值
			fTempTrafficPower=
				pTempSector->GetMaxPower()*m_pMsManager->
				m_fMaxFractionOfTrafficPower;       
			//就将业务信道功率置为最大值
		fMinTrafficPower=
			(float)((pTempSector->GetMaxPower()*
			m_pMsManager->m_fMaxFractionOfTrafficPower)
			/pow(10,(m_pMsManager->m_fDynamicRangeOfTrafficPower/10)));  
		//将dB转化为mw
		if(fTempTrafficPower<fMinTrafficPower)
		//如果业务信道功率小于动态范围
		    fTempTrafficPower=fMinTrafficPower;       
			//就将业务信道功率置为最小值(动态范围)
		
		fPowerIncrement=fTempTrafficPower-fOldTrafficPower;
		//retrieve the power increment of the power control
		bDecision=pTempSector->PowerControlDecision(fPowerIncrement);
		if(bDecision)
		{
		    m_ActiveSetList.GetAt(posTemp)->fTrafficPower=fTempTrafficPower;
		
		    pTempSector->VoicePowerCumulate(fPowerIncrement);
		    //add the voice power increment to the active sector
		    pTempSector->TxPowerUpdate();
            //update the total power of the sector
		}
        
/*		if(m_iMsID==90)
		{
            f.WriteString("\nthe active sector's index in monitor is:");
			_gcvt(m_ActiveSetList.GetAt(posTemp)->iIndexInMonitor,8,buf);
	        f.WriteString(buf);

			f.WriteString("\nthe active sector's transmission power is:");
			_gcvt(m_ActiveSetList.GetAt(posTemp)->fTrafficPower,8,buf);
	        f.WriteString(buf);

		}*/

		m_ActiveSetList.GetNext(posTemp); 
		//获得链表的下一个激活扇区结构
	}
	
/*	if(m_iMsID==90)
	{
		f.Close();
	}*/
}



//////////////////////////////////////////////////////////////////////////
//TITLE:      SetVoiceActivity(话音激活特性设置函数)				        
//
//PARAMETERS:NULL              
//
//PURPOSE AND ALGORITHMS:
//            根据话音激活因子,设置话音激活标志   
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//                                                                
//////////////////////////////////////////////////////////////////////////
/*void   CVoiceMs::SetVoiceActivity()
{                                   
	float fDif;
	m_fFwdLastActiveFactor=m_fFwdCurrentActiveFactor;
	if(m_iSlotCount%15==1)
	//每一个帧,更新一次激活因子
	{
		m_iFwdFrameRate=m_cFwdMarkovState.GetNextState()%4;
		switch(m_iFwdFrameRate)
		{
			case FULL_RATE : m_fFwdCurrentActiveFactor=1.0;
			                 fDif=0.0;
				 break;
			case HALF_RATE : m_fFwdCurrentActiveFactor=0.5;
			                 fDif=3.0;
				 break;
			case QUARTER_RATE : m_fFwdCurrentActiveFactor=0.25;
			                    fDif=6.0;
				 break;
			case EIGHTH_RATE : m_fFwdCurrentActiveFactor=0.125;
			                   fDif=9.0;
				 break;
		}
		
		m_fC2IThreshold=m_pMsManager->m_fC2IThreshold-fDif;
		
		switch(m_iChannelType)
		{
		        case 1 : m_fC2ITarget=(float)C2ITargetForVoice1-fDif;
		         break;
		        case 2 : m_fC2ITarget=(float)C2ITargetForVoice2-fDif;
		         break;
		        case 3 : m_fC2ITarget=(float)C2ITargetForVoice3-fDif;
		         break;
		        case 4 : m_fC2ITarget=(float)C2ITargetForVoice4-fDif;
		         break;
		        case 5 : m_fC2ITarget=(float)C2ITargetForVoice5-fDif;
		         break;
		}
		                
		
	}
}
*/


//////////////////////////////////////////////////////////////////////////
//TITLE:      IsServiceOver(服务时长到时的判断函数)				        
//
//PARAMETERS:NULL              
//
//PURPOSE AND ALGORITHMS:
//            判断服务时长是否到时,到时返回TRUE   
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//                                                                
//////////////////////////////////////////////////////////////////////////
bool   CVoiceMs::IsServiceOver()
{
	if(m_iServiceLength>=MeanCallTime*1500)      //如果服务到时
		return true;             //返回true
	else 
		return false;            //返回false
}



//////////////////////////////////////////////////////////////////////////
//TITLE:      UpdateActiveSetPower(更新激活集中激活扇区的功率函数)				        
//
//PARAMETERS:NULL              
//
//PURPOSE AND ALGORITHMS:
//            将移动台激活集中的各个扇区各自的话音功率进行累加,调用函数:
//            CMsManager::UpdateSectorVoicePower()将所有的话音移动台
//            进行循环一次后,实际上就将每一个扇区发射的话音总功率累加起来了  
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//            CServiceArea::GetSector()
//            CSector::VoicePowerCumulate()
//
//CALLED FUNCTIONS:
//            CMsManager::UpdateSectorVoicePower()
//
//NOTES:      这个函数还是放在话音移动台中实现,因为数据移动台不调用这个函数
//                                                    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -