/*! \brief Set up SBR decoder phase 1 \return Handle */ SBRDECODER openSBR (SBR_DECODER_INSTANCE &sbrDecoderInstance, int sampleRate, int samplesPerFrame, int bDownSample, int bApplyQmfLp) { int i, err; SBR_CHANNEL *SbrChannel = &sbrDecoderInstance.SbrChannel[0]; HANDLE_SBR_HEADER_DATA_DEC hHeaderData = &sbrDecoderInstance.sbr_header; HANDLE_SBR_CONCEAL_DATA hSbrConcealData = &sbrDecoderInstance.SbrConcealData; FLC_sub_start("openSBR"); FloatFR_Init(); /* Not needed for a DSP implementation */ FUNC(3); initHeaderData( hHeaderData, sampleRate, samplesPerFrame); LOOP(1); for (i = 0; i < MAXNRSBRCHANNELS; i++) { FUNC(5); PTR_INIT(1); err = createSbrDec (&(SbrChannel[i]), hHeaderData, i, bApplyQmfLp, sampleRate); BRANCH(1); if (err) { FLC_sub_end(); return NULL; } } LOOP(1); for (i = 0; i < MAXNRQMFCHANNELS; i++) { FUNC(4); PTR_INIT(1); err = createSbrQMF (&(SbrChannel[i]), hHeaderData, i, bDownSample); BRANCH(1); if (err) { FLC_sub_end(); return NULL; } } #ifndef MONO_ONLY FUNC(5); PTR_INIT(1); INDIRECT(3); err = CreatePsDec(&sbrDecoderInstance.ParametricStereoDec, &sbrDecoderInstance.sbr_header, &sbrDecoderInstance.SbrChannel->SbrDec.LppTrans, SbrChannel[0].SbrDec.SynthesisQmfBank.no_col, sbrDecoderInstance.OverlapBuffer); BRANCH(1); if ( err) { FLC_sub_end(); return NULL; } #endif /* #ifndef MONO_ONLY */ PTR_INIT(1); hSbrConcealData->Bitstream = &hSbrConcealData->sbr_PrevBitstream; MOVE(3); hSbrConcealData->FrameOk = 1; hSbrConcealData->Bitstream->NrElements = 1; hSbrConcealData->Bitstream->NrElementsCore = 1; LOOP(1); for (i = 0; i < MAXNRELEMENTS; i++) { MOVE(3); hSbrConcealData->Bitstream->sbrElement[i].ElementID = 0; hSbrConcealData->Bitstream->sbrElement[i].ExtensionType = SBR_EXTENSION; hSbrConcealData->Bitstream->sbrElement[i].Payload = 0; } FUNC(2); LOOP(1); PTR_INIT(1); MOVE(1); STORE(sizeof(sbrDecoderInstance.sbr_header.sbr_OverlapBuffer)/2); memset(sbrDecoderInstance.sbr_header.sbr_OverlapBuffer, 0, sizeof(sbrDecoderInstance.sbr_header.sbr_OverlapBuffer)/2); PTR_INIT(1); FLC_sub_end(); return &sbrDecoderInstance; }
/*! \brief Reset SBR decoder. Reset should only be called if SBR has been sucessfully detected by an appropriate checkForPayload() function. \return Error code. */ static SBR_ERROR sbrDecoder_ResetElement ( HANDLE_SBRDECODER self, int sampleRateIn, int sampleRateOut, int samplesPerFrame, const MP4_ELEMENT_ID elementID, const int elementIndex, const int overlap ) { SBR_ERROR sbrError = SBRDEC_OK; HANDLE_SBR_HEADER_DATA hSbrHeader; UINT qmfFlags = 0; int i, synDownsampleFac; /* Check in/out samplerates */ if ( sampleRateIn < 6400 || sampleRateIn > 48000 ) { sbrError = SBRDEC_UNSUPPORTED_CONFIG; goto bail; } if ( sampleRateOut > 96000 ) { sbrError = SBRDEC_UNSUPPORTED_CONFIG; goto bail; } /* Set QMF mode flags */ if (self->flags & SBRDEC_LOW_POWER) qmfFlags |= QMF_FLAG_LP; if (self->coreCodec == AOT_ER_AAC_ELD) { if (self->flags & SBRDEC_LD_MPS_QMF) { qmfFlags |= QMF_FLAG_MPSLDFB; } else { qmfFlags |= QMF_FLAG_CLDFB; } } /* Set downsampling factor for synthesis filter bank */ if (sampleRateOut == 0) { /* no single rate mode */ sampleRateOut = sampleRateIn<<1; /* In case of implicit signalling, assume dual rate SBR */ } if ( sampleRateIn == sampleRateOut ) { synDownsampleFac = 2; self->flags |= SBRDEC_DOWNSAMPLE; } else { synDownsampleFac = 1; self->flags &= ~SBRDEC_DOWNSAMPLE; } self->synDownsampleFac = synDownsampleFac; self->sampleRateOut = sampleRateOut; { int i; for (i = 0; i < (1)+1; i++) { hSbrHeader = &(self->sbrHeader[elementIndex][i]); /* init a default header such that we can at least do upsampling later */ sbrError = initHeaderData( hSbrHeader, sampleRateIn, sampleRateOut, samplesPerFrame, self->flags ); } } if (sbrError != SBRDEC_OK) { goto bail; } /* Init SBR channels going to be assigned to a SBR element */ { int ch; for (ch=0; ch<self->pSbrElement[elementIndex]->nChannels; ch++) { /* and create sbrDec */ sbrError = createSbrDec (self->pSbrElement[elementIndex]->pSbrChannel[ch], hSbrHeader, &self->pSbrElement[elementIndex]->transposerSettings, synDownsampleFac, qmfFlags, self->flags, overlap, ch ); if (sbrError != SBRDEC_OK) { goto bail; } } } //FDKmemclear(sbr_OverlapBuffer, sizeof(sbr_OverlapBuffer)); if (self->numSbrElements == 1) { switch ( self->coreCodec ) { case AOT_AAC_LC: case AOT_SBR: case AOT_PS: case AOT_ER_AAC_SCAL: case AOT_DRM_AAC: case AOT_DRM_SURROUND: if (CreatePsDec ( &self->hParametricStereoDec, samplesPerFrame )) { sbrError = SBRDEC_CREATE_ERROR; goto bail; } break; default: break; } } /* Init frame delay slot handling */ self->pSbrElement[elementIndex]->useFrameSlot = 0; for (i = 0; i < ((1)+1); i++) { self->pSbrElement[elementIndex]->useHeaderSlot[i] = i; } bail: return sbrError; }