| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 | 
							- /* ***** BEGIN LICENSE BLOCK *****  
 
-  * Source last modified: $Id: sbr.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ 
 
-  *   
 
-  * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.  
 
-  *       
 
-  * The contents of this file, and the files included with this file, 
 
-  * are subject to the current version of the RealNetworks Public 
 
-  * Source License (the "RPSL") available at 
 
-  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 
-  * the file under the current version of the RealNetworks Community 
 
-  * Source License (the "RCSL") available at 
 
-  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL 
 
-  * will apply. You may also obtain the license terms directly from 
 
-  * RealNetworks.  You may not use this file except in compliance with 
 
-  * the RPSL or, if you have a valid RCSL with RealNetworks applicable 
 
-  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for 
 
-  * the rights, obligations and limitations governing use of the 
 
-  * contents of the file. 
 
-  *   
 
-  * This file is part of the Helix DNA Technology. RealNetworks is the 
 
-  * developer of the Original Code and owns the copyrights in the 
 
-  * portions it created. 
 
-  *   
 
-  * This file, and the files included with this file, is distributed 
 
-  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY 
 
-  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS 
 
-  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES 
 
-  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET 
 
-  * ENJOYMENT OR NON-INFRINGEMENT. 
 
-  *  
 
-  * Technology Compatibility Kit Test Suite(s) Location:  
 
-  *    http://www.helixcommunity.org/content/tck  
 
-  *  
 
-  * Contributor(s):  
 
-  *   
 
-  * ***** END LICENSE BLOCK ***** */  
 
- /**************************************************************************************
 
-  * Fixed-point HE-AAC decoder
 
-  * Jon Recker (jrecker@real.com)
 
-  * February 2005
 
-  *
 
-  * sbr.c - top level functions for SBR
 
-  **************************************************************************************/
 
- #if defined(USE_DEFAULT_STDLIB) || defined(ESP_PLATFORM)
 
- #include <stdio.h>
 
- #include <stdlib.h>
 
- #else
 
- #include "hlxclib/stdlib.h"
 
- #endif
 
- #include "sbr.h"
 
- /**************************************************************************************
 
-  * Function:    InitSBRState
 
-  *
 
-  * Description: initialize PSInfoSBR struct at start of stream or after flush
 
-  *
 
-  * Inputs:      valid AACDecInfo struct
 
-  *
 
-  * Outputs:     PSInfoSBR struct with proper initial state
 
-  *
 
-  * Return:      none
 
-  **************************************************************************************/
 
- static void InitSBRState(PSInfoSBR *psi)
 
- {
 
- 	int i, ch;
 
- 	unsigned char *c;
 
- 	if (!psi)
 
- 		return;
 
- 	/* clear SBR state structure */
 
- 	c = (unsigned char *)psi;
 
- 	for (i = 0; i < (int)sizeof(PSInfoSBR); i++)
 
- 		*c++ = 0;
 
- 	/* initialize non-zero state variables */
 
- 	for (ch = 0; ch < AAC_MAX_NCHANS; ch++) {
 
- 		psi->sbrChan[ch].reset = 1;
 
- 		psi->sbrChan[ch].laPrev = -1;
 
- 	}
 
- }
 
-  
 
- /**************************************************************************************
 
-  * Function:    InitSBR
 
-  *
 
-  * Description: initialize SBR decoder
 
-  *
 
-  * Inputs:      valid AACDecInfo struct
 
-  *
 
-  * Outputs:     PSInfoSBR struct to hold SBR state information
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  *
 
-  * Note:        memory allocation for SBR is only done here
 
-  **************************************************************************************/
 
- int InitSBR(AACDecInfo *aacDecInfo)
 
- {
 
- 	PSInfoSBR *psi;
 
- 	if (!aacDecInfo)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	/* allocate SBR state structure */
 
- 	psi = (PSInfoSBR *)malloc(sizeof(PSInfoSBR));
 
- 	if (!psi) {
 
- 		printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR));
 
- 		return ERR_AAC_SBR_INIT;
 
- 	}
 
- 	InitSBRState(psi);
 
- 	aacDecInfo->psInfoSBR = psi;
 
- 	return ERR_AAC_NONE;
 
- }
 
- int InitSBRPre(AACDecInfo *aacDecInfo, void **ptr, int *sz)
 
- {
 
-         PSInfoSBR *psi;
 
-         if (!aacDecInfo)
 
-                 return ERR_AAC_NULL_POINTER;
 
-         /* allocate SBR state structure */
 
-         psi = (PSInfoSBR *)*ptr;
 
-         *sz -= sizeof(PSInfoSBR);
 
-         if (*sz < 0) {
 
-                 printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR));
 
