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

📄 sdcreceive.cpp

📁 数字音频广播中三个子信道之一的SDC信道的解码和在pc机上的功能实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************\ * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik * Copyright (c) 2001 * * Author(s): *	Volker Fischer * * Description: *	SDC data stream decoding (receiver) * ****************************************************************************** * * 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 "SDC.h"/* Implementation *************************************************************/CSDCReceive::ERetStatus CSDCReceive::SDCParam(CVector<_BINARY>* pbiData,											  CParameter& Parameter){	/* Calculate length of data field in bytes	   (consistant to table 61 in (6.4.1)) */	const int iLengthDataFieldBytes = 		(int) ((_REAL) (Parameter.iNumSDCBitsPerSFrame - 20) / 8);	/* 20 bits from AFS index and CRC */	const int iUsefulBitsSDC = 20 + iLengthDataFieldBytes * 8;	/* CRC ------------------------------------------------------------------ */	/* Check the CRC of this data block */	CRCObject.Reset(16);	(*pbiData).ResetBitAccess();	/* Special treatment of SDC data stream: The CRC (Cyclic Redundancy	Check) field shall contain a 16-bit CRC calculated over the AFS	index coded in an 8-bit field (4 msbs are 0) and the data field.	4 MSBs from AFS-index. Insert four "0" in the data-stream */	const _BYTE byFirstByte = (_BYTE) (*pbiData).Separate(4);	CRCObject.AddByte(byFirstByte);	/* "- 4": Four bits already used, "/ SIZEOF__BYTE": We add bytes, not bits,	   "- 2": 16 bits for CRC at the end */	const int iNumBytesForCRCCheck = (iUsefulBitsSDC - 4) / SIZEOF__BYTE - 2;	for (int i = 0; i < iNumBytesForCRCCheck; i++)		CRCObject.AddByte((_BYTE) (*pbiData).Separate(SIZEOF__BYTE));	if (CRCObject.CheckCRC((*pbiData).Separate(16)) == TRUE)	{		/* CRC-check successful, extract data from SDC-stream --------------- */		int			iLengthOfBody;		_BOOLEAN	bError = FALSE;		/* Reset separation function */		(*pbiData).ResetBitAccess();		/* AFS index */		/* Reconfiguration index (not used by this application) */		(*pbiData).Separate(4);		/* Init bit count and total number of bits for body */		int			iBitsConsumed = 4; /* 4 bits for AFS index */		const int	iTotNumBitsWithoutCRC = iUsefulBitsSDC - 16;		/* Length of the body, excluding the initial 4 bits ("- 4"),		   measured in bytes ("/ 8").		   With this condition also the error code of the "Separate" function		   is checked! (implicitly)		   Check for: -end tag, -error, -no more data available */		while (((iLengthOfBody = (*pbiData).Separate(7)) != 0) &&			(bError == FALSE) && (iBitsConsumed < iTotNumBitsWithoutCRC))		{			/* Version flag */			_BOOLEAN bVersionFlag;			if ((*pbiData).Separate(1) == 0)				bVersionFlag = FALSE;			else				bVersionFlag = TRUE;			/* Data entity type */			/* First calculate number of bits for this entity ("+ 4" because of:			   "The body of the data entities shall be at least 4 bits long. The			   length of the body, excluding the initial 4 bits, shall be			   signalled by the header") */			const int iNumBitsEntity = iLengthOfBody * 8 + 4;			/* Call the routine for the signalled type */			switch ((*pbiData).Separate(4))			{			case 0: /* Type 0 */				bError = DataEntityType0(pbiData, iLengthOfBody, Parameter);				break;			case 1: /* Type 1 */				bError = DataEntityType1(pbiData, iLengthOfBody, Parameter);				break;			case 3: /* Type 3 */				bError = DataEntityType3(pbiData, iLengthOfBody, Parameter,					bVersionFlag);				break;			case 4: /* Type 4 */				bError = DataEntityType4(pbiData, iLengthOfBody, Parameter,					bVersionFlag);				break;			case 5: /* Type 5 */				bError = DataEntityType5(pbiData, iLengthOfBody, Parameter);				break;			case 7: /* Type 7 */				bError = DataEntityType7(pbiData, iLengthOfBody, Parameter,					bVersionFlag);				break;			case 8: /* Type 8 */				bError = DataEntityType8(pbiData, iLengthOfBody, Parameter);				break;			case 9: /* Type 9 */				bError = DataEntityType9(pbiData, iLengthOfBody, Parameter);				break;			default:				/* This type is not supported, delete all bits of this entity				   from the queue */				(*pbiData).Separate(iNumBitsEntity);			}			/* Count number of bits consumed (7 for length, 1 for version flag,			   4 for type = 12 plus actual entitiy body data) */			iBitsConsumed += 12 + iNumBitsEntity;		}		/* If error was detected, return proper error code */		if (bError == TRUE)			return SR_BAD_DATA;		else			return SR_OK; /* everything was ok */	}	else	{		/* Data is corrupted, do not use it. Return error code */		return SR_BAD_CRC;	}}/******************************************************************************\* Data entity Type 0 (Multiplex description data entity)					   *\******************************************************************************/_BOOLEAN CSDCReceive::DataEntityType0(CVector<_BINARY>* pbiData,									  const int iLengthOfBody,									  CParameter& Parameter){	CParameter::CMSCProtLev	MSCPrLe;	int						iLenPartA;	int						iLenPartB;	/* The receiver may determine the number of streams present in the multiplex	   by dividing the length field of the header by three (6.4.3.1) */	const int iNumStreams = iLengthOfBody / 3;	/* Check number of streams for overflow */	if (iNumStreams > MAX_NUM_STREAMS)		return TRUE;	/* Get protection levels */	/* Protection level for part A */	MSCPrLe.iPartA = (*pbiData).Separate(2);	/* Protection level for part B */	MSCPrLe.iPartB = (*pbiData).Separate(2);	/* Reset hierarchical flag (hierarchical present or not) */	_BOOLEAN bWithHierarch = FALSE;	/* Get stream parameters */	for (int i = 0; i < iNumStreams; i++)	{		/* In case of hirachical modulation stream 0 describes the protection		   level and length of hierarchical data */		if ((i == 0) &&			((Parameter.eMSCCodingScheme == CParameter::CS_3_HMSYM) ||			(Parameter.eMSCCodingScheme == CParameter::CS_3_HMMIX)))		{			/* Protection level for hierarchical */			MSCPrLe.iHierarch = (*pbiData).Separate(2);			bWithHierarch = TRUE;			/* rfu: these 10 bits shall be reserved for future use by the stream			   description field and shall be set to zero until they are			   defined */			if ((*pbiData).Separate(10) != 0)				return TRUE;			/* Data length for hierarchical */			iLenPartB = (*pbiData).Separate(12);			/* Set new parameters in global struct. Lenght of part A is zero			   with hierarchical modulation */			Parameter.SetStreamLen(i, 0, iLenPartB);		}		else		{			/* Data length for part A */			iLenPartA = (*pbiData).Separate(12);			/* Data length for part B */			iLenPartB = (*pbiData).Separate(12);			/* Set new parameters in global struct */			Parameter.SetStreamLen(i, iLenPartA, iLenPartB);		}	}	/* Set new parameters in global struct */	Parameter.SetMSCProtLev(MSCPrLe, bWithHierarch);	return FALSE;}/******************************************************************************\* Data entity Type 1 (Label data entity)									   *\******************************************************************************/_BOOLEAN CSDCReceive::DataEntityType1(CVector<_BINARY>* pbiData,									  const int iLengthOfBody,									  CParameter& Parameter){	/* Short ID (the short ID is the index of the service-array) */	const int iTempShortID = (*pbiData).Separate(2);	/* rfu: these 2 bits are reserved for future use and shall be set to zero	   until they are defined */	if ((*pbiData).Separate(2) != 0)		return TRUE;	/* Get label string ----------------------------------------------------- */	/* Check the following restriction to the length of label: "label: this is a	   variable length field of up to 64 bytes defining the label" */	if (iLengthOfBody <= 64)	{		/* Reset label string */		Parameter.Service[iTempShortID].strLabel = "";		/* Get all characters from SDC-stream */		for (int i = 0; i < iLengthOfBody; i++)		{			/* Get character */			const char cNewChar = (*pbiData).Separate(8);			/* Append new character */			Parameter.Service[iTempShortID].strLabel.append(&cNewChar, 1);		}		return FALSE;	}	else		return TRUE; /* error */}/******************************************************************************\* Data entity Type 3 (Alternative frequency signalling)                        *\******************************************************************************/_BOOLEAN CSDCReceive::DataEntityType3(CVector<_BINARY>* pbiData,									  const int iLengthOfBody,									  CParameter& Parameter,									  const _BOOLEAN bVersion){	int			i;	_BOOLEAN	bSyncMultplxFlag;	_BOOLEAN	bEnhanceFlag;	_BOOLEAN	bServRestrFlag;	_BOOLEAN	bRegionSchedFlag;	int			iServRestr;	/* Init number of frequency count */	int iNumFreqTmp = iLengthOfBody;	/* Init region ID and schedule ID with "not used" parameters */	int iRegionID = 0;	int iScheduleID = 0;	/* Synchronous Multiplex flag: this flag indicates whether the multiplex is	   broadcast synchronously */	switch ((*pbiData).Separate(1))	{	case 0: /* 0 */		/* Multiplex is not synchronous (different content and/or channel		   parameters and/or multiplex parameters and/or signal timing in target		   area) */		bSyncMultplxFlag = FALSE;		break;	case 1: /* 1 */		/* Multiplex is synchronous (identical content and channel parameters		   and multiplex parameters and signal timing in target area) */		bSyncMultplxFlag = TRUE;		break;	}	/* Layer flag: this flag indicates whether the frequencies given apply to	   the base layer of the DRM multiplex or to the enhancement layer */	switch ((*pbiData).Separate(1))	{	case 0: /* 0 */		/* Base layer */		bEnhanceFlag = FALSE;		break;	case 1: /* 1 */		/* Enhancement layer */		bEnhanceFlag = TRUE;		break;	}	/* Service Restriction flag: this flag indicates whether all or just some of	   the services of the tuned multiplex are available in the DRM multiplex on	   the frequencies */	switch ((*pbiData).Separate(1))	{	case 0: /* 0 */		/* All services in the tuned multiplex are available on the frequencies		   given */		bServRestrFlag = FALSE;		break;	case 1: /* 1 */		/* A restricted set of services are available on the frequencies		   given */		bServRestrFlag = TRUE;		break;	}	/* Region/Schedule flag: this field indicates whether the list of	   frequencies is restricted by region and/or schedule or not */	switch ((*pbiData).Separate(1))	{	case 0: /* 0 */		/* No restriction */		bRegionSchedFlag = FALSE;		break;	case 1: /* 1 */		/* Region and/or schedule applies to this list of frequencies */		bRegionSchedFlag = TRUE;		break;	}	/* Service Restriction field: this 8 bit field is only present if the	   Service Restriction flag is set to 1 */	if (bServRestrFlag == TRUE)	{		/* Short Id flags 4 bits. This field indicates, which services		   (identified by their Short Id) of the tuned DRM multiplex are carried		   in the DRM multiplex on the alternative frequencies by setting the		   corresponding bit to 1 */		iServRestr = (*pbiData).Separate(4);		/* rfa 4 bits. This field (if present) is reserved for future additions		   and shall be set to zero until it is defined */		if ((*pbiData).Separate(4) != 0)			return TRUE;		/* Remove one byte from frequency count */		iNumFreqTmp--;	}	/* Region/Schedule field: this 8 bit field is only present if the	   Region/Schedule flag is set to 1 */	if (bRegionSchedFlag == TRUE)	{		/* Region Id 4 bits. This field indicates whether the region is		   unspecified (value 0) or whether the alternative frequencies are		   valid just in certain geographic areas, in which case it carries		   the Region Id (value 1 to 15). The region may be described by one or		   more "Alternative frequency signalling: Region definition data entity		   - type 7" with this Region Id */		iRegionID = (*pbiData).Separate(4); 		/* Schedule Id 4 bits. This field indicates whether the schedule is		   unspecified (value 0) or whether the alternative frequencies are		   valid just at certain times, in which case it carries the Schedule Id		   (value 1 to 15). The schedule is described by one or more		   "Alternative frequency signalling: Schedule definition data entity		   - type 4" with this Schedule Id */		iScheduleID = (*pbiData).Separate(4);		/* Remove one byte from frequency count */		iNumFreqTmp--;	}	/* Check for error (length of body must be so long to include Service	   Restriction field and Region/Schedule field, also check that	   remaining number of bytes is devidable by 2 since we read 16 bits) */	if ((iNumFreqTmp < 0) || (iNumFreqTmp % 2 != 0))		return TRUE;	/* n frequencies: this field carries n 16 bit fields. n is in the	   range 1 to 16. The number of frequencies, n, is determined from the	   length field of the header and the value of the Service Restriction flag	   and the Region/Schedule flag */	const int iNumFreq = iNumFreqTmp / 2; /* 16 bits are read */	CVector<int> veciFrequencies(iNumFreq);	for (i = 0; i < iNumFreq; i++)	{		/* rfu 1 bit. This field is reserved for future use of the frequency		   value field and shall be set to zero until defined */		if ((*pbiData).Separate(1) != 0)			return TRUE;		/* Frequency value 15 bits. This field is coded as an unsigned integer		   and gives the frequency in kHz */		veciFrequencies[i] = (*pbiData).Separate(15);	}	/* Now, set data in global struct */	/* Enhancement layer is not supported */	if (bEnhanceFlag == FALSE)	{		/* Check the version flag */		if (bVersion != Parameter.AltFreqSign.bVersionFlag)		{			/* If version flag is wrong, reset everything and save flag */			Parameter.AltFreqSign.Reset();			Parameter.AltFreqSign.bVersionFlag = bVersion;		}		/* Create temporary object and reset for initialization */		CParameter::CAltFreqSign::CAltFreq AltFreq;		AltFreq.Reset();		/* Set some parameters */		AltFreq.bIsSyncMultplx = bSyncMultplxFlag;		AltFreq.iRegionID = iRegionID;		AltFreq.iScheduleID = iScheduleID;		/* Set Service Restriction */		if (bServRestrFlag == TRUE)		{			/* The first bit (msb) refers to Short Id 3, while the last bit			   (lsb) refers to Short Id 0 of the tuned DRM multiplex */			for (i = 0; i < MAX_NUM_SERVICES; i++)			{				/* Mask last bit (lsb) */				AltFreq.veciServRestrict[i] = iServRestr & 1;

⌨️ 快捷键说明

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