static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], uint8_t bd, uint8_t len) { real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i; real_t temp4_r, temp4_i, temp5_r, temp5_i; int8_t j; uint8_t offset = sbr->tHFAdj; const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); temp2_r = ACDET_PRE(QMF_RE(buffer[offset-2][bd])); temp2_i = ACDET_PRE(QMF_IM(buffer[offset-2][bd])); temp3_r = ACDET_PRE(QMF_RE(buffer[offset-1][bd])); temp3_i = ACDET_PRE(QMF_IM(buffer[offset-1][bd])); // Save these because they are needed after loop temp4_r = temp2_r; temp4_i = temp2_i; temp5_r = temp3_r; temp5_i = temp3_i; for (j = offset; j < len + offset; j++) { temp1_r = temp2_r; temp1_i = temp2_i; temp2_r = temp3_r; temp2_i = temp3_i; temp3_r = ACDET_PRE(QMF_RE(buffer[j][bd])); temp3_i = ACDET_PRE(QMF_IM(buffer[j][bd])); r01r += MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i); r01i += MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i); r02r += MUL_F(temp3_r, temp1_r) + MUL_F(temp3_i, temp1_i); r02i += MUL_F(temp3_i, temp1_r) - MUL_F(temp3_r, temp1_i); r11r += MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i); } RE(ac->r12) = r01r - (MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i)) + (MUL_F(temp5_r, temp4_r) + MUL_F(temp5_i, temp4_i)); IM(ac->r12) = r01i - (MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i)) + (MUL_F(temp5_i, temp4_r) - MUL_F(temp5_r, temp4_i)); RE(ac->r22) = r11r - (MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i)) + (MUL_F(temp4_r, temp4_r) + MUL_F(temp4_i, temp4_i)); RE(ac->r01) = r01r; IM(ac->r01) = r01i; RE(ac->r02) = r02r; IM(ac->r02) = r02i; RE(ac->r11) = r11r; ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F((MUL_F(RE(ac->r12), RE(ac->r12)) + MUL_F(IM(ac->r12), IM(ac->r12))), rel); ac->det = ACDET_POST(ac->det); }
static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], uint8_t bd, uint8_t len) { real_t r01 = 0, r02 = 0, r11 = 0; real_t tmp1, tmp2; int8_t j; uint8_t offset = sbr->tHFAdj; const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); for (j = offset; j < len + offset; j++) { real_t buf_j = ACDET_PRE(QMF_RE(buffer[j ][bd])); real_t buf_j_1 = ACDET_PRE(QMF_RE(buffer[j-1][bd])); real_t buf_j_2 = ACDET_PRE(QMF_RE(buffer[j-2][bd])); r01 += MUL_F(buf_j , buf_j_1); r02 += MUL_F(buf_j , buf_j_2); r11 += MUL_F(buf_j_1, buf_j_1); } tmp1 = ACDET_PRE(QMF_RE(buffer[len+offset-1][bd])); tmp2 = ACDET_PRE(QMF_RE(buffer[ offset-1][bd])); RE(ac->r12) = r01 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); tmp1 = ACDET_PRE(QMF_RE(buffer[len+offset-2][bd])); tmp2 = ACDET_PRE(QMF_RE(buffer[ offset-2][bd])); RE(ac->r22) = r11 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); RE(ac->r01) = r01; RE(ac->r02) = r02; RE(ac->r11) = r11; ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_F(RE(ac->r12), RE(ac->r12)), rel); ac->det = ACDET_POST(ac->det); }
static void ps_dummy_function(qmf_t X_mono[MAX_NTSR][64], qmf_t X_left[MAX_NTSR][64], qmf_t X_right[MAX_NTSR][64]) { uint8_t i, j; for (i = 0; i < MAX_NTSR; i++) { for (j = 0; j < 64; j++) { QMF_RE(X_left[i][j]) = QMF_RE(X_mono[i][j]); QMF_RE(X_right[i][j]) = QMF_RE(X_mono[i][j]); #ifndef SBR_LOW_POWER QMF_IM(X_left[i][j]) = QMF_IM(X_mono[i][j]); QMF_IM(X_right[i][j]) = QMF_IM(X_mono[i][j]); #endif } } }
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)); } }
void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], qmf_t Xhigh[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg #endif ,uint8_t ch) { uint8_t l, i, x; ALIGN complex_t alpha_0[64], alpha_1[64]; #ifdef SBR_LOW_POWER ALIGN real_t rxx[64]; #endif uint8_t offset = sbr->tHFAdj; uint8_t first = sbr->t_E[ch][0]; uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; calc_chirp_factors(sbr, ch); #ifdef SBR_LOW_POWER memset(deg, 0, 64*sizeof(real_t)); #endif if ((ch == 0) && (sbr->Reset)) patch_construction(sbr); /* calculate the prediction coefficients */ #ifdef SBR_LOW_POWER calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); calc_aliasing_degree(sbr, rxx, deg); #endif /* actual HF generation */ for (i = 0; i < sbr->noPatches; i++) { for (x = 0; x < sbr->patchNoSubbands[i]; x++) { real_t a0_r, a0_i, a1_r, a1_i; real_t bw, bw2; uint8_t q, p, k, g; /* find the low and high band for patching */ k = sbr->kx + x; for (q = 0; q < i; q++) { k += sbr->patchNoSubbands[q]; } p = sbr->patchStartSubband[i] + x; #ifdef SBR_LOW_POWER if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) deg[k] = deg[p]; else deg[k] = 0; #endif g = sbr->table_map_k_to_g[k]; bw = sbr->bwArray[ch][g]; bw2 = MUL_C(bw, bw); /* do the patching */ /* with or without filtering */ if (bw2 > 0) { real_t temp1_r, temp2_r, temp3_r; #ifndef SBR_LOW_POWER real_t temp1_i, temp2_i, temp3_i; calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); #endif a0_r = MUL_C(RE(alpha_0[p]), bw); a1_r = MUL_C(RE(alpha_1[p]), bw2); #ifndef SBR_LOW_POWER a0_i = MUL_C(IM(alpha_0[p]), bw); a1_i = MUL_C(IM(alpha_1[p]), bw2); #endif temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); #ifndef SBR_LOW_POWER temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); #endif for (l = first; l < last; l++) { temp1_r = temp2_r; temp2_r = temp3_r; temp3_r = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER temp1_i = temp2_i; temp2_i = temp3_i; temp3_i = QMF_IM(Xlow[l + offset][p]); #endif #ifdef SBR_LOW_POWER QMF_RE(Xhigh[l + offset][k]) = temp3_r + (MUL_R(a0_r, temp2_r) + MUL_R(a1_r, temp1_r)); #else QMF_RE(Xhigh[l + offset][k]) = temp3_r + (MUL_R(a0_r, temp2_r) - MUL_R(a0_i, temp2_i) + MUL_R(a1_r, temp1_r) - MUL_R(a1_i, temp1_i)); QMF_IM(Xhigh[l + offset][k]) = temp3_i + (MUL_R(a0_i, temp2_r) + MUL_R(a0_r, temp2_i) + MUL_R(a1_i, temp1_r) + MUL_R(a1_r, temp1_i)); #endif } } else { for (l = first; l < last; l++) { QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); #endif } } } } if (sbr->Reset) { limiter_frequency_table(sbr); } }
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, const uint8_t downSampledSBR) { int16_t k, l; (void)downSampledSBR; #ifdef DRM if (sbr->Is_DRM_SBR) { sbr->bsco = max((int32_t)sbr->maxAACLine*32/(int32_t)sbr->frame_len - (int32_t)sbr->kx, 0); } else { #endif sbr->bsco = 0; #ifdef DRM } #endif //#define PRE_QMF_PRINT #ifdef PRE_QMF_PRINT { int i; for (i = 0; i < 1024; i++) { printf("%d\n", channel_buf[i]); } } #endif /* subband analysis */ if (dont_process) sbr_qmf_analysis_32(sbr, &sbr->qmfa[ch], channel_buf, sbr->Xsbr[ch], sbr->tHFGen, 32); else sbr_qmf_analysis_32(sbr, &sbr->qmfa[ch], channel_buf, sbr->Xsbr[ch], sbr->tHFGen, sbr->kx); if (!dont_process) { #if 1 /* insert high frequencies here */ /* hf generation using patching */ hf_generation(sbr, sbr->Xsbr[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->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 } 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 kx_band, M_band, bsco_band; if (l < sbr->t_E[ch][0]) { kx_band = sbr->kx_prev; M_band = sbr->M_prev; bsco_band = sbr->bsco_prev; } else { kx_band = sbr->kx; M_band = sbr->M; bsco_band = sbr->bsco; } #ifndef SBR_LOW_POWER for (k = 0; k < kx_band + bsco_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = kx_band + bsco_band; k < kx_band + M_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = max(kx_band + bsco_band, kx_band + M_band); k < 64; k++) { QMF_RE(X[l][k]) = 0; QMF_IM(X[l][k]) = 0; } #else for (k = 0; k < kx_band + bsco_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = kx_band + bsco_band; k < min(kx_band + M_band, 63); k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = max(kx_band + bsco_band, kx_band + M_band); k < 64; k++) { QMF_RE(X[l][k]) = 0; } QMF_RE(X[l][kx_band - 1 + bsco_band]) += QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][kx_band - 1 + bsco_band]); #endif } } }
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; memset(p_XLR->X_L, 0, sizeof(*p_XLR->X_L)); memset(p_XLR->X_R, 0, sizeof(*p_XLR->X_R)); 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; } sbr_process_channel(sbr, left_channel, p_XLR->X_L, 0, dont_process, downSampledSBR); /* copy some extra data for PS */ for (l = 32; l < 38; l++) { for (k = 0; k < 5; k++) { QMF_RE(p_XLR->X_L[l][k]) = QMF_RE(sbr->Xsbr[0][sbr->tHFAdj+l][k]); QMF_IM(p_XLR->X_L[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), sbr->sample_rate, p_XLR->X_L, p_XLR->X_R); } else { #endif #ifdef PS_DEC ps_decode(&sbr->ps, p_XLR->X_L, p_XLR->X_R); #endif #ifdef DRM_PS } #endif /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, &sbr->qmfs[0], p_XLR->X_L, left_channel); sbr_qmf_synthesis_32(sbr, &sbr->qmfs[1], p_XLR->X_R, right_channel); } else { sbr_qmf_synthesis_64(sbr, &sbr->qmfs[0], p_XLR->X_L, left_channel); sbr_qmf_synthesis_64(sbr, &sbr->qmfs[1], p_XLR->X_R, 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; }
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 = sbr->numTimeSlotsRate; l < sbr->numTimeSlotsRate + 6; 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; }
void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel, real_t *right_channel, uint8_t id_aac, uint8_t just_seeked) { int16_t i, k, l; uint8_t dont_process = 0; uint8_t ch, channels, ret; real_t *ch_buf; sbr->id_aac = id_aac; channels = (id_aac == ID_SCE) ? 1 : 2; ret = sbr_extension_data(&sbr->ld, sbr, id_aac); ret = (sbr->ld.error)? sbr->ld.error : ret; if(ret || (sbr->header_count == 0)) dont_process = 1; if(just_seeked) sbr->just_seeked = 1; else sbr->just_seeked = 0; for (ch = 0; ch < channels; ch++){ if (ch == 0) ch_buf = left_channel; else ch_buf = right_channel; for (i = 0; i < tHFAdj; i++){ int8_t j; for (j = sbr->kx_prev; j < sbr->kx; j++){ QMF_RE(sbr->Xcodec[ch][i*32 + j]) = 0; QMF_IM(sbr->Xcodec[ch][i*32 + j]) = 0; } } sbr_qmf_analysis_32(sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], tHFGen); if(!dont_process){ hf_generation(sbr, sbr->Xcodec[ch], sbr->Xsbr[ch],ch); hf_adjustment(sbr, sbr->Xsbr[ch],ch); } if((sbr->just_seeked != 0) || dont_process){ for (l = 0; l < 32; l++){ for (k = 0; k < 32; k++){ QMF_RE(sbr->temp_X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]); QMF_IM(sbr->temp_X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]); } for (k = 32; k < 64; k++){ QMF_RE(sbr->temp_X[l * 64 + k]) = 0; QMF_IM(sbr->temp_X[l * 64 + k]) = 0; } } }else{ for (l = 0; l < 32; 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(sbr->temp_X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]); QMF_IM(sbr->temp_X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]); } for (k = xover_band; k < 64; k++){ QMF_RE(sbr->temp_X[l * 64 + k]) = QMF_RE(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]); QMF_IM(sbr->temp_X[l * 64 + k]) = QMF_IM(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]); } } } sbr_qmf_synthesis_64(sbr->qmfs[ch], (const complex_t*)sbr->temp_X, ch_buf); for (i = 0; i < 32; i++){ int8_t j; for (j = 0; j < tHFGen; j++){ QMF_RE(sbr->Xcodec[ch][j*32 + i]) = QMF_RE(sbr->Xcodec[ch][(j+32)*32 + i]); QMF_IM(sbr->Xcodec[ch][j*32 + i]) = QMF_IM(sbr->Xcodec[ch][(j+32)*32 + i]); } } for (i = 0; i < 64; i++){ int8_t j; for (j = 0; j < tHFGen; j++){ QMF_RE(sbr->Xsbr[ch][j*64 + i]) = QMF_RE(sbr->Xsbr[ch][(j+32)*64 + i]); QMF_IM(sbr->Xsbr[ch][j*64 + i]) = QMF_IM(sbr->Xsbr[ch][(j+32)*64 + i]); } } } if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0){ for (ch = 0; ch < channels; ch++) sbr_save_prev_data(sbr, ch); } sbr->frame++; }
static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) { static real_t h_smooth[] = { COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084), COEF_CONST(0.21816949906249), COEF_CONST(0.30150283239582), COEF_CONST(0.33333333333333) }; static int8_t phi_re[] = { 1, 0, -1, 0 }; static int8_t phi_im[] = { 0, 1, 0, -1 }; uint8_t m, l, i, n; uint16_t fIndexNoise = 0; uint8_t fIndexSine = 0; uint8_t assembly_reset = 0; real_t *temp; real_t G_filt, Q_filt; uint8_t h_SL; if (sbr->Reset == 1) { assembly_reset = 1; fIndexNoise = 0; } else { fIndexNoise = sbr->index_noise_prev[ch]; } fIndexSine = sbr->psi_is_prev[ch]; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; #ifdef SBR_LOW_POWER h_SL = 0; #else h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; h_SL = (no_noise ? 0 : h_SL); #endif if (assembly_reset) { for (n = 0; n < 4; n++) { memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); } assembly_reset = 0; } for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) { #ifdef SBR_LOW_POWER uint8_t i_min1, i_plus1; uint8_t sinusoids = 0; #endif memcpy(sbr->G_temp_prev[ch][4], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); memcpy(sbr->Q_temp_prev[ch][4], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); for (m = 0; m < sbr->M; m++) { uint8_t j; qmf_t psi; G_filt = 0; Q_filt = 0; j = 0; if (h_SL != 0) { for (n = 0; n <= 4; n++) { G_filt += MUL_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]); Q_filt += MUL_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]); j++; } } else { G_filt = sbr->G_temp_prev[ch][4][m]; Q_filt = sbr->Q_temp_prev[ch][4][m]; } Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt; /* add noise to the output */ fIndexNoise = (fIndexNoise + 1) & 511; /* the smoothed gain values are applied to Xsbr */ /* V is defined, not calculated */ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) + MUL_F(Q_filt, RE(V[fIndexNoise])); if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; #ifndef SBR_LOW_POWER QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) + MUL_F(Q_filt, IM(V[fIndexNoise])); #endif //if (adj->S_index_mapped[m][l]) { int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); QMF_RE(psi) = MUL_R(adj->S_M_boost[l][m], phi_re[fIndexSine]); QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); #ifndef SBR_LOW_POWER QMF_IM(psi) = rev * MUL_R(adj->S_M_boost[l][m], phi_im[fIndexSine]); QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); #else i_min1 = (fIndexSine - 1) & 3; i_plus1 = (fIndexSine + 1) & 3; if (m == 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) -= (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815))); if(m < sbr->M - 1) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev * MUL_C(MUL_R(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815))); } } if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev * MUL_C(MUL_R(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815))); } if ((m == sbr->M - 1) && (sinusoids < 16)) { if (m > 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); } if (m + sbr->kx < 64) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) -= (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][m], phi_re[i_min1]), COEF_CONST(0.00815))); } } if (adj->S_M_boost[l][m] != 0) sinusoids++; #endif } } fIndexSine = (fIndexSine + 1) & 3; temp = sbr->G_temp_prev[ch][0]; for (n = 0; n < 4; n++) sbr->G_temp_prev[ch][n] = sbr->G_temp_prev[ch][n+1]; sbr->G_temp_prev[ch][4] = temp; temp = sbr->Q_temp_prev[ch][0]; for (n = 0; n < 4; n++) sbr->Q_temp_prev[ch][n] = sbr->Q_temp_prev[ch][n+1]; sbr->Q_temp_prev[ch][4] = temp; } } sbr->index_noise_prev[ch] = fIndexNoise; sbr->psi_is_prev[ch] = fIndexSine; }
static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) { uint8_t m, l, j, k, k_l, k_h, p; real_t nrg, div; if (sbr->bs_interpol_freq == 1) { for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t i, l_i, u_i; l_i = sbr->t_E[ch][l]; u_i = sbr->t_E[ch][l+1]; div = (real_t)(u_i - l_i); for (m = 0; m < sbr->M; m++) { nrg = 0; for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) { nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx])) #ifndef SBR_LOW_POWER + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx])) #endif ; } sbr->E_curr[ch][m][l] = nrg / div; #ifdef SBR_LOW_POWER sbr->E_curr[ch][m][l] *= 2; #endif } } } else { for (l = 0; l < sbr->L_E[ch]; l++) { for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) { k_l = sbr->f_table_res[sbr->f[ch][l]][p]; k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; for (k = k_l; k < k_h; k++) { uint8_t i, l_i, u_i; nrg = 0.0; l_i = sbr->t_E[ch][l]; u_i = sbr->t_E[ch][l+1]; div = (real_t)((u_i - l_i)*(k_h - k_l)); for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) { for (j = k_l; j < k_h; j++) { nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j])) #ifndef SBR_LOW_POWER + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j])) #endif ; } } sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; #ifdef SBR_LOW_POWER sbr->E_curr[ch][k - sbr->kx][l] *= 2; #endif } } } } }
void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][32], qmf_t Xhigh[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg #endif ,uint8_t ch) { uint8_t l, i, x; ALIGN complex_t alpha_0[64], alpha_1[64]; #ifdef SBR_LOW_POWER ALIGN real_t rxx[64]; #endif uint8_t offset = sbr->tHFAdj; uint8_t first = sbr->t_E[ch][0]; uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; // printf("%d %d\n", first, last); calc_chirp_factors(sbr, ch); for (i = first; i < last; i++) { memset(Xhigh[i + offset], 0, 64 * sizeof(qmf_t)); } if ((ch == 0) && (sbr->Reset)) patch_construction(sbr); /* calculate the prediction coefficients */ calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1 #ifdef SBR_LOW_POWER , rxx #endif ); #ifdef SBR_LOW_POWER calc_aliasing_degree(sbr, rxx, deg); #endif /* actual HF generation */ for (i = 0; i < sbr->noPatches; i++) { for (x = 0; x < sbr->patchNoSubbands[i]; x++) { complex_t a0, a1; real_t bw, bw2; uint8_t q, p, k, g; /* find the low and high band for patching */ k = sbr->kx + x; for (q = 0; q < i; q++) { k += sbr->patchNoSubbands[q]; } p = sbr->patchStartSubband[i] + x; #ifdef SBR_LOW_POWER if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) deg[k] = deg[p]; else deg[k] = 0; #endif g = sbr->table_map_k_to_g[k]; bw = sbr->bwArray[ch][g]; bw2 = MUL_C(bw, bw); /* do the patching */ /* with or without filtering */ if (bw2 > 0) { RE(a0) = MUL_C(RE(alpha_0[p]), bw); RE(a1) = MUL_C(RE(alpha_1[p]), bw2); #ifndef SBR_LOW_POWER IM(a0) = MUL_C(IM(alpha_0[p]), bw); IM(a1) = MUL_C(IM(alpha_1[p]), bw2); #endif for (l = first; l < last; l++) { QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); #endif #ifdef SBR_LOW_POWER QMF_RE(Xhigh[l + offset][k]) += ( MUL_R(RE(a0), QMF_RE(Xlow[l - 1 + offset][p])) + MUL_R(RE(a1), QMF_RE(Xlow[l - 2 + offset][p]))); #else QMF_RE(Xhigh[l + offset][k]) += ( RE(a0) * QMF_RE(Xlow[l - 1 + offset][p]) - IM(a0) * QMF_IM(Xlow[l - 1 + offset][p]) + RE(a1) * QMF_RE(Xlow[l - 2 + offset][p]) - IM(a1) * QMF_IM(Xlow[l - 2 + offset][p])); QMF_IM(Xhigh[l + offset][k]) += ( IM(a0) * QMF_RE(Xlow[l - 1 + offset][p]) + RE(a0) * QMF_IM(Xlow[l - 1 + offset][p]) + IM(a1) * QMF_RE(Xlow[l - 2 + offset][p]) + RE(a1) * QMF_IM(Xlow[l - 2 + offset][p])); #endif } } else { for (l = first; l < last; l++) { QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); #endif } } } } if (sbr->Reset) { limiter_frequency_table(sbr); } }
static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][32], uint8_t bd, uint8_t len) { real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; const real_t rel = 1 / (1 + 1e-6f); int8_t j; uint8_t offset = sbr->tHFAdj; for (j = offset; j < len + offset; j++) { r01r += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]) + QMF_IM(buffer[j][bd]) * QMF_IM(buffer[j-1][bd]); r01i += QMF_IM(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]) - QMF_RE(buffer[j][bd]) * QMF_IM(buffer[j-1][bd]); r02r += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]) + QMF_IM(buffer[j][bd]) * QMF_IM(buffer[j-2][bd]); r02i += QMF_IM(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]) - QMF_RE(buffer[j][bd]) * QMF_IM(buffer[j-2][bd]); r11r += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]) + QMF_IM(buffer[j-1][bd]) * QMF_IM(buffer[j-1][bd]); } RE(ac->r01) = r01r; IM(ac->r01) = r01i; RE(ac->r02) = r02r; IM(ac->r02) = r02i; RE(ac->r11) = r11r; RE(ac->r12) = r01r - (QMF_RE(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_IM(buffer[len+offset-1][bd]) * QMF_IM(buffer[len+offset-2][bd])) + (QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]) + QMF_IM(buffer[offset-1][bd]) * QMF_IM(buffer[offset-2][bd])); IM(ac->r12) = r01i - (QMF_IM(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) - QMF_RE(buffer[len+offset-1][bd]) * QMF_IM(buffer[len+offset-2][bd])) + (QMF_IM(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]) - QMF_RE(buffer[offset-1][bd]) * QMF_IM(buffer[offset-2][bd])); RE(ac->r22) = r11r - (QMF_RE(buffer[len+offset-2][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_IM(buffer[len+offset-2][bd]) * QMF_IM(buffer[len+offset-2][bd])) + (QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]) + QMF_IM(buffer[offset-2][bd]) * QMF_IM(buffer[offset-2][bd])); ac->det = RE(ac->r11) * RE(ac->r22) - rel * (RE(ac->r12) * RE(ac->r12) + IM(ac->r12) * IM(ac->r12)); }
static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][32], uint8_t bd, uint8_t len) { real_t r01 = 0, r02 = 0, r11 = 0; int8_t j; uint8_t offset = sbr->tHFAdj; const real_t rel = 1 / (1 + 1e-6f); for (j = offset; j < len + offset; j++) { r01 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]); r02 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]); r11 += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]); } RE(ac->r12) = r01 - QMF_RE(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]); RE(ac->r22) = r11 - QMF_RE(buffer[len+offset-2][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]); RE(ac->r01) = r01; RE(ac->r02) = r02; RE(ac->r11) = r11; ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_C(MUL_R(RE(ac->r12), RE(ac->r12)), rel); }