Int32 sbr_crc_check(BIT_BUFFER * hBitBuf, UInt32 NrBits) { Int32 crcResult = 1; BIT_BUFFER BitBufferCRC; UInt32 NrCrcBits; UInt32 crcCheckSum; Int32 i; CRC_BUFFER CrcBuf; UInt32 bValue; Int32 CrcStep; Int32 CrcNrBitsRest; crcCheckSum = buf_getbits(hBitBuf, SI_SBR_CRC_BITS); /* * Copy Bit buffer State */ BitBufferCRC.char_ptr = hBitBuf->char_ptr; BitBufferCRC.buffer_word = hBitBuf->buffer_word; BitBufferCRC.buffered_bits = hBitBuf->buffered_bits; BitBufferCRC.nrBitsRead = hBitBuf->nrBitsRead; BitBufferCRC.bufferLen = hBitBuf->bufferLen; NrCrcBits = min(NrBits, BitBufferCRC.bufferLen - BitBufferCRC.nrBitsRead); CrcStep = NrCrcBits / MAXCRCSTEP; CrcNrBitsRest = (NrCrcBits - CrcStep * MAXCRCSTEP); CrcBuf.crcState = CRCSTART; CrcBuf.crcMask = CRCMASK; CrcBuf.crcPoly = CRCPOLY; for (i = 0; i < CrcStep; i++) { bValue = buf_getbits(&BitBufferCRC, MAXCRCSTEP); check_crc(&CrcBuf, bValue, MAXCRCSTEP); } bValue = buf_getbits(&BitBufferCRC, CrcNrBitsRest); check_crc(&CrcBuf, bValue, CrcNrBitsRest); if ((UInt32)(CrcBuf.crcState & CRCRANGE) != crcCheckSum) { crcResult = 0; } return (crcResult); }
void sbr_get_additional_data(SBR_FRAME_DATA * hFrameData, BIT_BUFFER * hBitBuf) { Int32 i; Int32 flag = buf_getbits(hBitBuf, 1); if (flag) { for (i = 0; i < hFrameData->nSfb[HI]; i++) { hFrameData->addHarmonics[i] = buf_getbits(hBitBuf, 1); } } }
SBR_ERROR sbr_read_data(SBRDECODER_DATA * self, SBR_DEC * sbrDec, SBRBITSTREAM *stream) { SBR_ERROR sbr_err = SBRDEC_OK; int32_t SbrFrameOK = 1; int32_t sbrCRCAlwaysOn = 0; UInt32 bs_header_flag = 0; SBR_HEADER_STATUS headerStatus = HEADER_OK; SBR_CHANNEL *SbrChannel = self->SbrChannel; int32_t zeropadding_bits; BIT_BUFFER bitBuf ; /* * evaluate Bitstream */ bitBuf.buffer_word = 0; bitBuf.buffered_bits = 0; bitBuf.nrBitsRead = 0; bitBuf.char_ptr = stream->sbrElement[0].Data; bitBuf.bufferLen = (stream->sbrElement[0].Payload) << 3; /* * we have to skip a nibble because the first element of Data only * contains a nibble of data ! */ buf_getbits(&bitBuf, LEN_NIBBLE); if ((stream->sbrElement[0].ExtensionType == SBR_EXTENSION_CRC) || sbrCRCAlwaysOn) { int32_t CRCLen = ((stream->sbrElement[0].Payload - 1) << 3) + 4 - SI_SBR_CRC_BITS; SbrFrameOK = sbr_crc_check(&bitBuf, CRCLen); } if (SbrFrameOK) { /* * The sbr data seems ok, if the header flag is set we read the header * and check if vital parameters have changed since the previous frame. * If the syncState equals UPSAMPLING, the SBR Tool has not been * initialised by SBR header data, and can only do upsampling */ bs_header_flag = buf_getbits(&bitBuf, 1); /* read Header flag */ if (bs_header_flag) { /* * If syncState == SBR_ACTIVE, it means that we've had a SBR header * before, and we will compare with the previous header to see if a * reset is required. If the syncState equals UPSAMPLING this means * that the SBR-Tool so far is only initialised to do upsampling * and hence we need to do a reset, and initialise the system * according to the present header. */ headerStatus = sbr_get_header_data(&(SbrChannel[0].frameData.sbr_header), &bitBuf, SbrChannel[0].syncState); } /* if (bs_header_flag) */ switch (stream->sbrElement[0].ElementID) { case SBR_ID_SCE : /* change of control data, reset decoder */ if (headerStatus == HEADER_RESET) { sbr_err = sbr_reset_dec(&(SbrChannel[0].frameData), sbrDec, self->SbrChannel[0].frameData.sbr_header.sampleRateMode); if (sbr_err != SBRDEC_OK) { break; } /* * At this point we have a header and the system has been reset, * hence syncState from now on will be SBR_ACTIVE. */ SbrChannel[0].syncState = SBR_ACTIVE; } if ((SbrChannel[0].syncState == SBR_ACTIVE)) { sbr_err = sbr_get_sce(&(SbrChannel[0].frameData), &bitBuf #ifdef PARAMETRICSTEREO , self->hParametricStereoDec #endif ); if (sbr_err != SBRDEC_OK) { break; } } break; case SBR_ID_CPE : if (bs_header_flag) { pv_memcpy(&(SbrChannel[1].frameData.sbr_header), &(SbrChannel[0].frameData.sbr_header), sizeof(SBR_HEADER_DATA)); } /* change of control data, reset decoder */ if (headerStatus == HEADER_RESET) { for (int32_t lr = 0 ; lr < 2 ; lr++) { sbr_err = sbr_reset_dec(&(SbrChannel[lr].frameData), sbrDec, self->SbrChannel[0].frameData.sbr_header.sampleRateMode); if (sbr_err != SBRDEC_OK) { break; } SbrChannel[lr].syncState = SBR_ACTIVE; } } if (SbrChannel[0].syncState == SBR_ACTIVE) { sbr_err = sbr_get_cpe(&(SbrChannel[0].frameData), &(SbrChannel[1].frameData), &bitBuf); if (sbr_err != SBRDEC_OK) { break; } } break; default: sbr_err = SBRDEC_ILLEGAL_PLUS_ELE_ID; break; } } /* if (SbrFrameOK) */ /* * Check that the bits read did not go beyond SBR frame boundaries */ zeropadding_bits = (8 - (bitBuf.nrBitsRead & 0x7)) & 0x7; if ((bitBuf.nrBitsRead + zeropadding_bits) > bitBuf.bufferLen) { sbr_err = SBRDEC_INVALID_BITSTREAM; } return sbr_err; }
SBR_ERROR extractFrameInfo(BIT_BUFFER * hBitBuf, SBR_FRAME_DATA * h_frame_data) { Int32 absBordLead = 0; Int32 nRelLead = 0; Int32 nRelTrail = 0; Int32 bs_num_env = 0; Int32 bs_num_rel = 0; Int32 bs_var_bord = 0; Int32 bs_var_bord_0 = 0; Int32 bs_var_bord_1 = 0; Int32 bs_pointer = 0; Int32 bs_pointer_bits; Int32 frameClass; Int32 temp; Int32 env; Int32 k; Int32 bs_num_rel_0 = 0; Int32 bs_num_rel_1 = 0; Int32 absBordTrail = 0; Int32 middleBorder = 0; Int32 bs_num_noise; Int32 lA = 0; Int32 tE[MAX_ENVELOPES + 1]; Int32 tQ[2 + 1]; Int32 f[MAX_ENVELOPES + 1]; Int32 bs_rel_bord[3]; Int32 bs_rel_bord_0[3]; Int32 bs_rel_bord_1[3]; Int32 relBordLead[3]; Int32 relBordTrail[3]; Int32 *v_frame_info = h_frame_data->frameInfo; SBR_ERROR err = SBRDEC_OK; /* * First read from the bitstream. */ /* Read frame class */ h_frame_data->frameClass = frameClass = buf_getbits(hBitBuf, SBR_CLA_BITS); switch (frameClass) { case FIXFIX: temp = buf_getbits(hBitBuf, SBR_ENV_BITS); /* 2 bits */ bs_num_env = 1 << temp; f[0] = buf_getbits(hBitBuf, SBR_RES_BITS); /* 1 bit */ for (env = 1; env < bs_num_env; env++) { f[env] = f[0]; } nRelLead = bs_num_env - 1; absBordTrail = 16; break; case FIXVAR: bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_num_rel = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_env = bs_num_rel + 1; for (k = 0; k < bs_num_env - 1; k++) { bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[bs_num_env - 1 - env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordTrail = 16 + bs_var_bord; nRelTrail = bs_num_rel; break; case VARFIX: bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_num_rel = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_env = bs_num_rel + 1; for (k = 0; k < bs_num_env - 1; k++) { bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordTrail = 16; absBordLead = bs_var_bord; nRelLead = bs_num_rel; break; case VARVAR: bs_var_bord_0 = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_var_bord_1 = buf_getbits(hBitBuf, SBR_ABS_BITS); bs_num_rel_0 = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_rel_1 = buf_getbits(hBitBuf, SBR_NUM_BITS); bs_num_env = bs_num_rel_0 + bs_num_rel_1 + 1; for (k = 0; k < bs_num_rel_0; k++) { /* 2 bits */ bs_rel_bord_0[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } for (k = 0; k < bs_num_rel_1; k++) { /* 2 bits */ bs_rel_bord_1[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordLead = bs_var_bord_0; absBordTrail = 16 + bs_var_bord_1; nRelLead = bs_num_rel_0; nRelTrail = bs_num_rel_1; break; }; /* * Calculate the framing. */ switch (frameClass) { case FIXFIX: for (k = 0; k < nRelLead; k++) { relBordLead[k] = T_16_ov_bs_num_env_tbl[bs_num_env]; } break; case VARFIX: for (k = 0; k < nRelLead; k++) { relBordLead[k] = bs_rel_bord[k]; } break; case VARVAR: for (k = 0; k < nRelLead; k++) { relBordLead[k] = bs_rel_bord_0[k]; } for (k = 0; k < nRelTrail; k++) { relBordTrail[k] = bs_rel_bord_1[k]; } break; case FIXVAR: for (k = 0; k < nRelTrail; k++) { relBordTrail[k] = bs_rel_bord[k]; } break; } tE[0] = absBordLead; tE[bs_num_env] = absBordTrail; for (env = 1; env <= nRelLead; env++) { tE[env] = absBordLead; for (k = 0; k <= env - 1; k++) { tE[env] += relBordLead[k]; } } for (env = nRelLead + 1; env < bs_num_env; env++) { tE[env] = absBordTrail; for (k = 0; k <= bs_num_env - env - 1; k++) { tE[env] -= relBordTrail[k]; } } switch (frameClass) { case FIXFIX: middleBorder = bs_num_env >> 1; break; case VARFIX: switch (bs_pointer) { case 0: middleBorder = 1; break; case 1: middleBorder = bs_num_env - 1; break; default: middleBorder = bs_pointer - 1; break; }; break; case FIXVAR: case VARVAR: switch (bs_pointer) { case 0: case 1: middleBorder = bs_num_env - 1; break; default: middleBorder = bs_num_env + 1 - bs_pointer; break; }; break; }; tQ[0] = tE[0]; if (bs_num_env > 1) { tQ[1] = tE[middleBorder]; tQ[2] = tE[bs_num_env]; bs_num_noise = 2; } else { tQ[1] = tE[bs_num_env]; bs_num_noise = 1; } /* * Check consistency on freq bands */ if ((tE[bs_num_env] < tE[0]) || (tE[0] < 0)) { err = SBRDEC_INVALID_BITSTREAM; } switch (frameClass) { case FIXFIX: lA = -1; break; case VARFIX: switch (bs_pointer) { case 0: case 1: lA = -1; break; default: lA = bs_pointer - 1; break; }; break; case FIXVAR: case VARVAR: switch (bs_pointer) { case 0: lA = - 1; break; default: lA = bs_num_env + 1 - bs_pointer; break; }; break; }; /* * Build the frameInfo vector... */ v_frame_info[0] = bs_num_env; /* Number of envelopes*/ pv_memcpy(v_frame_info + 1, tE, (bs_num_env + 1)*sizeof(Int32)); /* time borders*/ /* frequency resolution */ pv_memcpy(v_frame_info + 1 + bs_num_env + 1, f, bs_num_env*sizeof(Int32)); temp = (1 + bs_num_env) << 1; v_frame_info[temp] = lA; /* transient envelope*/ v_frame_info[temp + 1] = bs_num_noise; /* Number of noise envelopes */ /* noise borders */ pv_memcpy(v_frame_info + temp + 2, tQ, (bs_num_noise + 1)*sizeof(Int32)); return (err); }
SBR_ERROR sbr_get_cpe(SBR_FRAME_DATA * hFrameDataLeft, SBR_FRAME_DATA * hFrameDataRight, BIT_BUFFER * hBitBuf) { Int32 i; Int32 bits; SBR_ERROR err = SBRDEC_OK; /* reserved bits */ bits = buf_getbits(hBitBuf, SI_SBR_RESERVED_PRESENT); if (bits) { buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA); buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA); } /* Read coupling flag */ bits = buf_getbits(hBitBuf, SI_SBR_COUPLING_BITS); if (bits) { hFrameDataLeft->coupling = COUPLING_LEVEL; hFrameDataRight->coupling = COUPLING_BAL; } else { hFrameDataLeft->coupling = COUPLING_OFF; hFrameDataRight->coupling = COUPLING_OFF; } err = extractFrameInfo(hBitBuf, hFrameDataLeft); if (err != SBRDEC_OK) { return err; } if (hFrameDataLeft->coupling) { pv_memcpy(hFrameDataRight->frameInfo, hFrameDataLeft->frameInfo, LENGTH_FRAME_INFO * sizeof(Int32)); hFrameDataRight->nNoiseFloorEnvelopes = hFrameDataLeft->nNoiseFloorEnvelopes; hFrameDataRight->frameClass = hFrameDataLeft->frameClass; sbr_get_dir_control_data(hFrameDataLeft, hBitBuf); sbr_get_dir_control_data(hFrameDataRight, hBitBuf); for (i = 0; i < hFrameDataLeft->nNfb; i++) { hFrameDataLeft->sbr_invf_mode_prev[i] = hFrameDataLeft->sbr_invf_mode[i]; hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i]; hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i]; } sbr_get_envelope(hFrameDataLeft, hBitBuf); sbr_get_noise_floor_data(hFrameDataLeft, hBitBuf); sbr_get_envelope(hFrameDataRight, hBitBuf); } else { err = extractFrameInfo(hBitBuf, hFrameDataRight); if (err != SBRDEC_OK) { return err; } sbr_get_dir_control_data(hFrameDataLeft, hBitBuf); sbr_get_dir_control_data(hFrameDataRight, hBitBuf); for (i = 0; i < hFrameDataLeft->nNfb; i++) { hFrameDataLeft->sbr_invf_mode_prev[i] = hFrameDataLeft->sbr_invf_mode[i]; hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); } for (i = 0; i < hFrameDataRight->nNfb; i++) { hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i]; hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); } sbr_get_envelope(hFrameDataLeft, hBitBuf); sbr_get_envelope(hFrameDataRight, hBitBuf); sbr_get_noise_floor_data(hFrameDataLeft, hBitBuf); } sbr_get_noise_floor_data(hFrameDataRight, hBitBuf); pv_memset((void *)hFrameDataLeft->addHarmonics, 0, hFrameDataLeft->nSfb[HI]*sizeof(Int32)); pv_memset((void *)hFrameDataRight->addHarmonics, 0, hFrameDataRight->nSfb[HI]*sizeof(Int32)); sbr_get_additional_data(hFrameDataLeft, hBitBuf); sbr_get_additional_data(hFrameDataRight, hBitBuf); sbr_extract_extended_data(hBitBuf // 2010.01.26 : // in order to detect ps tag in adts/adif but decoding it // we remove this definition ////#ifdef PARAMETRICSTEREO , NULL ////#endif ); return SBRDEC_OK; }
SBR_HEADER_STATUS sbr_get_header_data(SBR_HEADER_DATA * h_sbr_header, BIT_BUFFER * hBitBuf, SBR_SYNC_STATE syncState) { SBR_HEADER_DATA lastHeader; Int32 headerExtra1, headerExtra2; /* Copy header to temporary header */ if (syncState == SBR_ACTIVE) { pv_memcpy(&lastHeader, h_sbr_header, sizeof(SBR_HEADER_DATA)); } else { pv_memset((void *)&lastHeader, 0, sizeof(SBR_HEADER_DATA)); } /* Read new header from bitstream */ h_sbr_header->ampResolution = buf_getbits(hBitBuf, SI_SBR_AMP_RES_BITS); h_sbr_header->startFreq = buf_getbits(hBitBuf, SI_SBR_START_FREQ_BITS); h_sbr_header->stopFreq = buf_getbits(hBitBuf, SI_SBR_STOP_FREQ_BITS); h_sbr_header->xover_band = buf_getbits(hBitBuf, SI_SBR_XOVER_BAND_BITS); buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_HDR); headerExtra1 = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_1_BITS); headerExtra2 = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_2_BITS); /* handle extra header information */ if (headerExtra1) { h_sbr_header->freqScale = buf_getbits(hBitBuf, SI_SBR_FREQ_SCALE_BITS); h_sbr_header->alterScale = buf_getbits(hBitBuf, SI_SBR_ALTER_SCALE_BITS); h_sbr_header->noise_bands = buf_getbits(hBitBuf, SI_SBR_NOISE_BANDS_BITS); } else { /* Set default values.*/ h_sbr_header->freqScale = SBR_FREQ_SCALE_DEFAULT; h_sbr_header->alterScale = SBR_ALTER_SCALE_DEFAULT; h_sbr_header->noise_bands = SBR_NOISE_BANDS_DEFAULT; } if (headerExtra2) { h_sbr_header->limiterBands = buf_getbits(hBitBuf, SI_SBR_LIMITER_BANDS_BITS); h_sbr_header->limiterGains = buf_getbits(hBitBuf, SI_SBR_LIMITER_GAINS_BITS); h_sbr_header->interpolFreq = buf_getbits(hBitBuf, SI_SBR_INTERPOL_FREQ_BITS); h_sbr_header->smoothingLength = buf_getbits(hBitBuf, SI_SBR_SMOOTHING_LENGTH_BITS); } else { /* Set default values.*/ h_sbr_header->limiterBands = SBR_LIMITER_BANDS_DEFAULT; h_sbr_header->limiterGains = SBR_LIMITER_GAINS_DEFAULT; h_sbr_header->interpolFreq = SBR_INTERPOL_FREQ_DEFAULT; h_sbr_header->smoothingLength = SBR_SMOOTHING_LENGTH_DEFAULT; } if (syncState == SBR_ACTIVE) { h_sbr_header->status = HEADER_OK; /* look for new settings */ if (lastHeader.startFreq != h_sbr_header->startFreq || lastHeader.stopFreq != h_sbr_header->stopFreq || lastHeader.xover_band != h_sbr_header->xover_band || lastHeader.freqScale != h_sbr_header->freqScale || lastHeader.alterScale != h_sbr_header->alterScale || lastHeader.noise_bands != h_sbr_header->noise_bands) { h_sbr_header->status = HEADER_RESET; } } else { h_sbr_header->status = HEADER_RESET; } return h_sbr_header->status; }
void sbr_extract_extended_data(BIT_BUFFER * hBitBuf #ifdef PARAMETRICSTEREO /* Parametric Stereo Decoder */ , HANDLE_PS_DEC hParametricStereoDec #endif ) { Int32 extended_data; Int32 i; Int32 nBitsLeft; Int32 extension_id; extended_data = buf_get_1bit(hBitBuf); /* SI_SBR_EXTENDED_DATA_BITS */ if (extended_data) { Int32 cnt; cnt = buf_getbits(hBitBuf, SI_SBR_EXTENSION_SIZE_BITS); if (cnt == (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1) { cnt += buf_getbits(hBitBuf, SI_SBR_EXTENSION_ESC_COUNT_BITS); } nBitsLeft = (cnt << 3); while (nBitsLeft > 7) { extension_id = buf_getbits(hBitBuf, SI_SBR_EXTENSION_ID_BITS); nBitsLeft -= SI_SBR_EXTENSION_ID_BITS; switch (extension_id) { #ifdef HQ_SBR #ifdef PARAMETRICSTEREO /* * Parametric Coding supports the Transient, Sinusoidal, Noise, and * Parametric Stereo tools (MPEG4). * 3GPP use aac+ hq along with ps for enhanced aac+ * The PS tool uses complex-value QMF data, therefore can not be used * with low power version of aac+ */ case EXTENSION_ID_PS_CODING: if (hParametricStereoDec != NULL) { if (!hParametricStereoDec->psDetected) { /* parametric stereo detected */ hParametricStereoDec->psDetected = 1; } nBitsLeft -= ps_read_data(hParametricStereoDec, hBitBuf, nBitsLeft); } break; #endif #endif case 0: default: /* An unknown extension id causes the remaining extension data * to be skipped */ cnt = nBitsLeft >> 3; /* number of remaining bytes */ for (i = 0; i < cnt; i++) { buf_getbits(hBitBuf, 8); } nBitsLeft -= (cnt << 3); } } /* read fill bits for byte alignment */ buf_getbits(hBitBuf, nBitsLeft); } }