📄 filefmt.c
字号:
nChans++;
}
}
return nChans;
}
/**************************************************************************************
* Function: GetSampleRateIdxADIF
*
* Description: get sampling rate index from program config elements in an ADIF file
*
* Inputs: array of filled-in program config element structures
* number of PCE's
*
* Outputs: none
*
* Return: sample rate of file
* -1 if error (invalid number of PCE's or sample rate mismatch)
**************************************************************************************/
static int GetSampleRateIdxADIF(ProgConfigElement *fhPCE, int nPCE)
{
int i, idx;
if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF)
return -1;
/* make sure all PCE's have the same sample rate */
idx = fhPCE[0].sampRateIdx;
for (i = 1; i < nPCE; i++) {
if (fhPCE[i].sampRateIdx != idx)
return -1;
}
return idx;
}
/**************************************************************************************
* Function: UnpackADIFHeader
*
* Description: parse the ADIF file header and initialize decoder state
*
* Inputs: valid AACDecInfo struct
* double pointer to buffer with complete ADIF header
* (starting at 'A' in 'ADIF' tag)
* pointer to bit offset
* pointer to number of valid bits remaining in inbuf
*
* Outputs: filled-in ADIF struct
* updated buffer pointer
* updated bit offset
* updated number of available bits
*
* Return: 0 if successful, error code (< 0) if error
**************************************************************************************/
int UnpackADIFHeader(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail)
{
int i, bitsUsed;
PSInfoBase *psi;
BitStreamInfo bsi;
ADIFHeader *fhADIF;
ProgConfigElement *pce;
/* validate pointers */
if (!aacDecInfo || !aacDecInfo->psInfoBase)
return ERR_AAC_NULL_POINTER;
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
/* init bitstream reader */
SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf);
GetBits(&bsi, *bitOffset);
/* unpack ADIF file header */
fhADIF = &(psi->fhADIF);
pce = psi->pce;
/* verify that first 32 bits of header are "ADIF" */
if (GetBits(&bsi, 8) != 'A' || GetBits(&bsi, 8) != 'D' || GetBits(&bsi, 8) != 'I' || GetBits(&bsi, 8) != 'F')
return ERR_AAC_INVALID_ADIF_HEADER;
/* read ADIF header fields */
fhADIF->copyBit = GetBits(&bsi, 1);
if (fhADIF->copyBit) {
for (i = 0; i < ADIF_COPYID_SIZE; i++)
fhADIF->copyID[i] = GetBits(&bsi, 8);
}
fhADIF->origCopy = GetBits(&bsi, 1);
fhADIF->home = GetBits(&bsi, 1);
fhADIF->bsType = GetBits(&bsi, 1);
fhADIF->bitRate = GetBits(&bsi, 23);
fhADIF->numPCE = GetBits(&bsi, 4) + 1; /* add 1 (so range = [1, 16]) */
if (fhADIF->bsType == 0)
fhADIF->bufferFull = GetBits(&bsi, 20);
/* parse all program config elements */
for (i = 0; i < fhADIF->numPCE; i++)
DecodeProgramConfigElement(pce + i, &bsi);
/* byte align */
ByteAlignBitstream(&bsi);
/* update codec info */
psi->nChans = GetNumChannelsADIF(pce, fhADIF->numPCE);
psi->sampRateIdx = GetSampleRateIdxADIF(pce, fhADIF->numPCE);
/* check validity of header */
if (psi->nChans < 0 || psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES)
return ERR_AAC_INVALID_ADIF_HEADER;
/* syntactic element fields will be read from bitstream for each element */
aacDecInfo->prevBlockID = AAC_ID_INVALID;
aacDecInfo->currBlockID = AAC_ID_INVALID;
aacDecInfo->currInstTag = -1;
/* fill in user-accessible data */
aacDecInfo->bitRate = 0;
aacDecInfo->nChans = psi->nChans;
aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx];
aacDecInfo->profile = pce[0].profile;
aacDecInfo->sbrEnabled = 0;
/* update bitstream reader */
bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset);
*buf += (bitsUsed + *bitOffset) >> 3;
*bitOffset = (bitsUsed + *bitOffset) & 0x07;
*bitsAvail -= bitsUsed ;
if (*bitsAvail < 0)
return ERR_AAC_INDATA_UNDERFLOW;
return ERR_AAC_NONE;
}
/**************************************************************************************
* Function: SetRawBlockParams
*
* Description: set internal state variables for decoding a stream of raw data blocks
*
* Inputs: valid AACDecInfo struct
* flag indicating source of parameters (from previous headers or passed
* explicitly by caller)
* number of channels
* sample rate
* profile ID
*
* Outputs: updated state variables in aacDecInfo
*
* Return: 0 if successful, error code (< 0) if error
*
* Notes: if copyLast == 1, then psi->nChans, psi->sampRateIdx, and
* aacDecInfo->profile are not changed (it's assumed that we already
* set them, such as by a previous call to UnpackADTSHeader())
* if copyLast == 0, then the parameters we passed in are used instead
**************************************************************************************/
int SetRawBlockParams(AACDecInfo *aacDecInfo, int copyLast, int nChans, int sampRate, int profile)
{
int idx;
PSInfoBase *psi;
/* validate pointers */
if (!aacDecInfo || !aacDecInfo->psInfoBase)
return ERR_AAC_NULL_POINTER;
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
if (!copyLast) {
aacDecInfo->profile = profile;
psi->nChans = nChans;
for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) {
if (sampRate == sampRateTab[idx]) {
psi->sampRateIdx = idx;
break;
}
}
if (idx == NUM_SAMPLE_RATES)
return ERR_AAC_INVALID_FRAME;
}
aacDecInfo->nChans = psi->nChans;
aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx];
/* check validity of header */
if (psi->sampRateIdx >= NUM_SAMPLE_RATES || psi->sampRateIdx < 0 || aacDecInfo->profile != AAC_PROFILE_LC)
return ERR_AAC_RAWBLOCK_PARAMS;
return ERR_AAC_NONE;
}
/**************************************************************************************
* Function: PrepareRawBlock
*
* Description: reset per-block state variables for raw blocks (no ADTS/ADIF headers)
*
* Inputs: valid AACDecInfo struct
*
* Outputs: updated state variables in aacDecInfo
*
* Return: 0 if successful, error code (< 0) if error
**************************************************************************************/
int PrepareRawBlock(AACDecInfo *aacDecInfo)
{
PSInfoBase *psi;
/* validate pointers */
if (!aacDecInfo || !aacDecInfo->psInfoBase)
return ERR_AAC_NULL_POINTER;
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
/* syntactic element fields will be read from bitstream for each element */
aacDecInfo->prevBlockID = AAC_ID_INVALID;
aacDecInfo->currBlockID = AAC_ID_INVALID;
aacDecInfo->currInstTag = -1;
/* fill in user-accessible data */
aacDecInfo->bitRate = 0;
aacDecInfo->sbrEnabled = 0;
return ERR_AAC_NONE;
}
/**************************************************************************************
* Function: FlushCodec
*
* Description: flush internal codec state (after seeking, for example)
*
* Inputs: valid AACDecInfo struct
*
* Outputs: updated state variables in aacDecInfo
*
* Return: 0 if successful, error code (< 0) if error
*
* Notes: only need to clear data which is persistent between frames
* (such as overlap buffer)
**************************************************************************************/
int FlushCodec(AACDecInfo *aacDecInfo)
{
PSInfoBase *psi;
/* validate pointers */
if (!aacDecInfo || !aacDecInfo->psInfoBase)
return ERR_AAC_NULL_POINTER;
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
ClearBuffer(psi->overlap, AAC_MAX_NCHANS * AAC_MAX_NSAMPS * sizeof(int));
ClearBuffer(psi->prevWinShape, AAC_MAX_NCHANS * sizeof(int));
return ERR_AAC_NONE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -