📄 audiosourcedecoder.cpp
字号:
(iTotNumBytesForUsage < TransmParam.Stream[iCurStreamID].iLenPartA))
{
/* Equal error protection was chosen or protection part A was chosen too
high, set to equal error protection! */
TransmParam.Stream[iCurStreamID].iLenPartA = 0;
TransmParam.Stream[iCurStreamID].iLenPartB = iTotNumBytesForUsage;
}
else
TransmParam.Stream[iCurStreamID].iLenPartB = iTotNumBytesForUsage -
TransmParam.Stream[iCurStreamID].iLenPartA;
/* Define input and output block size */
iOutputBlockSize = TransmParam.iNumDecodedBitsMSC;
iInputBlockSize = iNumInSamplesMono * 2 /* stereo */;
}
void CAudioSourceEncoder::SetTextMessage(const string& strText)
{
/* Set text message in text message object */
TextMessage.SetMessage(strText);
/* Set text message flag */
bUsingTextMessage = TRUE;
}
void CAudioSourceEncoder::ClearTextMessage()
{
/* Clear all text segments */
TextMessage.ClearAllText();
/* Clear text message flag */
bUsingTextMessage = FALSE;
}
CAudioSourceEncoder::~CAudioSourceEncoder()
{
#ifdef USE_FAAC_LIBRARY
/* Close encoder instance afterwards */
if (hEncoder != NULL)
faacEncClose(hEncoder);
#endif
}
/******************************************************************************\
* Decoder *
\******************************************************************************/
void CAudioSourceDecoder::ProcessDataInternal(CParameter& ReceiverParam)
{
int i;
/* Check if something went wrong in the initialization routine */
if (DoNotProcessData == TRUE)
return;
/* Text Message ***********************************************************/
/* Total frame size depends on whether text message is used or not */
if (bTextMessageUsed == TRUE)
{
/* Decode last for bytes of input block for text message */
for (i = 0; i < SIZEOF__BYTE * NUM_BYTES_TEXT_MESS_IN_AUD_STR; i++)
vecbiTextMessBuf[i] = (*pvecInputData)[iTotalFrameSize + i];
TextMessage.Decode(vecbiTextMessBuf);
}
#ifdef USE_FAAD2_LIBRARY
faacDecFrameInfo DecFrameInfo;
_BOOLEAN bGoodValues;
short* psDecOutSampleBuf;
int j;
/* Check if AAC should not be decoded */
if (DoNotProcessAAC == TRUE)
return;
/* Extract audio data from stream *****************************************/
/* Reset bit extraction access */
(*pvecInputData).ResetBitAccess();
/* AAC super-frame-header ----------------------------------------------- */
int iPrevBorder = 0;
for (i = 0; i < iNumBorders; i++)
{
/* Frame border in bytes (12 bits) */
const int iFrameBorder = (*pvecInputData).Separate(12);
/* The lenght is difference between borders */
veciFrameLength[i] = iFrameBorder - iPrevBorder;
iPrevBorder = iFrameBorder;
}
/* Byte-alignment (4 bits) in case of 10 audio frames */
if (iNumBorders == 9)
(*pvecInputData).Separate(4);
/* Frame length of last frame */
veciFrameLength[iNumBorders] = iAudioPayloadLen - iPrevBorder;
/* Check if frame length entries represent possible values */
bGoodValues = TRUE;
for (i = 0; i < iNumAACFrames; i++)
{
if ((veciFrameLength[i] < 0) ||
(veciFrameLength[i] > iMaxLenOneAudFrame))
{
bGoodValues = FALSE;
}
}
if (bGoodValues == TRUE)
{
/* Higher-protected part -------------------------------------------- */
for (i = 0; i < iNumAACFrames; i++)
{
/* Extract higher protected part bytes (8 bits per byte) */
for (j = 0; j < iNumHigherProtectedBytes; j++)
audio_frame[i][j] = (*pvecInputData).Separate(8);
/* Extract CRC bits (8 bits) */
aac_crc_bits[i] = (*pvecInputData).Separate(8);
}
/* Lower-protected part --------------------------------------------- */
for (i = 0; i < iNumAACFrames; i++)
{
/* First calculate frame length, derived from higher protected part
frame length and total size */
const int iNumLowerProtectedBytes =
veciFrameLength[i] - iNumHigherProtectedBytes;
/* Extract lower protected part bytes (8 bits per byte) */
for (j = 0; j < iNumLowerProtectedBytes; j++)
{
audio_frame[i][iNumHigherProtectedBytes + j] =
(*pvecInputData).Separate(8);
}
}
}
/* AAC decoder ************************************************************/
/* Init output block size to zero, this variable is also used for
determining the position for writing the output vector */
iOutputBlockSize = 0;
for (j = 0; j < iNumAACFrames; j++)
{
if (bGoodValues == TRUE)
{
/* Prepare data vector with CRC at the beginning (the definition
with faad2 DRM interface) */
vecbyPrepAudioFrame[0] = aac_crc_bits[j];
for (i = 0; i < veciFrameLength[j]; i++)
vecbyPrepAudioFrame[i + 1] = audio_frame[j][i];
#if 0
// Store AAC-data in file
string strAACTestFileName = "test/aac_";
if (ReceiverParam.Service[ReceiverParam.GetCurSelAudioService()].
AudioParam.eAudioSamplRate == CParameter::AS_12KHZ)
{
strAACTestFileName += "12kHz_";
}
else
strAACTestFileName += "24kHz_";
switch (ReceiverParam.Service[ReceiverParam.GetCurSelAudioService()].
AudioParam.eAudioMode)
{
case CParameter::AM_MONO:
strAACTestFileName += "mono";
break;
case CParameter::AM_P_STEREO:
strAACTestFileName += "pstereo";
break;
case CParameter::AM_STEREO:
strAACTestFileName += "stereo";
break;
}
if (ReceiverParam.Service[ReceiverParam.GetCurSelAudioService()].AudioParam.
eSBRFlag == CParameter::SB_USED)
{
strAACTestFileName += "_sbr";
}
strAACTestFileName += ".dat";
static FILE* pFile2 = fopen(strAACTestFileName.c_str(), "wb");
int iNewFrL = veciFrameLength[j] + 1;
// Frame length
fwrite((void*) &iNewFrL, size_t(4), size_t(1), pFile2);
size_t count = veciFrameLength[j] + 1; /* Number of bytes to write */
fwrite((void*) &vecbyPrepAudioFrame[0], size_t(1), count, pFile2);
fflush(pFile2);
#endif
/* Call decoder routine */
psDecOutSampleBuf = (short*) NeAACDecDecode(HandleAACDecoder,
&DecFrameInfo, &vecbyPrepAudioFrame[0], veciFrameLength[j] + 1);
}
else
{
/* DRM AAC header was wrong, set decoder error code */
DecFrameInfo.error = 1;
}
if (DecFrameInfo.error != 0)
{
/* Set AAC CRC result in log file */
ReceiverParam.ReceptLog.SetMSC(FALSE);
if (bAudioWasOK == TRUE)
{
/* Post message to show that CRC was wrong (yellow light) */
PostWinMessage(MS_MSC_CRC, 1);
/* Fade-out old block to avoid "clicks" in audio. We use linear
fading which gives a log-fading impression */
for (i = 0; i < iResOutBlockSize; i++)
{
/* Linear attenuation with time of OLD buffer */
const _REAL rAtt =
(_REAL) 1.0 - (_REAL) i / iResOutBlockSize;
vecTempResBufOutOldLeft[i] *= rAtt;
vecTempResBufOutOldRight[i] *= rAtt;
if (bUseReverbEffect == TRUE)
{
/* Fade in input signal for reverberation to avoid
clicks */
const _REAL rAttRev = (_REAL) i / iResOutBlockSize;
/* Cross-fade reverberation effect */
const _REAL rRevSam = (1.0 - rAtt) * AudioRev.
ProcessSample(vecTempResBufOutOldLeft[i] * rAttRev,
vecTempResBufOutOldRight[i] * rAttRev);
/* Mono reverbration signal */
vecTempResBufOutOldLeft[i] += rRevSam;
vecTempResBufOutOldRight[i] += rRevSam;
}
}
/* Set flag to show that audio block was bad */
bAudioWasOK = FALSE;
}
else
{
/* Post message to show that CRC was wrong (red light) */
PostWinMessage(MS_MSC_CRC, 2);
if (bUseReverbEffect == TRUE)
{
/* Add Reverberation effect */
for (i = 0; i < iResOutBlockSize; i++)
{
/* Mono reverberation signal */
vecTempResBufOutOldLeft[i] =
vecTempResBufOutOldRight[i] = AudioRev.
ProcessSample(0, 0);
}
}
}
/* Write zeros in current output buffer */
for (i = 0; i < iResOutBlockSize; i++)
{
vecTempResBufOutCurLeft[i] = (_REAL) 0.0;
vecTempResBufOutCurRight[i] = (_REAL) 0.0;
}
}
else
{
/* Set AAC CRC result in log file */
ReceiverParam.ReceptLog.SetMSC(TRUE);
/* Increment correctly decoded audio blocks counter */
iNumCorDecAudio++;
/* Post message to show that CRC was OK */
PostWinMessage(MS_MSC_CRC, 0);
/* Conversion from _SAMPLE vector to _REAL vector for resampling.
ATTENTION: We use a vector which was allocated inside
the AAC decoder! */
if (DecFrameInfo.channels == 1)
{
/* Change type of data (short -> real) */
for (i = 0; i < iLenDecOutPerChan; i++)
vecTempResBufInLeft[i] = psDecOutSampleBuf[i];
/* Resample data */
ResampleObjL.Resample(vecTempResBufInLeft,
vecTempResBufOutCurLeft);
/* Mono (write the same audio material in both channels) */
for (i = 0; i < iResOutBlockSize; i++)
vecTempResBufOutCurRight[i] = vecTempResBufOutCurLeft[i];
}
else
{
/* Stereo */
for (i = 0; i < iLenDecOutPerChan; i++)
{
vecTempResBufInLeft[i] = psDecOutSampleBuf[i * 2];
vecTempResBufInRight[i] = psDecOutSampleBuf[i * 2 + 1];
}
/* Resample data */
ResampleObjL.Resample(vecTempResBufInLeft,
vecTempResBufOutCurLeft);
ResampleObjR.Resample(vecTempResBufInRight,
vecTempResBufOutCurRight);
}
if (bAudioWasOK == FALSE)
{
if (bUseReverbEffect == TRUE)
{
/* Add "last" reverbration only to old block */
for (i = 0; i < iResOutBlockSize; i++)
{
/* Mono reverberation signal */
vecTempResBufOutOldLeft[i] =
vecTempResBufOutOldRight[i] = AudioRev.
ProcessSample(vecTempResBufOutOldLeft[i],
vecTempResBufOutOldRight[i]);
}
}
/* Fade-in new block to avoid "clicks" in audio. We use linear
fading which gives a log-fading impression */
for (i = 0; i < iResOutBlockSize; i++)
{
/* Linear attenuation with time */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -