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

📄 audiosourcedecoder.cpp

📁 Dream.exe soft source (Visual C++)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					const _REAL rAtt = (_REAL) i / iResOutBlockSize;

					vecTempResBufOutCurLeft[i] *= rAtt;
					vecTempResBufOutCurRight[i] *= rAtt;

					if (bUseReverbEffect == TRUE)
					{
						/* Cross-fade reverberation effect */
						const _REAL rRevSam = (1.0 - rAtt) * AudioRev.
							ProcessSample(0, 0);

						/* Mono reverberation signal */
						vecTempResBufOutCurLeft[i] += rRevSam;
						vecTempResBufOutCurRight[i] += rRevSam;
					}
				}

				/* Reset flag */
				bAudioWasOK = TRUE;
			}
		}

		/* Conversion from _REAL to _SAMPLE with special function */
		for (i = 0; i < iResOutBlockSize; i++)
		{
			(*pvecOutputData)[iOutputBlockSize + i * 2] = 
				Real2Sample(vecTempResBufOutOldLeft[i]); /* Left channel */
			(*pvecOutputData)[iOutputBlockSize + i * 2 + 1] =
				Real2Sample(vecTempResBufOutOldRight[i]); /* Right channel */
		}

		/* Add new block to output block size ("* 2" for stereo output block) */
		iOutputBlockSize += iResOutBlockSize * 2;

		/* Store current audio block */
		for (i = 0; i < iResOutBlockSize; i++)
		{
			vecTempResBufOutOldLeft[i] = vecTempResBufOutCurLeft[i];
			vecTempResBufOutOldRight[i] = vecTempResBufOutCurRight[i];
		}
	}
#endif
}

