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

📄 fac.cpp

📁 Dream.exe soft source (Visual C++)
💻 CPP
字号:
/******************************************************************************\
 * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
 * Copyright (c) 2001
 *
 * Author(s):
 *	Volker Fischer
 *
 * Description:
 *	FAC
 *
 ******************************************************************************
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later 
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
\******************************************************************************/

#include "FAC.h"


/* Implementation *************************************************************/
/******************************************************************************\
* CFACTransmit																   *
\******************************************************************************/
void CFACTransmit::FACParam(CVector<_BINARY>* pbiFACData, CParameter& Parameter)
{
	uint32_t	iRfuDummy;
	int			iCurShortID;
	static int	FACRepetitionCounter = 0;

	/* Reset enqueue function */
	(*pbiFACData).ResetBitAccess();


	/* Put FAC parameters on stream */
	/* Channel parameters --------------------------------------------------- */
	/* Base/Enhancement flag, set it to base which is decodable by all DRM
	   receivers */
	(*pbiFACData).Enqueue(0 /* 0 */, 1);

	/* Identity */
	/* Manage index of FAC block in super-frame */
	switch (Parameter.iFrameIDTransm)
	{
	case 0:
		/* Assuming AFS is valid (AFS not used here), if AFS is not valid, the
		   parameter must be 3 (11) */
		(*pbiFACData).Enqueue(3 /* 11 */, 2);
		break;

	case 1:
		(*pbiFACData).Enqueue(1 /* 01 */, 2);
		break;

	case 2:
		(*pbiFACData).Enqueue(2 /* 10 */, 2);
		break;
	}

	/* Spectrum occupancy */
	switch (Parameter.GetSpectrumOccup())
	{
	case SO_0:
		(*pbiFACData).Enqueue(0 /* 0000 */, 4);
		break;

	case SO_1:
		(*pbiFACData).Enqueue(1 /* 0001 */, 4);
		break;

	case SO_2:
		(*pbiFACData).Enqueue(2 /* 0010 */, 4);
		break;

	case SO_3:
		(*pbiFACData).Enqueue(3 /* 0011 */, 4);
		break;

	case SO_4:
		(*pbiFACData).Enqueue(4 /* 0100 */, 4);
		break;

	case SO_5:
		(*pbiFACData).Enqueue(5 /* 0101 */, 4);
		break;
	}

	/* Interleaver depth flag */
	switch (Parameter.eSymbolInterlMode)
	{
	case CParameter::SI_LONG:
		(*pbiFACData).Enqueue(0 /* 0 */, 1);
		break;

	case CParameter::SI_SHORT:
		(*pbiFACData).Enqueue(1 /* 1 */, 1);
		break;
	}

	/* MSC mode */
	switch (Parameter.eMSCCodingScheme)
	{
	case CParameter::CS_3_SM:
		(*pbiFACData).Enqueue(0 /* 00 */, 2);
		break;

	case CParameter::CS_3_HMMIX:
		(*pbiFACData).Enqueue(1 /* 01 */, 2);
		break;

	case CParameter::CS_3_HMSYM:
		(*pbiFACData).Enqueue(2 /* 10 */, 2);
		break;

	case CParameter::CS_2_SM:
		(*pbiFACData).Enqueue(3 /* 11 */, 2);
		break;
	}

	/* SDC mode */
	switch (Parameter.eSDCCodingScheme)
	{
	case CParameter::CS_2_SM:
		(*pbiFACData).Enqueue(0 /* 0 */, 1);
		break;

	case CParameter::CS_1_SM:
		(*pbiFACData).Enqueue(1 /* 1 */, 1);
		break;
	}

	/* Number of services */
	/* Use Table */
	(*pbiFACData).Enqueue(iTableNumOfServices[Parameter.iNumAudioService]
		[Parameter.iNumDataService], 4);

	/* Reconfiguration index (not used) */
	(*pbiFACData).Enqueue((uint32_t) 0, 3);

	/* rfu */
	iRfuDummy = 0;
	(*pbiFACData).Enqueue(iRfuDummy, 2);


	/* Service parameters --------------------------------------------------- */
	/* Transmit service-information of service signalled in the FAC-repetition
	   array */
	iCurShortID = FACRepetition[FACRepetitionCounter];
	FACRepetitionCounter++;
	if (FACRepetitionCounter == FACNumRep)
		FACRepetitionCounter = 0;

	/* Service identifier */
	(*pbiFACData).Enqueue(Parameter.Service[iCurShortID].iServiceID, 24);

	/* Short ID */
	(*pbiFACData).Enqueue((uint32_t) iCurShortID, 2);

	/* CA indication */
	switch (Parameter.Service[iCurShortID].eCAIndication)
	{
	case CParameter::CA_NOT_USED:
		(*pbiFACData).Enqueue(0 /* 0 */, 1);
		break;

	case CParameter::CA_USED:
		(*pbiFACData).Enqueue(1 /* 1 */, 1);
		break;
	}

	/* Language */
	(*pbiFACData).Enqueue( 
		(uint32_t) Parameter.Service[iCurShortID].iLanguage, 4);

	/* Audio/Data flag */
	switch (Parameter.Service[iCurShortID].eAudDataFlag)
	{
	case CParameter::SF_AUDIO:
		(*pbiFACData).Enqueue(0 /* 0 */, 1);
		break;

	case CParameter::SF_DATA:
		(*pbiFACData).Enqueue(1 /* 1 */, 1);
	}
	
	/* Service descriptor */
	(*pbiFACData).Enqueue( 
		(uint32_t) Parameter.Service[iCurShortID].iServiceDescr, 5);

	/* Rfa */
	iRfuDummy = 0;
	(*pbiFACData).Enqueue(iRfuDummy, 7);


	/* CRC ------------------------------------------------------------------ */
	/* Calculate the CRC and put at the end of the stream */
	CRCObject.Reset(8);

	(*pbiFACData).ResetBitAccess();

	for (int i = 0; i < NUM_FAC_BITS_PER_BLOCK / SIZEOF__BYTE - 1; i++)
		CRCObject.AddByte((_BYTE) (*pbiFACData).Separate(SIZEOF__BYTE));

	/* Now, pointer in "enqueue"-function is back at the same place, 
	   add CRC */
	(*pbiFACData).Enqueue(CRCObject.GetCRC(), 8);
}

