📄 specrec.c
字号:
*/static void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len){ uint8_t g, sfb, win; uint16_t width, bin, k, gindex; ALIGN real_t tmp_spec[1024] = {0}; k = 0; gindex = 0; for (g = 0; g < ics->num_window_groups; g++) { uint16_t j = 0; uint16_t gincrease = 0; uint16_t win_inc = ics->swb_offset[ics->num_swb]; for (sfb = 0; sfb < ics->num_swb; sfb++) { width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb]; for (win = 0; win < ics->window_group_length[g]; win++) { for (bin = 0; bin < width; bin += 4) { tmp_spec[gindex+(win*win_inc)+j+bin+0] = spec_data[k+0]; tmp_spec[gindex+(win*win_inc)+j+bin+1] = spec_data[k+1]; tmp_spec[gindex+(win*win_inc)+j+bin+2] = spec_data[k+2]; tmp_spec[gindex+(win*win_inc)+j+bin+3] = spec_data[k+3]; gincrease += 4; k += 4; } } j += width; } gindex += gincrease; } memcpy(spec_data, tmp_spec, frame_len*sizeof(real_t));}static INLINE real_t iquant(int16_t q, const real_t *tab, uint8_t *error){#ifdef FIXED_POINT static const real_t errcorr[] = { REAL_CONST(0), REAL_CONST(1.0/8.0), REAL_CONST(2.0/8.0), REAL_CONST(3.0/8.0), REAL_CONST(4.0/8.0), REAL_CONST(5.0/8.0), REAL_CONST(6.0/8.0), REAL_CONST(7.0/8.0), REAL_CONST(0) }; real_t x1, x2; int16_t sgn = 1; if (q < 0) { q = -q; sgn = -1; } if (q < IQ_TABLE_SIZE) return sgn * tab[q]; /* linear interpolation */ x1 = tab[q>>3]; x2 = tab[(q>>3) + 1]; return sgn * 16 * (MUL_R(errcorr[q&7],(x2-x1)) + x1);#else if (q < 0) { /* tab contains a value for all possible q [0,8192] */ if (-q < IQ_TABLE_SIZE) return -tab[-q]; *error = 17; return 0; } else { /* tab contains a value for all possible q [0,8192] */ if (q < IQ_TABLE_SIZE) return tab[q]; *error = 17; return 0; }#endif}static uint8_t inverse_quantization(real_t *x_invquant, const int16_t *x_quant, const uint16_t frame_len){ int16_t i; uint8_t error = 0; /* Init error flag */ const real_t *tab = iq_table; for (i = 0; i < frame_len; i+=4) { x_invquant[i] = iquant(x_quant[i], tab, &error); x_invquant[i+1] = iquant(x_quant[i+1], tab, &error); x_invquant[i+2] = iquant(x_quant[i+2], tab, &error); x_invquant[i+3] = iquant(x_quant[i+3], tab, &error); } return error;}#ifndef FIXED_POINTALIGN static const real_t pow2sf_tab[] = { 2.9802322387695313E-008, 5.9604644775390625E-008, 1.1920928955078125E-007, 2.384185791015625E-007, 4.76837158203125E-007, 9.5367431640625E-007, 1.9073486328125E-006, 3.814697265625E-006, 7.62939453125E-006, 1.52587890625E-005, 3.0517578125E-005, 6.103515625E-005, 0.0001220703125, 0.000244140625, 0.00048828125, 0.0009765625, 0.001953125, 0.00390625, 0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 65536.0, 131072.0, 262144.0, 524288.0, 1048576.0, 2097152.0, 4194304.0, 8388608.0, 16777216.0, 33554432.0, 67108864.0, 134217728.0, 268435456.0, 536870912.0, 1073741824.0, 2147483648.0, 4294967296.0, 8589934592.0, 17179869184.0, 34359738368.0, 68719476736.0, 137438953472.0, 274877906944.0};#endifALIGN static real_t pow2_table[] ={#if 0 COEF_CONST(0.59460355750136053335874998528024), /* 2^-0.75 */ COEF_CONST(0.70710678118654752440084436210485), /* 2^-0.5 */ COEF_CONST(0.84089641525371454303112547623321), /* 2^-0.25 */#endif COEF_CONST(1.0), COEF_CONST(1.1892071150027210667174999705605), /* 2^0.25 */ COEF_CONST(1.4142135623730950488016887242097), /* 2^0.5 */ COEF_CONST(1.6817928305074290860622509524664) /* 2^0.75 */};void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant, uint16_t frame_len){ uint8_t g, sfb; uint16_t top; int32_t exp, frac; uint8_t groups = 0; uint16_t nshort = frame_len/8; for (g = 0; g < ics->num_window_groups; g++) { uint16_t k = 0; /* using this nshort*groups doesn't hurt long blocks, because long blocks only have 1 group, so that means 'groups' is always 0 for long blocks */ for (sfb = 0; sfb < ics->max_sfb; sfb++) { top = ics->sect_sfb_offset[g][sfb+1]; /* this could be scalefactor for IS or PNS, those can be negative or bigger then 255 */ /* just ignore them */ if (ics->scale_factors[g][sfb] < 0 || ics->scale_factors[g][sfb] > 255) { exp = 0; frac = 0; } else { /* ics->scale_factors[g][sfb] must be between 0 and 255 */ exp = (ics->scale_factors[g][sfb] /* - 100 */) >> 2; frac = (ics->scale_factors[g][sfb] /* - 100 */) & 3; }#ifdef FIXED_POINT exp -= 25; /* IMDCT pre-scaling */ if (hDecoder->object_type == LD) { exp -= 6 /*9*/; } else { if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) exp -= 4 /*7*/; else exp -= 7 /*10*/; }#endif /* minimum size of a sf band is 4 and always a multiple of 4 */ for ( ; k < top; k += 4) {#ifdef FIXED_POINT if (exp < 0) { x_invquant[k+(groups*nshort)] >>= -exp; x_invquant[k+(groups*nshort)+1] >>= -exp; x_invquant[k+(groups*nshort)+2] >>= -exp; x_invquant[k+(groups*nshort)+3] >>= -exp; } else { x_invquant[k+(groups*nshort)] <<= exp; x_invquant[k+(groups*nshort)+1] <<= exp; x_invquant[k+(groups*nshort)+2] <<= exp; x_invquant[k+(groups*nshort)+3] <<= exp; }#else x_invquant[k+(groups*nshort)] = x_invquant[k+(groups*nshort)] * pow2sf_tab[exp/*+25*/]; x_invquant[k+(groups*nshort)+1] = x_invquant[k+(groups*nshort)+1] * pow2sf_tab[exp/*+25*/]; x_invquant[k+(groups*nshort)+2] = x_invquant[k+(groups*nshort)+2] * pow2sf_tab[exp/*+25*/]; x_invquant[k+(groups*nshort)+3] = x_invquant[k+(groups*nshort)+3] * pow2sf_tab[exp/*+25*/];#endif x_invquant[k+(groups*nshort)] = MUL_C(x_invquant[k+(groups*nshort)],pow2_table[frac /* + 3*/]); x_invquant[k+(groups*nshort)+1] = MUL_C(x_invquant[k+(groups*nshort)+1],pow2_table[frac /* + 3*/]); x_invquant[k+(groups*nshort)+2] = MUL_C(x_invquant[k+(groups*nshort)+2],pow2_table[frac /* + 3*/]); x_invquant[k+(groups*nshort)+3] = MUL_C(x_invquant[k+(groups*nshort)+3],pow2_table[frac /* + 3*/]); } } groups += ics->window_group_length[g]; }}#ifdef USE_SSEvoid apply_scalefactors_sse(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant, uint16_t frame_len){ uint8_t g, sfb; uint16_t top; int32_t exp, frac; uint8_t groups = 0; uint16_t nshort = frame_len/8; for (g = 0; g < ics->num_window_groups; g++) { uint16_t k = 0; /* using this nshort*groups doesn't hurt long blocks, because long blocks only have 1 group, so that means 'groups' is always 0 for long blocks */ for (sfb = 0; sfb < ics->max_sfb; sfb++) { top = ics->sect_sfb_offset[g][sfb+1]; exp = (ics->scale_factors[g][sfb] /* - 100 */) >> 2; frac = (ics->scale_factors[g][sfb] /* - 100 */) & 3; /* minimum size of a sf band is 4 and always a multiple of 4 */ for ( ; k < top; k += 4) { __m128 m1 = _mm_load_ps(&x_invquant[k+(groups*nshort)]); __m128 m2 = _mm_load_ps1(&pow2sf_tab[exp /*+25*/]); __m128 m3 = _mm_load_ps1(&pow2_table[frac /* + 3*/]); __m128 m4 = _mm_mul_ps(m1, m2); __m128 m5 = _mm_mul_ps(m3, m4); _mm_store_ps(&x_invquant[k+(groups*nshort)], m5); } } groups += ics->window_group_length[g]; }}#endifstatic uint8_t allocate_single_channel(faacDecHandle hDecoder, uint8_t channel, uint8_t output_channels){ uint8_t mul = 1;#ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { /* allocate the state only when needed */ if (hDecoder->pred_stat[channel] == NULL) { hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength); } }#endif#ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { /* allocate the state only when needed */ if (hDecoder->lt_pred_stat[channel] == NULL) { hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } }#endif if (hDecoder->time_out[channel] == NULL) { mul = 1;#ifdef SBR_DEC hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0; if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { /* SBR requires 2 times as much output data */ mul = 2; hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1; }#endif hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); }#if (defined(PS_DEC) || defined(DRM_PS)) if (output_channels == 2) { if (hDecoder->time_out[channel+1] == NULL) { hDecoder->time_out[channel+1] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t)); } }#endif if (hDecoder->fb_intermed[channel] == NULL) { hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t)); }#ifdef SSR_DEC if (hDecoder->object_type == SSR) { if (hDecoder->ssr_overlap[channel] == NULL) { hDecoder->ssr_overlap[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->ssr_overlap[channel], 0, 2*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->prev_fmd[channel] == NULL) { uint16_t k; hDecoder->prev_fmd[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); for (k = 0; k < 2*hDecoder->frameLength; k++) hDecoder->prev_fmd[channel][k] = REAL_CONST(-1); } }#endif return 0;}static uint8_t allocate_channel_pair(faacDecHandle hDecoder, uint8_t channel, uint8_t paired_channel){ uint8_t mul = 1;#ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { /* allocate the state only when needed */ if (hDecoder->pred_stat[channel] == NULL) { hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength); } if (hDecoder->pred_stat[paired_channel] == NULL) { hDecoder->pred_stat[paired_channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[paired_channel], hDecoder->frameLength); } }#endif#ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { /* allocate the state only when needed */ if (hDecoder->lt_pred_stat[channel] == NULL) { hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } if (hDecoder->lt_pred_stat[paired_channel] == NULL) { hDecoder->lt_pred_stat[paired_channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[paired_channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } }#endif if (hDecoder->time_out[channel] == NULL) { mul = 1;#ifdef SBR_DEC hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0; if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { /* SBR requires 2 times as much output data */ mul = 2; hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1; }#endif hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->time_out[paired_channel] == NULL) { hDecoder->time_out[paired_channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[paired_channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->fb_intermed[channel] == NULL) { hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->fb_intermed[paired_channel] == NULL) { hDecoder->fb_intermed[paired_channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[paired_channel], 0, hDecoder->frameLength*sizeof(real_t)); }#ifdef SSR_DEC if (hDecoder->object_type == SSR) { if (hDecoder->ssr_overlap[cpe->channel] == NULL) { hDecoder->ssr_overlap[cpe->channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->ssr_overlap[cpe->channel], 0, 2*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->ssr_overlap[cpe->paired_channel] == NULL) { hDecoder->ssr_overlap[cpe->paired_channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -