static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, uint8_t order) { /* - Simple all-zero filter of order "order" defined by y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order) - The state variables of the filter are initialized to zero every time - The output data is written over the input data ("in-place operation") - An input vector of "size" samples is processed and the index increment to the next data sample is given by "inc" */ uint8_t j; uint16_t i; real_t y, state[TNS_MAX_ORDER]; for (i = 0; i < order; i++) state[i] = REAL_CONST(0.0); for (i = 0; i < size; i++) { y = *spectrum; for (j = 0; j < order; j++) y += MUL_C(state[j], lpc[j+1]); for (j = order-1; j > 0; j--) state[j] = state[j-1]; state[0] = *spectrum; *spectrum = y; spectrum += inc; } }
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); }
void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec, uint16_t frame_len) { uint8_t g, sfb, b; uint16_t i; #ifndef FIXED_POINT real_t scale; #else int32_t exp, frac; #endif uint16_t nshort = frame_len/8; uint8_t group = 0; for (g = 0; g < icsr->num_window_groups; g++) { /* Do intensity stereo decoding */ for (b = 0; b < icsr->window_group_length[g]; b++) { for (sfb = 0; sfb < icsr->max_sfb; sfb++) { if (is_intensity(icsr, g, sfb)) { /* For scalefactor bands coded in intensity stereo the corresponding predictors in the right channel are switched to "off". */ ics->pred.prediction_used[sfb] = 0; icsr->pred.prediction_used[sfb] = 0; #ifndef FIXED_POINT scale = (real_t)pow(0.5, (0.25*icsr->scale_factors[g][sfb])); #else exp = icsr->scale_factors[g][sfb] >> 2; frac = icsr->scale_factors[g][sfb] & 3; #endif /* Scale from left to right channel, do not touch left channel */ for (i = icsr->swb_offset[sfb]; i < icsr->swb_offset[sfb+1]; i++) { #ifndef FIXED_POINT r_spec[(group*nshort)+i] = MUL_R(l_spec[(group*nshort)+i], scale); #else if (exp < 0) r_spec[(group*nshort)+i] = l_spec[(group*nshort)+i] << -exp; else r_spec[(group*nshort)+i] = l_spec[(group*nshort)+i] >> exp; r_spec[(group*nshort)+i] = MUL_C(r_spec[(group*nshort)+i], pow05_table[frac + 3]); #endif if (is_intensity(icsr, g, sfb) != invert_intensity(ics, g, sfb)) r_spec[(group*nshort)+i] = -r_spec[(group*nshort)+i]; } } } group++; } } }
static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg) { uint8_t k; rxx[0] = COEF_CONST(0.0); deg[1] = COEF_CONST(0.0); for (k = 2; k < sbr->k0; k++) { deg[k] = COEF_CONST(0.0); if ((k % 2 == 0) && (rxx[k] < COEF_CONST(0.0))) { if (rxx[k-1] < COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0); if (rxx[k-2] > COEF_CONST(0.0)) { deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } else if (rxx[k-2] > COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } if ((k % 2 == 1) && (rxx[k] > COEF_CONST(0.0))) { if (rxx[k-1] > COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0); if (rxx[k-2] < COEF_CONST(0.0)) { deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } else if (rxx[k-2] < COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } } }
/*{{{*/ static void tns_ar_filter (real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, uint8_t order) { /* - Simple all-pole filter of order "order" defined by y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) - The state variables of the filter are initialized to zero every time - The output data is written over the input data ("in-place operation") - An input vector of "size" samples is processed and the index increment to the next data sample is given by "inc" */ uint8_t j; uint16_t i; real_t y; /* state is stored as a double ringbuffer */ real_t state[2*TNS_MAX_ORDER] = {0}; int8_t state_index = 0; for (i = 0; i < size; i++) { y = *spectrum; for (j = 0; j < order; j++) y -= MUL_C(state[state_index+j], lpc[j+1]); /* double ringbuffer state */ state_index--; if (state_index < 0) state_index = order-1; state[state_index] = state[state_index + order] = y; *spectrum = y; spectrum += inc; //#define TNS_PRINT #ifdef TNS_PRINT //printf("%d\n", y); printf("0x%.8X\n", y); #endif } }
/* Decoder transmitted coefficients for one TNS filter */ static void tns_decode_coef (uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, uint8_t *coef, real_t *a) { uint8_t i, m; real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1]; /* Conversion to signed integer */ for (i = 0; i < order; i++) { if (coef_compress == 0) { if (coef_res_bits == 3) { tmp2[i] = tns_coef_0_3[coef[i]]; } else { tmp2[i] = tns_coef_0_4[coef[i]]; } } else { if (coef_res_bits == 3) { tmp2[i] = tns_coef_1_3[coef[i]]; } else { tmp2[i] = tns_coef_1_4[coef[i]]; } } } /* Conversion to LPC coefficients */ a[0] = COEF_CONST(1.0); for (m = 1; m <= order; m++) { for (i = 1; i < m; i++) /* loop only while i<m */ b[i] = a[i] + MUL_C(tmp2[m-1], a[m-i]); for (i = 1; i < m; i++) /* loop only while i<m */ a[i] = b[i]; a[m] = tmp2[m-1]; /* changed */ } }
/*{{{*/ static void tns_ma_filter (real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, uint8_t order) { /* - Simple all-zero filter of order "order" defined by y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order) - The state variables of the filter are initialized to zero every time - The output data is written over the input data ("in-place operation") - An input vector of "size" samples is processed and the index increment to the next data sample is given by "inc" */ uint8_t j; uint16_t i; real_t y; /* state is stored as a double ringbuffer */ real_t state[2*TNS_MAX_ORDER] = {0}; int8_t state_index = 0; for (i = 0; i < size; i++) { y = *spectrum; for (j = 0; j < order; j++) y += MUL_C(state[state_index+j], lpc[j+1]); /* double ringbuffer state */ state_index--; if (state_index < 0) state_index = order-1; state[state_index] = state[state_index + order] = *spectrum; *spectrum = y; spectrum += inc; } }
int dca_frame (dca_state_t * state, uint8_t * buf, int * flags, level_t * level, sample_t bias) { int i, j; static float adj_table[] = { 1.0, 1.1250, 1.2500, 1.4375 }; dca_bitstream_init (state, buf, state->word_mode, state->bigendian_mode); /* Sync code */ bitstream_get (state, 32); /* Frame header */ state->frame_type = bitstream_get (state, 1); state->samples_deficit = bitstream_get (state, 5) + 1; state->crc_present = bitstream_get (state, 1); state->sample_blocks = bitstream_get (state, 7) + 1; state->frame_size = bitstream_get (state, 14) + 1; state->amode = bitstream_get (state, 6); state->sample_rate = bitstream_get (state, 4); state->bit_rate = bitstream_get (state, 5); state->downmix = bitstream_get (state, 1); state->dynrange = bitstream_get (state, 1); state->timestamp = bitstream_get (state, 1); state->aux_data = bitstream_get (state, 1); state->hdcd = bitstream_get (state, 1); state->ext_descr = bitstream_get (state, 3); state->ext_coding = bitstream_get (state, 1); state->aspf = bitstream_get (state, 1); state->lfe = bitstream_get (state, 2); state->predictor_history = bitstream_get (state, 1); /* TODO: check CRC */ if (state->crc_present) state->header_crc = bitstream_get (state, 16); state->multirate_inter = bitstream_get (state, 1); state->version = bitstream_get (state, 4); state->copy_history = bitstream_get (state, 2); state->source_pcm_res = bitstream_get (state, 3); state->front_sum = bitstream_get (state, 1); state->surround_sum = bitstream_get (state, 1); state->dialog_norm = bitstream_get (state, 4); /* FIME: channels mixing levels */ state->clev = state->slev = 1; state->output = dca_downmix_init (state->amode, *flags, level, state->clev, state->slev); if (state->output < 0) return 1; if (state->lfe && (*flags & DCA_LFE)) state->output |= DCA_LFE; *flags = state->output; state->dynrng = state->level = MUL_C (*level, 2); state->bias = bias; state->dynrnge = 1; state->dynrngcall = NULL; #ifdef DEBUG fprintf (stderr, "frame type: %i\n", state->frame_type); fprintf (stderr, "samples deficit: %i\n", state->samples_deficit); fprintf (stderr, "crc present: %i\n", state->crc_present); fprintf (stderr, "sample blocks: %i (%i samples)\n", state->sample_blocks, state->sample_blocks * 32); fprintf (stderr, "frame size: %i bytes\n", state->frame_size); fprintf (stderr, "amode: %i (%i channels)\n", state->amode, dca_channels[state->amode]); fprintf (stderr, "sample rate: %i (%i Hz)\n", state->sample_rate, dca_sample_rates[state->sample_rate]); fprintf (stderr, "bit rate: %i (%i bits/s)\n", state->bit_rate, dca_bit_rates[state->bit_rate]); fprintf (stderr, "downmix: %i\n", state->downmix); fprintf (stderr, "dynrange: %i\n", state->dynrange); fprintf (stderr, "timestamp: %i\n", state->timestamp); fprintf (stderr, "aux_data: %i\n", state->aux_data); fprintf (stderr, "hdcd: %i\n", state->hdcd); fprintf (stderr, "ext descr: %i\n", state->ext_descr); fprintf (stderr, "ext coding: %i\n", state->ext_coding); fprintf (stderr, "aspf: %i\n", state->aspf); fprintf (stderr, "lfe: %i\n", state->lfe); fprintf (stderr, "predictor history: %i\n", state->predictor_history); fprintf (stderr, "header crc: %i\n", state->header_crc); fprintf (stderr, "multirate inter: %i\n", state->multirate_inter); fprintf (stderr, "version number: %i\n", state->version); fprintf (stderr, "copy history: %i\n", state->copy_history); fprintf (stderr, "source pcm resolution: %i (%i bits/sample)\n", state->source_pcm_res, dca_bits_per_sample[state->source_pcm_res]); fprintf (stderr, "front sum: %i\n", state->front_sum); fprintf (stderr, "surround sum: %i\n", state->surround_sum); fprintf (stderr, "dialog norm: %i\n", state->dialog_norm); fprintf (stderr, "\n"); #endif /* Primary audio coding header */ state->subframes = bitstream_get (state, 4) + 1; if (state->subframes > DCA_SUBFRAMES_MAX) state->subframes = DCA_SUBFRAMES_MAX; state->prim_channels = bitstream_get (state, 3) + 1; if (state->prim_channels > DCA_PRIM_CHANNELS_MAX) state->prim_channels = DCA_PRIM_CHANNELS_MAX; #ifdef DEBUG fprintf (stderr, "subframes: %i\n", state->subframes); fprintf (stderr, "prim channels: %i\n", state->prim_channels); #endif for (i = 0; i < state->prim_channels; i++) { state->subband_activity[i] = bitstream_get (state, 5) + 2; #ifdef DEBUG fprintf (stderr, "subband activity: %i\n", state->subband_activity[i]); #endif if (state->subband_activity[i] > DCA_SUBBANDS) state->subband_activity[i] = DCA_SUBBANDS; } for (i = 0; i < state->prim_channels; i++) { state->vq_start_subband[i] = bitstream_get (state, 5) + 1; #ifdef DEBUG fprintf (stderr, "vq start subband: %i\n", state->vq_start_subband[i]); #endif if (state->vq_start_subband[i] > DCA_SUBBANDS) state->vq_start_subband[i] = DCA_SUBBANDS; } for (i = 0; i < state->prim_channels; i++) { state->joint_intensity[i] = bitstream_get (state, 3); #ifdef DEBUG fprintf (stderr, "joint intensity: %i\n", state->joint_intensity[i]); if (state->joint_intensity[i]) {fprintf (stderr, "JOINTINTENSITY\n");} #endif } for (i = 0; i < state->prim_channels; i++) { state->transient_huffman[i] = bitstream_get (state, 2); #ifdef DEBUG fprintf (stderr, "transient mode codebook: %i\n", state->transient_huffman[i]); #endif } for (i = 0; i < state->prim_channels; i++) { state->scalefactor_huffman[i] = bitstream_get (state, 3); #ifdef DEBUG fprintf (stderr, "scale factor codebook: %i\n", state->scalefactor_huffman[i]); #endif } for (i = 0; i < state->prim_channels; i++) { state->bitalloc_huffman[i] = bitstream_get (state, 3); /* There might be a way not to trash the whole frame, but for * now we must bail out or we will buffer overflow later. */ if (state->bitalloc_huffman[i] == 7) return 1; #ifdef DEBUG fprintf (stderr, "bit allocation quantizer: %i\n", state->bitalloc_huffman[i]); #endif } /* Get codebooks quantization indexes */ for (i = 0; i < state->prim_channels; i++) { state->quant_index_huffman[i][0] = 0; /* Not transmitted */ state->quant_index_huffman[i][1] = bitstream_get (state, 1); } for (j = 2; j < 6; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = bitstream_get (state, 2); for (j = 6; j < 11; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = bitstream_get (state, 3); for (j = 11; j < 27; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = 0; /* Not transmitted */ #ifdef DEBUG for (i = 0; i < state->prim_channels; i++) { fprintf( stderr, "quant index huff:" ); for (j = 0; j < 11; j++) fprintf (stderr, " %i", state->quant_index_huffman[i][j]); fprintf (stderr, "\n"); } #endif /* Get scale factor adjustment */ for (j = 0; j < 11; j++) { for (i = 0; i < state->prim_channels; i++) state->scalefactor_adj[i][j] = 1; } for (i = 0; i < state->prim_channels; i++) { if (state->quant_index_huffman[i][1] == 0) { /* Transmitted only if quant_index_huffman=0 (Huffman code used) */ state->scalefactor_adj[i][1] = adj_table[bitstream_get (state, 2)]; } } for (j = 2; j < 6; j++) for (i = 0; i < state->prim_channels; i++) if (state->quant_index_huffman[i][j] < 3) { /* Transmitted only if quant_index_huffman < 3 */ state->scalefactor_adj[i][j] = adj_table[bitstream_get (state, 2)]; } for (j = 6; j < 11; j++) for (i = 0; i < state->prim_channels; i++) if (state->quant_index_huffman[i][j] < 7) { /* Transmitted only if quant_index_huffman < 7 */ state->scalefactor_adj[i][j] = adj_table[bitstream_get (state, 2)]; } #ifdef DEBUG for (i = 0; i < state->prim_channels; i++) { fprintf (stderr, "scalefac adj:"); for (j = 0; j < 11; j++) fprintf (stderr, " %1.3f", state->scalefactor_adj[i][j]); fprintf (stderr, "\n"); } #endif if (state->crc_present) { /* Audio header CRC check */ bitstream_get (state, 16); } state->current_subframe = 0; state->current_subsubframe = 0; return 0; }
static uint8_t quant_to_spec(NeAACDecHandle hDecoder, ic_stream *ics, int16_t *quant_data, real_t *spec_data, uint16_t frame_len) { const real_t *tab = iq_table; (void)frame_len; uint8_t g, sfb, win; uint16_t width, bin, k, gindex, wa, wb; uint8_t error = 0; /* Init error flag */ real_t scf; 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++) { int32_t exp, frac; width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb]; /* 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 must always be > 0 */ 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 wa = gindex + j; #ifndef FIXED_POINT scf = pow2sf_tab[exp/*+25*/] * pow2_table[frac]; #else scf = pow2_table[frac]; #endif for (win = 0; win < ics->window_group_length[g]; win++) { for (bin = 0; bin < width; bin += 4) { #ifndef FIXED_POINT wb = wa + bin; spec_data[wb+0] = iquant(quant_data[k+0], tab, &error) * scf; spec_data[wb+1] = iquant(quant_data[k+1], tab, &error) * scf; spec_data[wb+2] = iquant(quant_data[k+2], tab, &error) * scf; spec_data[wb+3] = iquant(quant_data[k+3], tab, &error) * scf; #else wb = wa + bin; if (exp>=0) { spec_data[wb+0] = MUL_C((iquant(quant_data[k+0], tab, &error)<< exp), scf); spec_data[wb+1] = MUL_C((iquant(quant_data[k+1], tab, &error)<< exp), scf); spec_data[wb+2] = MUL_C((iquant(quant_data[k+2], tab, &error)<< exp), scf); spec_data[wb+3] = MUL_C((iquant(quant_data[k+3], tab, &error)<< exp), scf); } else { spec_data[wb+0] = MUL_C((iquant(quant_data[k+0], tab, &error)>>-exp), scf); spec_data[wb+1] = MUL_C((iquant(quant_data[k+1], tab, &error)>>-exp), scf); spec_data[wb+2] = MUL_C((iquant(quant_data[k+2], tab, &error)>>-exp), scf); spec_data[wb+3] = MUL_C((iquant(quant_data[k+3], tab, &error)>>-exp), scf); } //#define SCFS_PRINT #ifdef SCFS_PRINT printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+0]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+1]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+2]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+3]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+0]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+1]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+2]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+3]); #endif #endif gincrease += 4; k += 4; } wa += win_inc; } j += width; } gindex += gincrease; } return error; }
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); } }
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 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; }
void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; complex_t x; #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT real_t scale, b_scale = 0; #endif #endif ALIGN complex_t Z1[512]; complex_t *sincos = mdct->sincos; uint16_t N = mdct->N; uint16_t N2 = N >> 1; uint16_t N4 = N >> 2; uint16_t N8 = N >> 3; #ifdef PROFILE int64_t count1, count2 = faad_get_ts(); #endif #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* detect non-power of 2 */ if (N & (N-1)) { /* adjust scale for non-power of 2 MDCT */ /* 2048/1920 */ b_scale = 1; scale = COEF_CONST(1.0666666666666667); } #endif #endif /* pre-IFFT complex multiplication */ for (k = 0; k < N4; k++) { ComplexMult(&IM(Z1[k]), &RE(Z1[k]), X_in[2*k], X_in[N2 - 1 - 2*k], RE(sincos[k]), IM(sincos[k])); } #ifdef PROFILE count1 = faad_get_ts(); #endif /* complex IFFT, any non-scaling FFT can be used here */ cfftb(mdct->cfft, Z1); #ifdef PROFILE count1 = faad_get_ts() - count1; #endif /* post-IFFT complex multiplication */ for (k = 0; k < N4; k++) { RE(x) = RE(Z1[k]); IM(x) = IM(Z1[k]); ComplexMult(&IM(Z1[k]), &RE(Z1[k]), IM(x), RE(x), RE(sincos[k]), IM(sincos[k])); #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* non-power of 2 MDCT scaling */ if (b_scale) { RE(Z1[k]) = MUL_C(RE(Z1[k]), scale); IM(Z1[k]) = MUL_C(IM(Z1[k]), scale); } #endif #endif } /* reordering */ for (k = 0; k < N8; k+=2) { X_out[ 2*k] = IM(Z1[N8 + k]); X_out[ 2 + 2*k] = IM(Z1[N8 + 1 + k]); X_out[ 1 + 2*k] = -RE(Z1[N8 - 1 - k]); X_out[ 3 + 2*k] = -RE(Z1[N8 - 2 - k]); X_out[N4 + 2*k] = RE(Z1[ k]); X_out[N4 + + 2 + 2*k] = RE(Z1[ 1 + k]); X_out[N4 + 1 + 2*k] = -IM(Z1[N4 - 1 - k]); X_out[N4 + 3 + 2*k] = -IM(Z1[N4 - 2 - k]); X_out[N2 + 2*k] = RE(Z1[N8 + k]); X_out[N2 + + 2 + 2*k] = RE(Z1[N8 + 1 + k]); X_out[N2 + 1 + 2*k] = -IM(Z1[N8 - 1 - k]); X_out[N2 + 3 + 2*k] = -IM(Z1[N8 - 2 - k]); X_out[N2 + N4 + 2*k] = -IM(Z1[ k]); X_out[N2 + N4 + 2 + 2*k] = -IM(Z1[ 1 + k]); X_out[N2 + N4 + 1 + 2*k] = RE(Z1[N4 - 1 - k]); X_out[N2 + N4 + 3 + 2*k] = RE(Z1[N4 - 2 - k]); } #ifdef PROFILE count2 = faad_get_ts() - count2; mdct->fft_cycles += count1; mdct->cycles += (count2 - count1); #endif }
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*/]); } }
int a52_downmix_init (int input, int flags, level_t * level, level_t clev, level_t slev) { static uint8_t table[11][8] = { {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, {A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_STEREO, A52_3F, A52_STEREO, A52_3F}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R}, {A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY} }; int output; output = flags & A52_CHANNEL_MASK; if (output > A52_DOLBY) return -1; output = table[output][input & 7]; if (output == A52_STEREO && (input == A52_DOLBY || (input == A52_3F && clev == LEVEL (LEVEL_3DB)))) output = A52_DOLBY; if (flags & A52_ADJUST_LEVEL) { level_t adjust; switch (CONVERT (input & 7, output)) { case CONVERT (A52_3F, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev); break; case CONVERT (A52_STEREO, A52_MONO): case CONVERT (A52_2F2R, A52_2F1R): case CONVERT (A52_3F2R, A52_3F1R): level_3db: adjust = LEVEL (LEVEL_3DB); break; case CONVERT (A52_3F2R, A52_2F1R): if (clev < LEVEL (LEVEL_PLUS3DB - 1)) goto level_3db; /* break thru */ case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F1R, A52_2F1R): case CONVERT (A52_3F1R, A52_2F2R): case CONVERT (A52_3F2R, A52_2F2R): adjust = DIV (1, LEVEL (1) + clev); break; case CONVERT (A52_2F1R, A52_MONO): adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev); break; case CONVERT (A52_2F1R, A52_STEREO): case CONVERT (A52_3F1R, A52_3F): adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (A52_3F1R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5)); break; case CONVERT (A52_3F1R, A52_STEREO): adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (A52_2F2R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + slev); break; case CONVERT (A52_2F2R, A52_STEREO): case CONVERT (A52_3F2R, A52_3F): adjust = DIV (1, LEVEL (1) + slev); break; case CONVERT (A52_3F2R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev); break; case CONVERT (A52_3F2R, A52_STEREO): adjust = DIV (1, LEVEL (1) + clev + slev); break; case CONVERT (A52_MONO, A52_DOLBY): adjust = LEVEL (LEVEL_PLUS3DB); break; case CONVERT (A52_3F, A52_DOLBY): case CONVERT (A52_2F1R, A52_DOLBY): adjust = LEVEL (1 / (1 + LEVEL_3DB)); break; case CONVERT (A52_3F1R, A52_DOLBY): case CONVERT (A52_2F2R, A52_DOLBY): adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB)); break; case CONVERT (A52_3F2R, A52_DOLBY): adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB)); break; default: return output; } *level = MUL_L (*level, adjust); } return output; }
int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, level_t clev, level_t slev) { level_t level_3db; level_3db = MUL_C (level, LEVEL_3DB); switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { case CONVERT (A52_CHANNEL, A52_CHANNEL): case CONVERT (A52_MONO, A52_MONO): case CONVERT (A52_STEREO, A52_STEREO): case CONVERT (A52_3F, A52_3F): case CONVERT (A52_2F1R, A52_2F1R): case CONVERT (A52_3F1R, A52_3F1R): case CONVERT (A52_2F2R, A52_2F2R): case CONVERT (A52_3F2R, A52_3F2R): case CONVERT (A52_STEREO, A52_DOLBY): coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level; return 0; case CONVERT (A52_CHANNEL, A52_MONO): coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB); return 3; case CONVERT (A52_STEREO, A52_MONO): coeff[0] = coeff[1] = level_3db; return 3; case CONVERT (A52_3F, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); return 7; case CONVERT (A52_2F1R, A52_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (A52_2F2R, A52_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_3F1R, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_3F2R, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); coeff[3] = coeff[4] = MUL_L (level_3db, slev); return 31; case CONVERT (A52_MONO, A52_DOLBY): coeff[0] = level_3db; return 0; case CONVERT (A52_3F, A52_DOLBY): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = level_3db; return 7; case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F1R, A52_2F1R): case CONVERT (A52_3F2R, A52_2F2R): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = MUL_L (level, clev); return 7; case CONVERT (A52_2F1R, A52_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 7; case CONVERT (A52_2F1R, A52_STEREO): coeff[0] = coeff[1] = level; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (A52_3F1R, A52_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = level_3db; return 15; case CONVERT (A52_3F1R, A52_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_2F2R, A52_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 15; case CONVERT (A52_2F2R, A52_STEREO): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = MUL_L (level, slev); return 15; case CONVERT (A52_3F2R, A52_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (A52_3F2R, A52_2F1R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (A52_3F2R, A52_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = MUL_L (level, slev); return 31; case CONVERT (A52_3F1R, A52_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = MUL_L (level_3db, slev); return 13; case CONVERT (A52_3F2R, A52_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = MUL_L (level, slev); return 29; case CONVERT (A52_2F2R, A52_2F1R): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 12; case CONVERT (A52_3F2R, A52_3F1R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = level_3db; return 24; case CONVERT (A52_2F1R, A52_2F2R): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 0; case CONVERT (A52_3F1R, A52_2F2R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = level_3db; return 7; case CONVERT (A52_3F1R, A52_3F2R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = level_3db; return 0; case CONVERT (A52_CHANNEL, A52_CHANNEL1): coeff[0] = level; coeff[1] = 0; return 0; case CONVERT (A52_CHANNEL, A52_CHANNEL2): coeff[0] = 0; coeff[1] = level; return 0; } return -1; /* NOTREACHED */ }
int dts_downmix_init (int input, int flags, level_t * level, level_t clev, level_t slev) { static uint8_t table[11][10] = { /* DTS_MONO */ {DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO, DTS_MONO}, /* DTS_CHANNEL */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO}, /* DTS_STEREO */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO}, /* DTS_STEREO_SUMDIFF */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO}, /* DTS_STEREO_TOTAL */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO}, /* DTS_3F */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_3F, DTS_3F, DTS_3F, DTS_3F, DTS_3F}, /* DTS_2F1R */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_2F1R, DTS_2F1R, DTS_2F1R, DTS_2F1R, DTS_2F1R}, /* DTS_3F1R */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_3F, DTS_3F1R, DTS_3F1R, DTS_3F1R, DTS_3F1R}, /* DTS_2F2R */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_2F2R, DTS_2F2R, DTS_2F2R, DTS_2F2R}, /* DTS_3F2R */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_3F, DTS_3F2R, DTS_3F2R, DTS_3F2R, DTS_3F2R}, /* DTS_4F2R */ {DTS_MONO, DTS_CHANNEL, DTS_STEREO, DTS_STEREO, DTS_STEREO, DTS_4F2R, DTS_4F2R, DTS_4F2R, DTS_4F2R, DTS_4F2R}, }; int output; output = flags & DTS_CHANNEL_MASK; if (output > DTS_CHANNEL_MAX) return -1; output = table[output][input]; if (output == DTS_STEREO && (input == DTS_DOLBY || (input == DTS_3F && clev == LEVEL (LEVEL_3DB)))) output = DTS_DOLBY; if (flags & DTS_ADJUST_LEVEL) { level_t adjust; switch (CONVERT (input & 7, output)) { case CONVERT (DTS_3F, DTS_MONO): adjust = (sample_t)(DIV (LEVEL_3DB, LEVEL (1) + clev)); break; case CONVERT (DTS_STEREO, DTS_MONO): case CONVERT (DTS_2F2R, DTS_2F1R): case CONVERT (DTS_3F2R, DTS_3F1R): level_3db: adjust = (sample_t)(LEVEL (LEVEL_3DB)); break; case CONVERT (DTS_3F2R, DTS_2F1R): if (clev < LEVEL (LEVEL_PLUS3DB - 1)) goto level_3db; /* break thru */ case CONVERT (DTS_3F, DTS_STEREO): case CONVERT (DTS_3F1R, DTS_2F1R): case CONVERT (DTS_3F1R, DTS_2F2R): case CONVERT (DTS_3F2R, DTS_2F2R): adjust = DIV (1, LEVEL (1) + clev); break; case CONVERT (DTS_2F1R, DTS_MONO): adjust = (sample_t)(DIV (LEVEL_PLUS3DB, LEVEL (2) + slev)); break; case CONVERT (DTS_2F1R, DTS_STEREO): case CONVERT (DTS_3F1R, DTS_3F): adjust = (sample_t)(DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB))); break; case CONVERT (DTS_3F1R, DTS_MONO): adjust = (sample_t)(DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5))); break; case CONVERT (DTS_3F1R, DTS_STEREO): adjust = (sample_t)(DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB))); break; case CONVERT (DTS_2F2R, DTS_MONO): adjust = (sample_t)(DIV (LEVEL_3DB, LEVEL (1) + slev)); break; case CONVERT (DTS_2F2R, DTS_STEREO): case CONVERT (DTS_3F2R, DTS_3F): adjust = DIV (1, LEVEL (1) + slev); break; case CONVERT (DTS_3F2R, DTS_MONO): adjust = (sample_t)(DIV (LEVEL_3DB, LEVEL (1) + clev + slev)); break; case CONVERT (DTS_3F2R, DTS_STEREO): adjust = DIV (1, LEVEL (1) + clev + slev); break; case CONVERT (DTS_MONO, DTS_DOLBY): adjust = (sample_t)(LEVEL (LEVEL_PLUS3DB)); break; case CONVERT (DTS_3F, DTS_DOLBY): case CONVERT (DTS_2F1R, DTS_DOLBY): adjust = (sample_t)(LEVEL (1 / (1 + LEVEL_3DB))); break; case CONVERT (DTS_3F1R, DTS_DOLBY): case CONVERT (DTS_2F2R, DTS_DOLBY): adjust = (sample_t)(LEVEL (1 / (1 + 2 * LEVEL_3DB))); break; case CONVERT (DTS_3F2R, DTS_DOLBY): adjust = (sample_t)(LEVEL (1 / (1 + 3 * LEVEL_3DB))); break; default: return output; } *level = MUL_L (*level, adjust); } return output; }
int dts_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, level_t clev, level_t slev) { level_t level_3db; level_3db = (sample_t)(MUL_C (level, LEVEL_3DB)); switch (CONVERT (acmod, output & DTS_CHANNEL_MASK)) { case CONVERT (DTS_CHANNEL, DTS_CHANNEL): case CONVERT (DTS_MONO, DTS_MONO): case CONVERT (DTS_STEREO, DTS_STEREO): case CONVERT (DTS_3F, DTS_3F): case CONVERT (DTS_2F1R, DTS_2F1R): case CONVERT (DTS_3F1R, DTS_3F1R): case CONVERT (DTS_2F2R, DTS_2F2R): case CONVERT (DTS_3F2R, DTS_3F2R): case CONVERT (DTS_STEREO, DTS_DOLBY): coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level; return 0; case CONVERT (DTS_CHANNEL, DTS_MONO): coeff[0] = coeff[1] = (sample_t)(MUL_C (level, LEVEL_6DB)); return 3; case CONVERT (DTS_STEREO, DTS_MONO): coeff[0] = coeff[1] = level_3db; return 3; case CONVERT (DTS_3F, DTS_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = (sample_t)(MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB)); return 7; case CONVERT (DTS_2F1R, DTS_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (DTS_2F2R, DTS_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DTS_3F1R, DTS_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = (sample_t)(MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB)); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DTS_3F2R, DTS_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = (sample_t)(MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB)); coeff[3] = coeff[4] = MUL_L (level_3db, slev); return 31; case CONVERT (DTS_MONO, DTS_DOLBY): coeff[0] = level_3db; return 0; case CONVERT (DTS_3F, DTS_DOLBY): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = level_3db; return 7; case CONVERT (DTS_3F, DTS_STEREO): case CONVERT (DTS_3F1R, DTS_2F1R): case CONVERT (DTS_3F2R, DTS_2F2R): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = MUL_L (level, clev); return 7; case CONVERT (DTS_2F1R, DTS_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 7; case CONVERT (DTS_2F1R, DTS_STEREO): coeff[0] = coeff[1] = level; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (DTS_3F1R, DTS_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = level_3db; return 15; case CONVERT (DTS_3F1R, DTS_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DTS_2F2R, DTS_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 15; case CONVERT (DTS_2F2R, DTS_STEREO): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = MUL_L (level, slev); return 15; case CONVERT (DTS_3F2R, DTS_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (DTS_3F2R, DTS_2F1R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (DTS_3F2R, DTS_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = MUL_L (level, slev); return 31; case CONVERT (DTS_3F1R, DTS_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = MUL_L (level_3db, slev); return 13; case CONVERT (DTS_3F2R, DTS_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = MUL_L (level, slev); return 29; case CONVERT (DTS_2F2R, DTS_2F1R): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 12; case CONVERT (DTS_3F2R, DTS_3F1R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = level_3db; return 24; case CONVERT (DTS_2F1R, DTS_2F2R): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 0; case CONVERT (DTS_3F1R, DTS_2F2R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = level_3db; return 7; case CONVERT (DTS_3F1R, DTS_3F2R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = level_3db; return 0; } return -1; /* NOTREACHED */ }
void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; complex_t x; ALIGN complex_t Z1[512]; complex_t *sincos = mdct->sincos; uint16_t N = mdct->N; uint16_t N2 = N >> 1; uint16_t N4 = N >> 2; uint16_t N8 = N >> 3; #ifndef FIXED_POINT real_t scale = REAL_CONST(N); #else real_t scale = REAL_CONST(4.0/N); #endif #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* detect non-power of 2 */ if (N & (N-1)) { /* adjust scale for non-power of 2 MDCT */ /* *= sqrt(2048/1920) */ scale = MUL_C(scale, COEF_CONST(1.0327955589886444)); } #endif #endif /* pre-FFT complex multiplication */ for (k = 0; k < N8; k++) { uint16_t n = k << 1; RE(x) = X_in[N - N4 - 1 - n] + X_in[N - N4 + n]; IM(x) = X_in[ N4 + n] - X_in[ N4 - 1 - n]; ComplexMult(&RE(Z1[k]), &IM(Z1[k]), RE(x), IM(x), RE(sincos[k]), IM(sincos[k])); RE(Z1[k]) = MUL_R(RE(Z1[k]), scale); IM(Z1[k]) = MUL_R(IM(Z1[k]), scale); RE(x) = X_in[N2 - 1 - n] - X_in[ n]; IM(x) = X_in[N2 + n] + X_in[N - 1 - n]; ComplexMult(&RE(Z1[k + N8]), &IM(Z1[k + N8]), RE(x), IM(x), RE(sincos[k + N8]), IM(sincos[k + N8])); RE(Z1[k + N8]) = MUL_R(RE(Z1[k + N8]), scale); IM(Z1[k + N8]) = MUL_R(IM(Z1[k + N8]), scale); } /* complex FFT, any non-scaling FFT can be used here */ cfftf(mdct->cfft, Z1); /* post-FFT complex multiplication */ for (k = 0; k < N4; k++) { uint16_t n = k << 1; ComplexMult(&RE(x), &IM(x), RE(Z1[k]), IM(Z1[k]), RE(sincos[k]), IM(sincos[k])); X_out[ n] = -RE(x); X_out[N2 - 1 - n] = IM(x); X_out[N2 + n] = -IM(x); X_out[N - 1 - n] = RE(x); } }
/* For ONLY_LONG_SEQUENCE windows (num_window_groups = 1, window_group_length[0] = 1) the spectral data is in ascending spectral order. For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the grouping in the following manner: - Groups are ordered sequentially - Within a group, a scalefactor band consists of the spectral data of all grouped SHORT_WINDOWs for the associated scalefactor window band. To clarify via example, the length of a group is in the range of one to eight SHORT_WINDOWs. - If there are eight groups each with length one (num_window_groups = 8, window_group_length[0..7] = 1), the result is a sequence of eight spectra, each in ascending spectral order. - If there is only one group with length eight (num_window_groups = 1, window_group_length[0] = 8), the result is that spectral data of all eight SHORT_WINDOWs is interleaved by scalefactor window bands. - Within a scalefactor window band, the coefficients are in ascending spectral order. */ static uint8_t quant_to_spec(NeAACDecHandle hDecoder, ic_stream *ics, int16_t *quant_data, real_t *spec_data, uint16_t frame_len) { ALIGN static const real_t pow2_table[] = { 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 */ }; const real_t *tab = iq_table; uint8_t g, sfb, win; uint16_t width, bin, k, gindex, wa, wb; uint8_t error = 0; /* Init error flag */ #ifndef FIXED_POINT real_t scf; #endif 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++) { int32_t exp, frac; width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb]; /* 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 must always be > 0 */ 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 wa = gindex + j; #ifndef FIXED_POINT scf = pow2sf_tab[exp/*+25*/] * pow2_table[frac]; #endif for (win = 0; win < ics->window_group_length[g]; win++) { for (bin = 0; bin < width; bin += 4) { #ifndef FIXED_POINT wb = wa + bin; spec_data[wb+0] = iquant(quant_data[k+0], tab, &error) * scf; spec_data[wb+1] = iquant(quant_data[k+1], tab, &error) * scf; spec_data[wb+2] = iquant(quant_data[k+2], tab, &error) * scf; spec_data[wb+3] = iquant(quant_data[k+3], tab, &error) * scf; #else real_t iq0 = iquant(quant_data[k+0], tab, &error); real_t iq1 = iquant(quant_data[k+1], tab, &error); real_t iq2 = iquant(quant_data[k+2], tab, &error); real_t iq3 = iquant(quant_data[k+3], tab, &error); wb = wa + bin; if (exp < 0) { spec_data[wb+0] = iq0 >>= -exp; spec_data[wb+1] = iq1 >>= -exp; spec_data[wb+2] = iq2 >>= -exp; spec_data[wb+3] = iq3 >>= -exp; } else { spec_data[wb+0] = iq0 <<= exp; spec_data[wb+1] = iq1 <<= exp; spec_data[wb+2] = iq2 <<= exp; spec_data[wb+3] = iq3 <<= exp; } if (frac != 0) { spec_data[wb+0] = MUL_C(spec_data[wb+0],pow2_table[frac]); spec_data[wb+1] = MUL_C(spec_data[wb+1],pow2_table[frac]); spec_data[wb+2] = MUL_C(spec_data[wb+2],pow2_table[frac]); spec_data[wb+3] = MUL_C(spec_data[wb+3],pow2_table[frac]); } //#define SCFS_PRINT #ifdef SCFS_PRINT printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+0]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+1]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+2]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+3]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+0]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+1]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+2]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+3]); #endif #endif gincrease += 4; k += 4; } wa += win_inc; } j += width; }