void CFACTransmit::Init(CParameter& Parameter)
{
	int				i;
	CVector<int>	veciActServ;

	/* Get active services */
	Parameter.GetActiveServices(veciActServ);
	const int iTotNumServices = veciActServ.Size();

	/* Check how many audio and data services present */
	CVector<int>	veciAudioServ(0);
	CVector<int>	veciDataServ(0);
	int				iNumAudio = 0;
	int				iNumData = 0;

	for (i = 0; i < iTotNumServices; i++)
	{
		if (Parameter.Service[veciActServ[i]].
			eAudDataFlag ==	CParameter::SF_AUDIO)
		{
			veciAudioServ.Add(i);
			iNumAudio++;
		}
		else
		{
			veciDataServ.Add(i);
			iNumData++;
		}
	}


	/* Now check special cases which are defined in 6.3.6-------------------- */
	/* If we have only data or only audio services. When all services are of
	   the same type (e.g. all audio or all data) then the services shall be
	   signalled sequentially */
	if ((iNumAudio == iTotNumServices) || (iNumData == iTotNumServices))
	{
		/* Init repetion vector */
		FACNumRep = iTotNumServices;
		FACRepetition.Init(FACNumRep);

		for (i = 0; i < FACNumRep; i++)
			FACRepetition[i] = veciActServ[i];
	}
	else
	{
		/* Special cases according to Table 60 (Service parameter repetition
		   patterns for mixtures of audio and data services) */
		if (iNumAudio == 1)
		{
			if (iNumData == 1)
			{
				/* Init repetion vector */
				FACNumRep = 5;
				FACRepetition.Init(FACNumRep);

				/* A1A1A1A1D1 */
				FACRepetition[0] = veciAudioServ[0];
				FACRepetition[1] = veciAudioServ[0];
				FACRepetition[2] = veciAudioServ[0];
				FACRepetition[3] = veciAudioServ[0];
				FACRepetition[4] = veciDataServ[0];
			}
			else if (iNumData == 2)
			{
				/* Init repetion vector */
				FACNumRep = 10;
				FACRepetition.Init(FACNumRep);

				/* A1A1A1A1D1A1A1A1A1D2 */
				FACRepetition[0] = veciAudioServ[0];
				FACRepetition[1] = veciAudioServ[0];
				FACRepetition[2] = veciAudioServ[0];
				FACRepetition[3] = veciAudioServ[0];
				FACRepetition[4] = veciDataServ[0];
				FACRepetition[5] = veciAudioServ[0];
				FACRepetition[6] = veciAudioServ[0];
				FACRepetition[7] = veciAudioServ[0];
				FACRepetition[8] = veciAudioServ[0];
				FACRepetition[9] = veciDataServ[1];
			}
			else /* iNumData == 3 */
			{
				/* Init repetion vector */
				FACNumRep = 15;
				FACRepetition.Init(FACNumRep);

				/* A1A1A1A1D1A1A1A1A1D2A1A1A1A1D3 */
				FACRepetition[0] = veciAudioServ[0];
				FACRepetition[1] = veciAudioServ[0];
				FACRepetition[2] = veciAudioServ[0];
				FACRepetition[3] = veciAudioServ[0];
				FACRepetition[4] = veciDataServ[0];
				FACRepetition[5] = veciAudioServ[0];
				FACRepetition[6] = veciAudioServ[0];
				FACRepetition[7] = veciAudioServ[0];
				FACRepetition[8] = veciAudioServ[0];
				FACRepetition[9] = veciDataServ[1];
				FACRepetition[10] = veciAudioServ[0];
				FACRepetition[11] = veciAudioServ[0];
				FACRepetition[12] = veciAudioServ[0];
				FACRepetition[13] = veciAudioServ[0];
				FACRepetition[14] = veciDataServ[2];
			}
		}
		else if (iNumAudio == 2)
		{
			if (iNumData == 1)
			{
				/* Init repetion vector */
				FACNumRep = 5;
				FACRepetition.Init(FACNumRep);

				/* A1A2A1A2D1 */
				FACRepetition[0] = veciAudioServ[0];
				FACRepetition[1] = veciAudioServ[1];
				FACRepetition[2] = veciAudioServ[0];
				FACRepetition[3] = veciAudioServ[1];
				FACRepetition[4] = veciDataServ[0];
			}
			else /* iNumData == 2 */
			{
				/* Init repetion vector */
				FACNumRep = 10;
				FACRepetition.Init(FACNumRep);

				/* A1A2A1A2D1A1A2A1A2D2 */
				FACRepetition[0] = veciAudioServ[0];
				FACRepetition[1] = veciAudioServ[1];
				FACRepetition[2] = veciAudioServ[0];
				FACRepetition[3] = veciAudioServ[1];
				FACRepetition[4] = veciDataServ[0];
				FACRepetition[5] = veciAudioServ[0];
				FACRepetition[6] = veciAudioServ[1];
				FACRepetition[7] = veciAudioServ[0];
				FACRepetition[8] = veciAudioServ[1];
				FACRepetition[9] = veciDataServ[1];
			}
		}
		else /* iNumAudio == 3 */
		{
			/* Init repetion vector */
			FACNumRep = 7;
			FACRepetition.Init(FACNumRep);

			/* A1A2A3A1A2A3D1 */
			FACRepetition[0] = veciAudioServ[0];
			FACRepetition[1] = veciAudioServ[1];
			FACRepetition[2] = veciAudioServ[2];
			FACRepetition[3] = veciAudioServ[0];
			FACRepetition[4] = veciAudioServ[1];
			FACRepetition[5] = veciAudioServ[2];
			FACRepetition[6] = veciDataServ[0];
		}
	}
}


