sbr_info *sbrDecodeInit() { uint8_t ch,j; sbr_info *sbr = malloc(sizeof(sbr_info)); if(!sbr) return sbr; memset(sbr, 0, sizeof(sbr_info)); sbr->bs_freq_scale = 2; sbr->bs_alter_scale = 1; sbr->bs_noise_bands = 2; sbr->bs_limiter_bands = 2; sbr->bs_limiter_gains = 2; sbr->bs_interpol_freq = 1; sbr->bs_smoothing_mode = 1; sbr->bs_start_freq = 5; sbr->bs_amp_res = 1; sbr->bs_samplerate_mode = 1; sbr->prevEnvIsShort[0] = -1; sbr->prevEnvIsShort[1] = -1; sbr->header_count = 0; for(ch=0;ch<2;ch++){ sbr->qmfa[ch] = qmfa_init(32); sbr->qmfs[ch] = qmfs_init(64); if(!sbr->qmfa[ch] || !sbr->qmfs[ch]) goto err_out; for (j = 0; j < 5; j++){ sbr->G_temp_prev[ch][j] = malloc(64*sizeof(real_t)); sbr->Q_temp_prev[ch][j] = malloc(64*sizeof(real_t)); if(!sbr->G_temp_prev[ch][j] || !sbr->Q_temp_prev[ch][j]) goto err_out; } sbr->Xsbr[ch] = malloc((32+tHFGen)*64 * sizeof(qmf_t)); sbr->Xcodec[ch] = malloc((32+tHFGen)*32 * sizeof(qmf_t)); if(!sbr->Xsbr[ch] || !sbr->Xcodec[ch]) goto err_out; memset(sbr->Xsbr[ch], 0, (32+tHFGen)*64 * sizeof(qmf_t)); memset(sbr->Xcodec[ch], 0, (32+tHFGen)*32 * sizeof(qmf_t)); } return sbr; err_out: sbrDecodeEnd(sbr); free(sbr); return NULL; }
uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel, const uint8_t just_seeked, const uint8_t upsample_only) { uint8_t dont_process = 0; uint8_t ret = 0; ALIGN qmf_t X_mono[MAX_NTSR][64]; ALIGN qmf_t X_left[MAX_NTSR][64]; ALIGN qmf_t X_right[MAX_NTSR][64]; if (sbr == NULL) return 20; /* case can occur due to bit errors */ if (sbr->id_aac != ID_SCE && sbr->id_aac != ID_LFE) return 21; if (sbr->ret || (sbr->header_count == 0)) { /* don't process just upsample */ dont_process = 1; /* Re-activate reset for next frame */ if (sbr->ret && sbr->Reset) sbr->bs_start_freq_prev = -1; } if (just_seeked) { sbr->just_seeked = 1; } else { sbr->just_seeked = 0; } if (sbr->frame == 0) { sbr->qmfs[1] = qmfs_init(64); } sbr_process_channel(sbr, left_channel, X_mono, 0, dont_process); /* perform parametric stereo */ ps_dummy_function(X_mono, X_left, X_right); /* subband synthesis */ #ifndef USE_SSE sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X_left, left_channel); sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X_right, right_channel); #else sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[0], X_left, left_channel); sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[1], X_right, right_channel); #endif if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0 && sbr->ret == 0) { ret = sbr_save_prev_data(sbr, 0); if (ret) return ret; } sbr->frame++; return 0; }
static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_NTSR][64], uint8_t ch, uint8_t dont_process) { int16_t i, k, l; #ifdef SBR_LOW_POWER ALIGN real_t deg[64]; #endif if (sbr->frame == 0) { uint8_t j; sbr->qmfa[ch] = qmfa_init(32); sbr->qmfs[ch] = qmfs_init(64); for (j = 0; j < 5; j++) { sbr->G_temp_prev[ch][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[ch][j] = faad_malloc(64*sizeof(real_t)); } memset(sbr->Xsbr[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); memset(sbr->Xcodec[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*32 * sizeof(qmf_t)); } /* subband analysis */ if (dont_process) sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], channel_buf, sbr->Xcodec[ch], sbr->tHFGen, 32); else sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], channel_buf, sbr->Xcodec[ch], sbr->tHFGen, sbr->kx); if (!dont_process) { #if 1 /* insert high frequencies here */ /* hf generation using patching */ hf_generation(sbr, sbr->Xcodec[ch], sbr->Xsbr[ch] #ifdef SBR_LOW_POWER ,deg #endif ,ch); #endif #ifdef SBR_LOW_POWER for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++) { for (k = 0; k < sbr->kx; k++) { QMF_RE(sbr->Xsbr[ch][sbr->tHFAdj + l][k]) = 0; } } #endif #if 1 /* hf adjustment */ hf_adjustment(sbr, sbr->Xsbr[ch] #ifdef SBR_LOW_POWER ,deg #endif ,ch); #endif } if ((sbr->just_seeked != 0) || dont_process) { for (l = 0; l < sbr->numTimeSlotsRate; l++) { for (k = 0; k < 32; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xcodec[ch][l + sbr->tHFAdj][k]); #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = QMF_IM(sbr->Xcodec[ch][l + sbr->tHFAdj][k]); #endif } for (k = 32; k < 64; k++) { QMF_RE(X[l][k]) = 0; #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = 0; #endif } } } else { for (l = 0; l < sbr->numTimeSlotsRate; l++) { uint8_t xover_band; if (l < sbr->t_E[ch][0]) xover_band = sbr->kx_prev; else xover_band = sbr->kx; for (k = 0; k < xover_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xcodec[ch][l + sbr->tHFAdj][k]); #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = QMF_IM(sbr->Xcodec[ch][l + sbr->tHFAdj][k]); #endif } for (k = xover_band; k < 64; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); #endif } #ifdef SBR_LOW_POWER QMF_RE(X[l][xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][xover_band - 1]); #endif } } for (i = 0; i < sbr->tHFGen; i++) { memmove(sbr->Xcodec[ch][i], sbr->Xcodec[ch][i+sbr->numTimeSlotsRate], 32 * sizeof(qmf_t)); memmove(sbr->Xsbr[ch][i], sbr->Xsbr[ch][i+sbr->numTimeSlotsRate], 64 * sizeof(qmf_t)); } }
uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel, const uint8_t just_seeked, const uint8_t downSampledSBR) { uint8_t l, k; uint8_t dont_process = 0; uint8_t ret = 0; ALIGN qmf_t X_left[38][64] = {{0}}; ALIGN qmf_t X_right[38][64] = {{0}}; /* must set this to 0 */ if (sbr == NULL) return 20; /* case can occur due to bit errors */ if (sbr->id_aac != ID_SCE && sbr->id_aac != ID_LFE) return 21; if (sbr->ret || (sbr->header_count == 0)) { /* don't process just upsample */ dont_process = 1; /* Re-activate reset for next frame */ if (sbr->ret && sbr->Reset) sbr->bs_start_freq_prev = -1; } if (just_seeked) { sbr->just_seeked = 1; } else { sbr->just_seeked = 0; } if (sbr->qmfs[1] == NULL) { sbr->qmfs[1] = qmfs_init((downSampledSBR)?32:64); } sbr->ret += sbr_process_channel(sbr, left_channel, X_left, 0, dont_process, downSampledSBR); /* copy some extra data for PS */ for (l = 32; l < 38; l++) { for (k = 0; k < 5; k++) { QMF_RE(X_left[l][k]) = QMF_RE(sbr->Xsbr[0][sbr->tHFAdj+l][k]); QMF_IM(X_left[l][k]) = QMF_IM(sbr->Xsbr[0][sbr->tHFAdj+l][k]); } } /* perform parametric stereo */ #ifdef DRM_PS if (sbr->Is_DRM_SBR) { drm_ps_decode(sbr->drm_ps, (sbr->ret > 0), X_left, X_right); } else { #endif #ifdef PS_DEC ps_decode(sbr->ps, X_left, X_right); #endif #ifdef DRM_PS } #endif /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, sbr->qmfs[0], X_left, left_channel); sbr_qmf_synthesis_32(sbr, sbr->qmfs[1], X_right, right_channel); } else { sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X_left, left_channel); sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X_right, right_channel); } if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0 && sbr->ret == 0) { ret = sbr_save_prev_data(sbr, 0); if (ret) return ret; } sbr_save_matrix(sbr, 0); sbr->frame++; return 0; }
sbr_info *sbrDecodeInit(uint16_t framelength, uint8_t id_aac, uint32_t sample_rate, uint8_t downSampledSBR #ifdef DRM , uint8_t IsDRM #endif ) { sbr_info *sbr = faad_malloc(sizeof(sbr_info)); memset(sbr, 0, sizeof(sbr_info)); /* save id of the parent element */ sbr->id_aac = id_aac; sbr->sample_rate = sample_rate; sbr->bs_freq_scale = 2; sbr->bs_alter_scale = 1; sbr->bs_noise_bands = 2; sbr->bs_limiter_bands = 2; sbr->bs_limiter_gains = 2; sbr->bs_interpol_freq = 1; sbr->bs_smoothing_mode = 1; sbr->bs_start_freq = 5; sbr->bs_amp_res = 1; sbr->bs_samplerate_mode = 1; sbr->prevEnvIsShort[0] = -1; sbr->prevEnvIsShort[1] = -1; sbr->header_count = 0; sbr->Reset = 1; #ifdef DRM sbr->Is_DRM_SBR = IsDRM; #endif sbr->tHFGen = T_HFGEN; sbr->tHFAdj = T_HFADJ; sbr->bsco = 0; sbr->bsco_prev = 0; sbr->M_prev = 0; sbr->frame_len = framelength; /* force sbr reset */ sbr->bs_start_freq_prev = -1; if (framelength == 960) { sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS_960; sbr->numTimeSlots = NO_TIME_SLOTS_960; } else { sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS; sbr->numTimeSlots = NO_TIME_SLOTS; } sbr->GQ_ringbuf_index[0] = 0; sbr->GQ_ringbuf_index[1] = 0; if (id_aac == ID_CPE) { /* stereo */ uint8_t j; sbr->qmfa[0] = qmfa_init(32); sbr->qmfa[1] = qmfa_init(32); sbr->qmfs[0] = qmfs_init((downSampledSBR)?32:64); sbr->qmfs[1] = qmfs_init((downSampledSBR)?32:64); for (j = 0; j < 5; j++) { sbr->G_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->G_temp_prev[1][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[1][j] = faad_malloc(64*sizeof(real_t)); } memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); memset(sbr->Xsbr[1], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); } else { /* mono */ uint8_t j; sbr->qmfa[0] = qmfa_init(32); sbr->qmfs[0] = qmfs_init((downSampledSBR)?32:64); sbr->qmfs[1] = NULL; for (j = 0; j < 5; j++) { sbr->G_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); } memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); } return sbr; }