void CAudioSourceDecoder::InitInternal(CParameter& ReceiverParam)
{
/*
	Since we use the exception mechanism in this init routine, the sequence of
	the individual initializations is very important!
	Requirement for text message is "stream is used" and "audio service".
	Requirement for AAC decoding are the requirements above plus "audio coding
	is AAC"
*/
	int iCurAudioStreamID;
	int iMaxLenResamplerOutput;
	int iCurSelServ;
	int iDRMchanMode;
	int iAudioSampleRate;
	int iAACSampleRate;
	int	iLenAudHigh;
	int	iNumHeaderBytes;

	try
	{
		/* Init error flags and output block size parameter. The output block
		   size is set in the processing routine. We must set it here in case
		   of an error in the initialization, this part in the processing
		   routine is not being called */
		DoNotProcessAAC = FALSE;
		DoNotProcessData = FALSE;
		iOutputBlockSize = 0;

		/* Init counter for correctly decoded audio blocks */
		iNumCorDecAudio = 0;

		/* Get number of total input bits for this module */
		iInputBlockSize = ReceiverParam.iNumAudioDecoderBits;

		/* Get current selected audio service */
		iCurSelServ = ReceiverParam.GetCurSelAudioService();

		/* Current audio stream ID */
		iCurAudioStreamID =
			ReceiverParam.Service[iCurSelServ].AudioParam.iStreamID;

		/* The requirement for this module is that the stream is used and the
		   service is an audio service. Check it here */
		if ((ReceiverParam.Service[iCurSelServ].
			eAudDataFlag != CParameter::SF_AUDIO) ||
			(iCurAudioStreamID == STREAM_ID_NOT_USED))
		{
			throw CInitErr(ET_ALL);
		}


		/* Init text message application ------------------------------------ */
		switch (ReceiverParam.Service[iCurSelServ].AudioParam.bTextflag)
		{
		case TRUE:
			bTextMessageUsed = TRUE;

			/* Get a pointer to the string */
			TextMessage.Init(&ReceiverParam.Service[iCurSelServ].AudioParam.
				strTextMessage);

			/* Total frame size is input block size minus the bytes for the text
			   message */
			iTotalFrameSize = iInputBlockSize -
				SIZEOF__BYTE * NUM_BYTES_TEXT_MESS_IN_AUD_STR;

			/* Init vector for text message bytes */
			vecbiTextMessBuf.Init(SIZEOF__BYTE * NUM_BYTES_TEXT_MESS_IN_AUD_STR);
			break;

		case FALSE:
			bTextMessageUsed = FALSE;

			/* All bytes are used for AAC data, no text message present */
			iTotalFrameSize = iInputBlockSize;
			break;
		}


#ifdef USE_FAAD2_LIBRARY
		/* Init for AAC decoding -------------------------------------------- */
		/* Check, if AAC is used */
		if (ReceiverParam.Service[iCurSelServ].AudioParam.
			eAudioCoding != CParameter::AC_AAC)
		{
			throw CInitErr(ET_AAC);
		}

		/* Init "audio was ok" flag */
		bAudioWasOK = TRUE;

		/* Length of higher protected part of audio stream */
		iLenAudHigh = ReceiverParam.Stream[iCurAudioStreamID].iLenPartA;

		/* Set number of AAC frames in a AAC super-frame */
		switch (ReceiverParam.Service[iCurSelServ].AudioParam.eAudioSamplRate)
		{ /* only 12 kHz and 24 kHz is allowed */
		case CParameter::AS_12KHZ:
			iNumAACFrames = 5;
			iNumHeaderBytes = 6;
			iAACSampleRate = 12000;
			break;

		case CParameter::AS_24KHZ:
			iNumAACFrames = 10;
			iNumHeaderBytes = 14;
			iAACSampleRate = 24000;
			break;

		default:
			/* Some error occurred, throw error */
			throw CInitErr(ET_AAC);
			break;
		}

		/* Number of borders */
		iNumBorders = iNumAACFrames - 1;

		/* Set number of AAC frames for log file */
		ReceiverParam.ReceptLog.SetNumAAC(iNumAACFrames);

		/* Number of channels for AAC: Mono, PStereo, Stereo */
		switch (ReceiverParam.Service[iCurSelServ].AudioParam.eAudioMode)
		{
		case CParameter::AM_MONO:
			if (ReceiverParam.Service[iCurSelServ].AudioParam.
				eSBRFlag == CParameter::SB_USED)
			{
				iDRMchanMode = DRMCH_SBR_MONO;
			}
			else
				iDRMchanMode = DRMCH_MONO;
			break;

		case CParameter::AM_P_STEREO:
			/* Low-complexity only defined in SBR mode */
			iDRMchanMode = DRMCH_SBR_PS_STEREO;
			break;

		case CParameter::AM_STEREO:
			if (ReceiverParam.Service[iCurSelServ].AudioParam.
				eSBRFlag == CParameter::SB_USED)
			{
				iDRMchanMode = DRMCH_SBR_STEREO;
			}
			else
			{
				iDRMchanMode = DRMCH_STEREO;
			}
			break;
		}

		/* In case of SBR, AAC sample rate is half the total sample rate. Length
		   of output is doubled if SBR is used */
		if (ReceiverParam.Service[iCurSelServ].AudioParam.
			eSBRFlag == CParameter::SB_USED)
		{
			iAudioSampleRate = iAACSampleRate * 2;
			iLenDecOutPerChan = AUD_DEC_TRANSFROM_LENGTH * 2;
		}
		else
		{
			iAudioSampleRate = iAACSampleRate;
			iLenDecOutPerChan = AUD_DEC_TRANSFROM_LENGTH;
		}

		/* The audio_payload_length is derived from the length of the audio
		   super frame (data_length_of_part_A + data_length_of_part_B)
		   subtracting the audio super frame overhead (bytes used for the audio
		   super frame header() and for the aac_crc_bits) (5.3.1.1, Table 5) */
		iAudioPayloadLen =
			iTotalFrameSize / SIZEOF__BYTE - iNumHeaderBytes - iNumAACFrames;

		/* Check iAudioPayloadLen value, only positive values make sense */
		if (iAudioPayloadLen < 0)
			throw CInitErr(ET_AAC);

		/* Calculate number of bytes for higher protected blocks */
		iNumHigherProtectedBytes =
			(iLenAudHigh - iNumHeaderBytes - iNumAACFrames /* CRC bytes */) /
			iNumAACFrames;

		if (iNumHigherProtectedBytes < 0)
			iNumHigherProtectedBytes = 0;

		/* Since we do not correct for sample rate offsets here (yet), we do not
		   have to consider larger buffers. An audio frame always corresponds
		   to 400 ms */
		iMaxLenResamplerOutput = (int) ((_REAL) SOUNDCRD_SAMPLE_RATE *
			(_REAL) 0.4 /* 400ms */ * 2 /* for stereo */);

		iResOutBlockSize = (int) ((_REAL) iLenDecOutPerChan *
			SOUNDCRD_SAMPLE_RATE / iAudioSampleRate);

		/* Additional buffers needed for resampling since we need conversation
		   between _REAL and _SAMPLE. We have to init the buffers with
		   zeros since it can happen, that we have bad CRC right at the
		   start of audio blocks */
		vecTempResBufInLeft.Init(iLenDecOutPerChan);
		vecTempResBufInRight.Init(iLenDecOutPerChan);
		vecTempResBufOutCurLeft.Init(iResOutBlockSize, (_REAL) 0.0);
		vecTempResBufOutCurRight.Init(iResOutBlockSize, (_REAL) 0.0);
		vecTempResBufOutOldLeft.Init(iResOutBlockSize, (_REAL) 0.0);
		vecTempResBufOutOldRight.Init(iResOutBlockSize, (_REAL) 0.0);

		/* Init resample objects */
		ResampleObjL.Init(iLenDecOutPerChan,
			(_REAL) SOUNDCRD_SAMPLE_RATE / iAudioSampleRate);
		ResampleObjR.Init(iLenDecOutPerChan,
			(_REAL) SOUNDCRD_SAMPLE_RATE / iAudioSampleRate);

		/* Clear reverberation object */
		AudioRev.Clear();


		/* AAC decoder ------------------------------------------------------ */
		/* The maximum length for one audio frame is "iAudioPayloadLen". The
		   regular size will be much shorter since all audio frames share the
		   total size, but we do not know at this time how the data is 
		   split in the transmitter source coder */
		iMaxLenOneAudFrame = iAudioPayloadLen;
		audio_frame.Init(iNumAACFrames, iMaxLenOneAudFrame);

		/* Init vector which stores the data with the CRC at the beginning
		   ("+ 1" for CRC) */
		vecbyPrepAudioFrame.Init(iMaxLenOneAudFrame + 1);

		/* Init storage for CRCs and frame lengths */
		aac_crc_bits.Init(iNumAACFrames);
		veciFrameLength.Init(iNumAACFrames);

		/* Init AAC-decoder */
		NeAACDecInitDRM(&HandleAACDecoder, iAACSampleRate, iDRMchanMode);

		/* With this parameter we define the maximum lenght of the output
		   buffer. The cyclic buffer is only needed if we do a sample rate
		   correction due to a difference compared to the transmitter. But for
		   now we do not correct and we could stay with a single buffer
		   Maybe TODO: sample rate correction to avoid audio dropouts */
		iMaxOutputBlockSize = iMaxLenResamplerOutput;
#else
		/* No audio output if AAC library is not used */
		iOutputBlockSize = 0;
#endif
	}

	catch (CInitErr CurErr)
	{
		switch (CurErr.eErrType)
		{
		case ET_ALL:
			/* An init error occurred, do not process data in this module */
			DoNotProcessData = TRUE;
			break;

		case ET_AAC:
			/* AAC part should not be decdoded, set flag */
			DoNotProcessAAC = TRUE;
			break;

		default:
			DoNotProcessData = TRUE;
		}

		/* In all cases set output size to zero */
		iOutputBlockSize = 0;
	}
}

int CAudioSourceDecoder::GetNumCorDecAudio()
{
	/* Return number of correctly decoded audio blocks. Reset counter
	   afterwards */
	const int iRet = iNumCorDecAudio;

	iNumCorDecAudio = 0;

	return iRet;
}

CAudioSourceDecoder::CAudioSourceDecoder()
#ifdef USE_FAAD2_LIBRARY
	: AudioRev((CReal) 1.0 /* seconds delay */), bUseReverbEffect(TRUE)
#endif
{
#ifdef USE_FAAD2_LIBRARY
	/* Open AACEncoder instance */
	HandleAACDecoder = NeAACDecOpen();

	/* Decoder MUST be initialized at least once, therefore do it here in the
	   constructor with arbitrary values to be sure that this is satisfied */
	NeAACDecInitDRM(&HandleAACDecoder, 24000, DRMCH_MONO);
#endif
}

CAudioSourceDecoder::~CAudioSourceDecoder()
{
#ifdef USE_FAAD2_LIBRARY
	/* Close decoder handle */
	NeAACDecClose(HandleAACDecoder);
#endif
}

⌨️ 快捷键说明

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