/******************************************************************************\
* CFACReceive																   *
\******************************************************************************/
_BOOLEAN CFACReceive::FACParam(CVector<_BINARY>* pbiFACData, 
							   CParameter& Parameter)
{
/* 
	First get new data from incoming data stream, then check if the new
	parameter differs from the old data stored in the receiver. If yes, init
	the modules to the new parameter 
*/
	uint32_t	iTempServiceID;
	int			iTempShortID;

	/* CRC ------------------------------------------------------------------ */
	/* Check the CRC of this data block */
	CRCObject.Reset(8);

	(*pbiFACData).ResetBitAccess();

	for (int i = 0; i < NUM_FAC_BITS_PER_BLOCK / SIZEOF__BYTE - 1; i++)
		CRCObject.AddByte((_BYTE) (*pbiFACData).Separate(SIZEOF__BYTE));

	if (CRCObject.CheckCRC((*pbiFACData).Separate(8)) == TRUE)
	{
		/* CRC-check successful, extract data from FAC-stream */
		/* Reset separation function */
		(*pbiFACData).ResetBitAccess();


		/* Channel parameters ----------------------------------------------- */
		/* Base/Enhancement flag (not used) */
		(*pbiFACData).Separate(1);
		
		/* Identity */
		switch ((*pbiFACData).Separate(2))
		{
		case 0: /* 00 */
			Parameter.iFrameIDReceiv = 0;
			break;

		case 1: /* 01 */
			Parameter.iFrameIDReceiv = 1;
			break;

		case 2: /* 10 */
			Parameter.iFrameIDReceiv = 2;
			break;

		case 3: /* 11 */
			Parameter.iFrameIDReceiv = 0;
			break;
		}

		/* Spectrum occupancy */
		switch ((*pbiFACData).Separate(4))
		{
		case 0: /* 0000 */
			Parameter.SetSpectrumOccup(SO_0);
			break;

		case 1: /* 0001 */
			Parameter.SetSpectrumOccup(SO_1);
			break;

		case 2: /* 0010 */
			Parameter.SetSpectrumOccup(SO_2);
			break;

		case 3: /* 0011 */
			Parameter.SetSpectrumOccup(SO_3);
			break;

		case 4: /* 0100 */
			Parameter.SetSpectrumOccup(SO_4);
			break;

		case 5: /* 0101 */
			Parameter.SetSpectrumOccup(SO_5);
			break;
		}

		/* Interleaver depth flag */
		switch ((*pbiFACData).Separate(1))
		{
		case 0: /* 0 */
			Parameter.SetInterleaverDepth(CParameter::SI_LONG);
			break;

		case 1: /* 1 */
			Parameter.SetInterleaverDepth(CParameter::SI_SHORT);
			break;
		}

		/* MSC mode */
		switch ((*pbiFACData).Separate(2))
		{
		case 0: /* 00 */
			Parameter.SetMSCCodingScheme(CParameter::CS_3_SM);
			break;

		case 1: /* 01 */
			Parameter.SetMSCCodingScheme(CParameter::CS_3_HMMIX);
			break;

		case 2: /* 10 */
			Parameter.SetMSCCodingScheme(CParameter::CS_3_HMSYM);
			break;

		case 3: /* 11 */
			Parameter.SetMSCCodingScheme(CParameter::CS_2_SM);
			break;
		}

		/* SDC mode */
		switch ((*pbiFACData).Separate(1))
		{
		case 0: /* 0 */
			Parameter.SetSDCCodingScheme(CParameter::CS_2_SM);
			break;

		case 1: /* 1 */
			Parameter.SetSDCCodingScheme(CParameter::CS_1_SM);
			break;
		}
			
		/* Number of services */
		/* Search table for entry */
		int iNumServTabEntry = (*pbiFACData).Separate(4);
		for (int i = 0; i < 5; i++)
			for (int j = 0; j < 5; j++)
				if (iNumServTabEntry == iTableNumOfServices[i][j])
					Parameter.SetNumOfServices(i, j);

		/* Reconfiguration index (not used, yet) */
		(*pbiFACData).Separate(3);

		/* rfu */
		/* Do not use rfu */
		(*pbiFACData).Separate(2);


		/* Service parameters ----------------------------------------------- */
		/* Service identifier */
		iTempServiceID = (*pbiFACData).Separate(24);

		/* Short ID (the short ID is the index of the service-array) */
		iTempShortID = (*pbiFACData).Separate(2);

		/* Set service identifier */
		Parameter.SetServID(iTempShortID, iTempServiceID);

		/* CA indication */
		switch ((*pbiFACData).Separate(1))
		{
		case 0: /* 0 */
			Parameter.Service[iTempShortID].eCAIndication = 
				CParameter::CA_NOT_USED;
			break;

		case 1: /* 1 */
			Parameter.Service[iTempShortID].eCAIndication = 
				CParameter::CA_USED;
			break;
		}

		/* Language */
		Parameter.Service[iTempShortID].iLanguage = (*pbiFACData).Separate(4);

		/* Audio/Data flag */
		switch ((*pbiFACData).Separate(1))
		{
		case 0: /* 0 */
			Parameter.SetAudDataFlag(iTempShortID, CParameter::SF_AUDIO);
			break;

		case 1: /* 1 */
			Parameter.SetAudDataFlag(iTempShortID, CParameter::SF_DATA);
			break;
		}

		/* Service descriptor */
		Parameter.Service[iTempShortID].iServiceDescr = 
			(*pbiFACData).Separate(5);

		/* Rfa */
		/* Do not use Rfa */
		(*pbiFACData).Separate(7);

		/* CRC is ok, return TRUE */
		return TRUE;
	}
	else
	{
		/* Data is corrupted, do not use it. Return failure as FALSE */
		return FALSE;
	}
}

⌨️ 快捷键说明

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