-                 return ERR_AAC_SBR_INIT;
 
-         }
 
-         InitSBRState(psi);
 
- 	*ptr = (void*)((char*)(*ptr) + sizeof(PSInfoSBR));
 
-         aacDecInfo->psInfoSBR = psi;
 
-         return ERR_AAC_NONE;
 
- }
 
- /**************************************************************************************
 
-  * Function:    FreeSBR
 
-  *
 
-  * Description: free SBR decoder
 
-  *
 
-  * Inputs:      valid AACDecInfo struct
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      none
 
-  *
 
-  * Note:        memory deallocation for SBR is only done here
 
-  **************************************************************************************/
 
- void FreeSBR(AACDecInfo *aacDecInfo)
 
- {
 
- 	if (aacDecInfo && aacDecInfo->psInfoSBR)
 
- 		free(aacDecInfo->psInfoSBR);
 
- 	return;
 
- }
 
- /**************************************************************************************
 
-  * Function:    DecodeSBRBitstream
 
-  *
 
-  * Description: decode sideband information for SBR
 
-  *
 
-  * Inputs:      valid AACDecInfo struct
 
-  *              fill buffer with SBR extension block
 
-  *              number of bytes in fill buffer
 
-  *              base output channel (range = [0, nChans-1])
 
-  *
 
-  * Outputs:     initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan)
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  *
 
-  * Notes:       SBR payload should be in aacDecInfo->fillBuf
 
-  *              returns with no error if fill buffer is not an SBR extension block, 
 
-  *                or if current block is not a fill block (e.g. for LFE upsampling)
 
-  **************************************************************************************/
 
- int DecodeSBRBitstream(AACDecInfo *aacDecInfo, int chBase)
 
- {
 
- 	int headerFlag;
 
- 	BitStreamInfo bsi;
 
- 	PSInfoSBR *psi;
 
- 	/* validate pointers */
 
- 	if (!aacDecInfo || !aacDecInfo->psInfoSBR)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR);
 
- 	if (aacDecInfo->currBlockID != AAC_ID_FIL || (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC))
 
- 		return ERR_AAC_NONE;
 
- 	SetBitstreamPointer(&bsi, aacDecInfo->fillCount, aacDecInfo->fillBuf);
 
- 	if (GetBits(&bsi, 4) != (unsigned int)aacDecInfo->fillExtType)
 
- 		return ERR_AAC_SBR_BITSTREAM;
 
- 	
 
- 	if (aacDecInfo->fillExtType == EXT_SBR_DATA_CRC)
 
- 		psi->crcCheckWord = GetBits(&bsi, 10);
 
- 	headerFlag = GetBits(&bsi, 1);
 
- 	if (headerFlag) {
 
- 		/* get sample rate index for output sample rate (2x base rate) */
 
- 		psi->sampRateIdx = GetSampRateIdx(2 * aacDecInfo->sampRate);
 
- 		if (psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES)
 
- 			return ERR_AAC_SBR_BITSTREAM;
 
- 		else if (psi->sampRateIdx >= NUM_SAMPLE_RATES_SBR)
 
- 			return ERR_AAC_SBR_SINGLERATE_UNSUPPORTED;
 
- 		/* reset flag = 1 if header values changed */
 
- 		if (UnpackSBRHeader(&bsi, &(psi->sbrHdr[chBase])))
 
- 			psi->sbrChan[chBase].reset = 1;
 
- 	
 
- 		/* first valid SBR header should always trigger CalcFreqTables(), since psi->reset was set in InitSBR() */
 
- 		if (psi->sbrChan[chBase].reset)
 
- 			CalcFreqTables(&(psi->sbrHdr[chBase+0]), &(psi->sbrFreq[chBase]), psi->sampRateIdx);
 
- 		/* copy and reset state to right channel for CPE */
 
- 		if (aacDecInfo->prevBlockID == AAC_ID_CPE)
 
- 			psi->sbrChan[chBase+1].reset = psi->sbrChan[chBase+0].reset;
 
- 	}
 
- 	
 
- 	/* if no header has been received, upsample only */
 
- 	if (psi->sbrHdr[chBase].count == 0)
 
- 		return ERR_AAC_NONE;
 
