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

📄 sdctransmit.cpp

📁 数字音频广播中三个子信道之一的SDC信道的解码和在pc机上的功能实现
💻 CPP
字号:
/******************************************************************************\ * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik * Copyright (c) 2001 * * Author(s): *	Volker Fischer * * Description: *	SDC * ****************************************************************************** * * 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 *************************************************************/void CSDCTransmit::SDCParam(CVector<_BINARY>* pbiData, CParameter& Parameter){/* 	Put SDC parameters on a stream */	int					i;	int					iSize;	CVector<_BINARY>	vecbiData;	/* 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;	/* "- 20" for the AFS-index and CRC! */	const int iMaxNumBitsDataBlocks = iUsefulBitsSDC - 20;	/* Reset enqueue function */	(*pbiData).ResetBitAccess();	/* SDC Header ----------------------------------------------------------- */	/* AFS index (not used by this application, insert a "1" */	(*pbiData).Enqueue((uint32_t) 1, 4);	/* Data Entities -------------------------------------------------------- */	/* Init bit-count */	int iNumUsedBits = 0;// Choose types, TEST. Send only important types for this test!// TODO: test, if SDC block is long enough for all types!	/* Type 0 */	DataEntityType0(vecbiData, Parameter);	// TODO: nicer solution	iSize = vecbiData.Size();	if (iNumUsedBits + iSize < iMaxNumBitsDataBlocks)	{		iNumUsedBits += iSize;		vecbiData.ResetBitAccess();		for (i = 0; i < iSize; i++)			(*pbiData).Enqueue(vecbiData.Separate(1), 1);	}// Only working for either one audio or data service!if (Parameter.iNumAudioService == 1){	/* Type 9 */	DataEntityType9(vecbiData, 0, Parameter);}else{	/* Type 5 */	DataEntityType5(vecbiData, 0, Parameter);}// TODO: nicer solutioniSize = vecbiData.Size();if (iNumUsedBits + iSize < iMaxNumBitsDataBlocks){	iNumUsedBits += iSize;	vecbiData.ResetBitAccess();	for (i = 0; i < iSize; i++)		(*pbiData).Enqueue(vecbiData.Separate(1), 1);}	/* Type 1 */	DataEntityType1(vecbiData, 0, Parameter);	// TODO: nicer solution	iSize = vecbiData.Size();	if (iNumUsedBits + iSize < iMaxNumBitsDataBlocks)	{		iNumUsedBits += iSize;		vecbiData.ResetBitAccess();		for (i = 0; i < iSize; i++)			(*pbiData).Enqueue(vecbiData.Separate(1), 1);	}	/* Zero-pad the unused bits in this SDC-block */	for (i = 0; i < iMaxNumBitsDataBlocks - iNumUsedBits; i++)		(*pbiData).Enqueue((uint32_t) 0, 1);	/* CRC ------------------------------------------------------------------ */	/* Calculate the CRC and put it at the end of the stream */	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);	for (i = 0; i < (iUsefulBitsSDC - 4) / SIZEOF__BYTE - 2; i++)		CRCObject.AddByte((_BYTE) (*pbiData).Separate(SIZEOF__BYTE));	/* Now, pointer in "enqueue"-function is back at the same place, 	   add CRC */	(*pbiData).Enqueue(CRCObject.GetCRC(), 16);}/******************************************************************************\* Data entity Type 0 (Multiplex description data entity)					   *\******************************************************************************/void CSDCTransmit::DataEntityType0(CVector<_BINARY>& vecbiData,								   CParameter& Parameter){	/* 24 bits for each stream description + 4 bits for protection levels */	const int iNumBitsTotal = 4 + Parameter.GetTotNumServices() * 24;	/* Init return vector (storing this data block) */	vecbiData.Init(iNumBitsTotal + NUM_BITS_HEADER_SDC);	vecbiData.ResetBitAccess();	/* Length of the body, excluding the initial 4 bits ("- 4"), 	   measured in bytes ("/ 8") */	uint32_t iLengthInBytes = (iNumBitsTotal - 4) / 8;	vecbiData.Enqueue(iLengthInBytes, 7);	/* Version flag (not used in this implementation) */	vecbiData.Enqueue((uint32_t) 0, 1);	/* Data entity type */	vecbiData.Enqueue((uint32_t) 00, 4); /* Type 00 */	/* Actual body ---------------------------------------------------------- */	/* Protection level for part A */	vecbiData.Enqueue((uint32_t) Parameter.MSCPrLe.iPartA, 2);	/* Protection level for part B */	vecbiData.Enqueue((uint32_t) Parameter.MSCPrLe.iPartB, 2);	for (int i = 0; i < Parameter.GetTotNumServices(); i++)	{		/* In case of hirachical modulation stream 0 describes the protection		   level and length of hirarchical data */		if ((i == 0) && 			((Parameter.eMSCCodingScheme == CParameter::CS_3_HMSYM) ||			(Parameter.eMSCCodingScheme == CParameter::CS_3_HMMIX)))		{			/* Protection level for hierarchical */			vecbiData.Enqueue((uint32_t) Parameter.MSCPrLe.iHierarch, 2);					/* rfu */			vecbiData.Enqueue((uint32_t) 0, 10);				/* Data length for hierarchical */			vecbiData.Enqueue((uint32_t) Parameter.Stream[i].iLenPartB, 12);		}		else		{			/* Data length for part A */			vecbiData.Enqueue((uint32_t) Parameter.Stream[i].iLenPartA, 12);					/* Data length for part B */			vecbiData.Enqueue((uint32_t) Parameter.Stream[i].iLenPartB, 12);		}	}}/******************************************************************************\* Data entity Type 1 (Label data entity)									   *\******************************************************************************/void CSDCTransmit::DataEntityType1(CVector<_BINARY>& vecbiData, int ServiceID,								   CParameter& Parameter){	int	iLenLabel;	/* Length of label. Label is a variable length field of up to 16 bytes	   defining the label using UTF-8 coding */	const int iLenLabelTmp = Parameter.Service[ServiceID].strLabel.length();	if (iLenLabelTmp > 16)		iLenLabel = 16;	else		iLenLabel = iLenLabelTmp;	/* Number in bits (* 8) plus initial 4 bits (+ 4) */	const int iNumBitsTotal = iLenLabel * 8 + 4;	/* Init return vector (storing this data block) */	vecbiData.Init(iNumBitsTotal + NUM_BITS_HEADER_SDC);	vecbiData.ResetBitAccess();	/**** Multiplex description data entity - type 1 ****/	/* Length of the body, excluding the initial 4 bits, 	   measured in bytes -> only number bytes of label */	vecbiData.Enqueue((uint32_t) iLenLabel, 7);	/* Version flag (not used in this implementation) */	vecbiData.Enqueue((uint32_t) 0, 1);	/* Data entity type */	vecbiData.Enqueue((uint32_t) 01, 4); /* Type 01 */	/* Actual body ---------------------------------------------------------- */	/* Short Id */	vecbiData.Enqueue((uint32_t) ServiceID, 2);	/* rfu */	vecbiData.Enqueue((uint32_t) 0, 2);	/* Set all characters of label string */	for (int i = 0; i < iLenLabel; i++)	{		const char cNewChar = Parameter.Service[ServiceID].strLabel[i];		/* Set character */		vecbiData.Enqueue((uint32_t) cNewChar, 8);	}}/******************************************************************************\* Data entity Type 5 (Application information data entity)					   *\******************************************************************************/void CSDCTransmit::DataEntityType5(CVector<_BINARY>& vecbiData, int ServiceID,								   CParameter& Parameter){	int	iNumBitsTotal;	/* Set total number of bits */	switch (Parameter.Service[ServiceID].DataParam.ePacketModInd)	{	case CParameter::PM_SYNCHRON_STR_MODE:		iNumBitsTotal = 12 + 16 /* TEST */ /* + application data TODO! */;		break;	case CParameter::PM_PACKET_MODE:		iNumBitsTotal = 20 + 16 /* TEST */ /* + application data TODO! */;		break;	}	/* Init return vector (storing this data block) */	vecbiData.Init(iNumBitsTotal + NUM_BITS_HEADER_SDC);	vecbiData.ResetBitAccess();	/* Length of the body, excluding the initial 4 bits ("- 4"), 	   measured in bytes ("/ 8") */	vecbiData.Enqueue((uint32_t) (iNumBitsTotal - 4) / 8, 7);	/* Version flag (not used in this implementation) */	vecbiData.Enqueue((uint32_t) 0, 1);	/* Data entity type */	vecbiData.Enqueue((uint32_t) 05, 4); /* Type 05 */	/* Actual body ---------------------------------------------------------- */	/* Short Id */	vecbiData.Enqueue((uint32_t) ServiceID, 2);	/* Stream Id */	vecbiData.Enqueue((uint32_t) Parameter.Service[ServiceID].DataParam.		iStreamID, 2);	/* Packet mode indicator */	switch (Parameter.Service[ServiceID].DataParam.ePacketModInd)	{	case CParameter::PM_SYNCHRON_STR_MODE:		vecbiData.Enqueue(0 /* 0 */, 1);		/* Descriptor */		vecbiData.Enqueue((uint32_t) 0, 7);		break;	case CParameter::PM_PACKET_MODE:		vecbiData.Enqueue(1 /* 1 */, 1);		/* Descriptor */		/* Data unit indicator */		switch (Parameter.Service[ServiceID].DataParam.eDataUnitInd)		{		case CParameter::DU_SINGLE_PACKETS:			vecbiData.Enqueue(0 /* 0 */, 1);			break;		case CParameter::DU_DATA_UNITS:			vecbiData.Enqueue(1 /* 1 */, 1);			break;		}		/* Packet Id */		vecbiData.Enqueue( 			(uint32_t) Parameter.Service[ServiceID].DataParam.iPacketID, 2);		/* Application domain */		switch (Parameter.Service[ServiceID].DataParam.eAppDomain)		{		case CParameter::AD_DRM_SPEC_APP:			vecbiData.Enqueue(0 /* 0000 */, 4);			break;		case CParameter::AD_DAB_SPEC_APP:			vecbiData.Enqueue(1 /* 0001 */, 4);			break;		}		/* Packet length */		vecbiData.Enqueue( 			(uint32_t) Parameter.Service[ServiceID].DataParam.iPacketLen, 8);		break;	}	/* Application data */// Not used// TEST/* Fixed implementation for MOTSlideshow application which is the one and   only supported application right now. TODO *//* rfu */vecbiData.Enqueue((uint32_t) 0, 5);/* User application identifier. SlideShow = 2 */vecbiData.Enqueue((uint32_t) 2, 11);}/******************************************************************************\* Data entity Type 9 (Audio information data entity)						   *\******************************************************************************/void CSDCTransmit::DataEntityType9(CVector<_BINARY>& vecbiData, int ServiceID,								   CParameter& Parameter){	/* Set total number of bits */	const int iNumBitsTotal = 20;	/* Init return vector (storing this data block) */	vecbiData.Init(iNumBitsTotal + NUM_BITS_HEADER_SDC);	vecbiData.ResetBitAccess();	/* Length of the body, excluding the initial 4 bits ("- 4"), 	   measured in bytes ("/ 8") */	vecbiData.Enqueue((uint32_t) (iNumBitsTotal - 4) / 8, 7);	/* Version flag (not used in this implementation) */	vecbiData.Enqueue((uint32_t) 0, 1);	/* Data entity type */	vecbiData.Enqueue((uint32_t) 9, 4); /* Type 09 */	/* Actual body ---------------------------------------------------------- */	/* Short Id */	vecbiData.Enqueue((uint32_t) ServiceID, 2);	/* Stream Id */	vecbiData.Enqueue((uint32_t) Parameter.Service[ServiceID].AudioParam.		iStreamID, 2);	/* Audio coding */	switch (Parameter.Service[ServiceID].AudioParam.eAudioCoding)	{	case CParameter::AC_AAC:		vecbiData.Enqueue(0 /* 00 */, 2);		break;	case CParameter::AC_CELP:		vecbiData.Enqueue(1 /* 01 */, 2);		break;	case CParameter::AC_HVXC:		vecbiData.Enqueue(2 /* 10 */, 2);		break;	}	/* SBR flag */	switch (Parameter.Service[ServiceID].AudioParam.eSBRFlag)	{	case CParameter::SB_NOT_USED:		vecbiData.Enqueue(0 /* 0 */, 1);		break;	case CParameter::SB_USED:		vecbiData.Enqueue(1 /* 1 */, 1);		break;	}	/* Audio mode */	switch (Parameter.Service[ServiceID].AudioParam.eAudioCoding)	{	case CParameter::AC_AAC:		/* Channel type */		switch (Parameter.Service[ServiceID].AudioParam.eAudioMode)		{		case CParameter::AM_MONO:			vecbiData.Enqueue(0 /* 00 */, 2);			break;		case CParameter::AM_P_STEREO:			vecbiData.Enqueue(1 /* 01 */, 2);			break;		case CParameter::AM_STEREO:			vecbiData.Enqueue(2 /* 10 */, 2);			break;		}		break;	case CParameter::AC_CELP:		/* rfa */		vecbiData.Enqueue((uint32_t) 0, 1);		/* CELP_CRC */		switch (Parameter.Service[ServiceID].AudioParam.bCELPCRC)		{		case FALSE:			vecbiData.Enqueue(0 /* 0 */, 1);			break;		case TRUE:			vecbiData.Enqueue(1 /* 1 */, 1);			break;		}		break;	case CParameter::AC_HVXC:		/* HVXC_rate */		switch (Parameter.Service[ServiceID].AudioParam.eHVXCRate)		{		case CParameter::HR_2_KBIT:			vecbiData.Enqueue(0 /* 0 */, 1);			break;		case CParameter::HR_4_KBIT:			vecbiData.Enqueue(1 /* 1 */, 1);			break;		}		/* HVXC CRC */		switch (Parameter.Service[ServiceID].AudioParam.bHVXCCRC)		{		case FALSE:			vecbiData.Enqueue(0 /* 0 */, 1);			break;		case TRUE:			vecbiData.Enqueue(1 /* 1 */, 1);			break;		}		break;	}	/* Audio sampling rate */	switch (Parameter.Service[ServiceID].AudioParam.eAudioSamplRate)	{	case CParameter::AS_8_KHZ:		vecbiData.Enqueue(0 /* 000 */, 3);		break;	case CParameter::AS_12KHZ:		vecbiData.Enqueue(1 /* 001 */, 3);		break;	case CParameter::AS_16KHZ:		vecbiData.Enqueue(2 /* 010 */, 3);		break;	case CParameter::AS_24KHZ:		vecbiData.Enqueue(3 /* 011 */, 3);		break;	}	/* Text flag */	switch (Parameter.Service[ServiceID].AudioParam.bTextflag)	{	case FALSE:		vecbiData.Enqueue(0 /* 0 */, 1);		break;	case TRUE:		vecbiData.Enqueue(1 /* 1 */, 1);		break;	}	/* Enhancement flag */	switch (Parameter.Service[ServiceID].AudioParam.bEnhanceFlag)	{	case FALSE:		vecbiData.Enqueue(0 /* 0 */, 1);		break;	case TRUE:		vecbiData.Enqueue(1 /* 1 */, 1);		break;	}	/* Coder field */	if (Parameter.Service[ServiceID].AudioParam.		eAudioCoding == CParameter::AC_CELP)	{		/* CELP index */		vecbiData.Enqueue( 			(uint32_t) Parameter.Service[ServiceID].AudioParam.iCELPIndex, 5);	}	else	{		/* rfa 5 bit */		vecbiData.Enqueue((uint32_t) 0, 5);	}		/* rfa 1 bit */	vecbiData.Enqueue((uint32_t) 0, 1);}

⌨️ 快捷键说明

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