- 	if (aacDecInfo->prevBlockID == AAC_ID_SCE) {
 
- 		UnpackSBRSingleChannel(&bsi, psi, chBase);
 
- 	} else if (aacDecInfo->prevBlockID == AAC_ID_CPE) {
 
- 		UnpackSBRChannelPair(&bsi, psi, chBase);
 
- 	} else {
 
- 		return ERR_AAC_SBR_BITSTREAM;
 
- 	}
 
- 	ByteAlignBitstream(&bsi);
 
- 	return ERR_AAC_NONE;
 
- }
 
- /**************************************************************************************
 
-  * Function:    DecodeSBRData
 
-  *
 
-  * Description: apply SBR to one frame of PCM data
 
-  *
 
-  * Inputs:      1024 samples of decoded 32-bit PCM, before SBR
 
-  *              size of input PCM samples (must be 4 bytes)
 
-  *              number of fraction bits in input PCM samples
 
-  *              base output channel (range = [0, nChans-1])
 
-  *              initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan)
 
-  *
 
-  * Outputs:     2048 samples of decoded 16-bit PCM, after SBR
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  **************************************************************************************/
 
- int DecodeSBRData(AACDecInfo *aacDecInfo, int chBase, short *outbuf)
 
- {
 
- 	int k, l, ch, chBlock, qmfaBands, qmfsBands;
 
- 	int upsampleOnly, gbIdx, gbMask;
 
- 	int *inbuf;
 
- 	short *outptr;
 
- 	PSInfoSBR *psi;
 
- 	SBRHeader *sbrHdr;
 
- 	SBRGrid *sbrGrid;
 
- 	SBRFreq *sbrFreq;
 
- 	SBRChan *sbrChan;
 
- 	/* validate pointers */
 
- 	if (!aacDecInfo || !aacDecInfo->psInfoSBR)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR);
 
- 	
 
- 	/* same header and freq tables for both channels in CPE */
 
- 	sbrHdr =  &(psi->sbrHdr[chBase]);
 
- 	sbrFreq = &(psi->sbrFreq[chBase]);
 
- 	/* upsample only if we haven't received an SBR header yet or if we have an LFE block */
 
- 	if (aacDecInfo->currBlockID == AAC_ID_LFE) {
 
- 		chBlock = 1;
 
- 		upsampleOnly = 1;
 
- 	} else if (aacDecInfo->currBlockID == AAC_ID_FIL) {
 
- 		if (aacDecInfo->prevBlockID == AAC_ID_SCE) 
 
- 			chBlock = 1;
 
- 		else if (aacDecInfo->prevBlockID == AAC_ID_CPE)
 
- 			chBlock = 2;
 
- 		else
 
- 			return ERR_AAC_NONE;
 
- 		
 
- 		upsampleOnly = (sbrHdr->count == 0 ? 1 : 0);
 
- 		if (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC)
 
- 			return ERR_AAC_NONE;
 
- 	} else {
 
- 		/* ignore non-SBR blocks */
 
- 		return ERR_AAC_NONE;
 
- 	}
 
- 	if (upsampleOnly) {
 
- 		sbrFreq->kStart = 32;
 
- 		sbrFreq->numQMFBands = 0;
 
- 	}
 
- 	for (ch = 0; ch < chBlock; ch++) {
 
- 		sbrGrid = &(psi->sbrGrid[chBase + ch]);	
 
- 		sbrChan = &(psi->sbrChan[chBase + ch]);
 
- 		if (aacDecInfo->rawSampleBuf[ch] == 0 || aacDecInfo->rawSampleBytes != 4)
 
- 			return ERR_AAC_SBR_PCM_FORMAT;
 
- 		inbuf = (int *)aacDecInfo->rawSampleBuf[ch];
 
- 		outptr = outbuf + chBase + ch;
 
- 		/* restore delay buffers (could use ring buffer or keep in temp buffer for nChans == 1) */
 
- 		for (l = 0; l < HF_GEN; l++) {
 
- 			for (k = 0; k < 64; k++) {
 
- 				psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0];
 
- 				psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1];
 
- 			}
 
- 		}
 
- 		/* step 1 - analysis QMF */
 
- 		qmfaBands = sbrFreq->kStart;
 
- 		for (l = 0; l < 32; l++) {
 
- 			gbMask = QMFAnalysis(inbuf + l*32, psi->delayQMFA[chBase + ch], psi->XBuf[l + HF_GEN][0], 
 
- 				aacDecInfo->rawSampleFBits, &(psi->delayIdxQMFA[chBase + ch]), qmfaBands);
 
- 			gbIdx = ((l + HF_GEN) >> 5) & 0x01;	
 
- 			sbrChan->gbMask[gbIdx] |= gbMask;	/* gbIdx = (0 if i < 32), (1 if i >= 32) */
 
- 		}
 
- 		if (upsampleOnly) {
 
- 			/* no SBR - just run synthesis QMF to upsample by 2x */
 
- 			qmfsBands = 32;
 
- 			for (l = 0; l < 32; l++) {
 
- 				/* step 4 - synthesis QMF */
 
- 				QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans);
 
- 				outptr += 64*aacDecInfo->nChans;
 
- 			}
 
- 		} else {
 
- 			/* if previous frame had lower SBR starting freq than current, zero out the synthesized QMF
 
- 			 *   bands so they aren't used as sources for patching
 
- 			 * after patch generation, restore from delay buffer
 
- 			 * can only happen after header reset
 
- 			 */
 
- 			for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
 
- 				for (l = 0; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
 
- 					psi->XBuf[l][k][0] = 0;
 
- 					psi->XBuf[l][k][1] = 0;
 
- 				}
 
- 			}
 
- 			/* step 2 - HF generation */
 
- 			GenerateHighFreq(psi, sbrGrid, sbrFreq, sbrChan, ch);
 
- 			/* restore SBR bands that were cleared before patch generation (time slots 0, 1 no longer needed) */
 
- 			for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
 
- 				for (l = HF_ADJ; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
 
- 					psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0];
 
- 					psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1];
 
- 				}
 
- 			}
 
- 			/* step 3 - HF adjustment */
 
- 			AdjustHighFreq(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch);
 
- 			/* step 4 - synthesis QMF */
 
- 			qmfsBands = sbrFreq->kStartPrev + sbrFreq->numQMFBandsPrev;
 
- 			for (l = 0; l < sbrGrid->envTimeBorder[0]; l++) {
 
- 				/* if new envelope starts mid-frame, use old settings until start of first envelope in this frame */
 
- 				QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans);
 
- 				outptr += 64*aacDecInfo->nChans;
 
- 			}
 
- 			qmfsBands = sbrFreq->kStart + sbrFreq->numQMFBands;
 
- 			for (     ; l < 32; l++) {
 
- 				/* use new settings for rest of frame (usually the entire frame, unless the first envelope starts mid-frame) */
 
- 				QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans);
 
- 				outptr += 64*aacDecInfo->nChans;
 
- 			}
 
- 		}
 
- 		/* save delay */
 
- 		for (l = 0; l < HF_GEN; l++) {
 
- 			for (k = 0; k < 64; k++) {		
 
- 				psi->XBufDelay[chBase + ch][l][k][0] = psi->XBuf[l+32][k][0];
 
- 				psi->XBufDelay[chBase + ch][l][k][1] = psi->XBuf[l+32][k][1];
 
- 			}
 
- 		}
 
- 		sbrChan->gbMask[0] = sbrChan->gbMask[1];
 
- 		sbrChan->gbMask[1] = 0;
 
- 		if (sbrHdr->count > 0)
 
- 			sbrChan->reset = 0;
 
- 	}
 
- 	sbrFreq->kStartPrev = sbrFreq->kStart;
 
- 	sbrFreq->numQMFBandsPrev = sbrFreq->numQMFBands;
 
- 	if (aacDecInfo->nChans > 0 && (chBase + ch) == aacDecInfo->nChans)
 
- 		psi->frameCount++;
 
- 	return ERR_AAC_NONE;
 
- }
 
- /**************************************************************************************
 
-  * Function:    FlushCodecSBR
 
-  *
 
-  * Description: flush internal SBR codec state (after seeking, for example)
 
-  *
 
-  * Inputs:      valid AACDecInfo struct
 
-  *
 
-  * Outputs:     updated state variables for SBR
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  *
 
-  * Notes:       SBR is heavily dependent on state from previous frames
 
-  *                (e.g. delta coded scalefactors, previous envelope boundaries, etc.)
 
-  *              On flush, we reset everything as if SBR had just been initialized
 
-  *                for the first time. This triggers "upsample-only" mode until
 
-  *                the first valid SBR header is received. Then SBR starts as usual.
 
-  **************************************************************************************/
 
- int FlushCodecSBR(AACDecInfo *aacDecInfo)
 
- {
 
- 	PSInfoSBR *psi;
 
- 	/* validate pointers */
 
- 	if (!aacDecInfo || !aacDecInfo->psInfoSBR)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR);
 
- 	InitSBRState(psi);
 
- 	return 0;
 
- }
 
 
  |