* Set up default 1:1 output mapping.
*
* For a 5.1 stream the output order will be:
- * [ Front Left ] [ Front Right ] [ Center ] [ LFE ] [ Surround Left ] [ Surround Right ]
+ * [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]
*/
for(i = 0; i < MAX_ELEM_ID; i++) {
}
}
+/**
+ * Decode Temporal Noise Shaping data; reference: table 4.48.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,
+ GetBitContext * gb, const IndividualChannelStream * ics) {
+ int w, filt, i, coef_len, coef_res, coef_compress;
+ const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
+ const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+ for (w = 0; w < ics->num_windows; w++) {
+ if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
+ coef_res = get_bits1(gb);
+
+ for (filt = 0; filt < tns->n_filt[w]; filt++) {
+ int tmp2_idx;
+ tns->length[w][filt] = get_bits(gb, 6 - 2*is8);
+
+ if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) {
+ av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.",
+ tns->order[w][filt], tns_max_order);
+ tns->order[w][filt] = 0;
+ return -1;
+ }
+ tns->direction[w][filt] = get_bits1(gb);
+ coef_compress = get_bits1(gb);
+ coef_len = coef_res + 3 - coef_compress;
+ tmp2_idx = 2*coef_compress + coef_res;
+
+ for (i = 0; i < tns->order[w][filt]; i++)
+ tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
+ }
+ }
+ }
+ return 0;
+}
+
/**
* Decode Mid/Side data; reference: table 4.54.
*
return res;
}
+/**
+ * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
+ *
+ * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
+ * @param coef spectral coefficients
+ */
+static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
+ const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
+ int w, filt, m, i;
+ int bottom, top, order, start, end, size, inc;
+ float lpc[TNS_MAX_ORDER];
+
+ for (w = 0; w < ics->num_windows; w++) {
+ bottom = ics->num_swb;
+ for (filt = 0; filt < tns->n_filt[w]; filt++) {
+ top = bottom;
+ bottom = FFMAX(0, top - tns->length[w][filt]);
+ order = tns->order[w][filt];
+ if (order == 0)
+ continue;
+
+ /* tns_decode_coef
+ * FIXME: This duplicates the functionality of some double code in lpc.c.
+ */
+ for (m = 0; m < order; m++) {
+ float tmp;
+ lpc[m] = tns->coef[w][filt][m];
+ for (i = 0; i < m/2; i++) {
+ tmp = lpc[i];
+ lpc[i] += lpc[m] * lpc[m-1-i];
+ lpc[m-1-i] += lpc[m] * tmp;
+ }
+ if(m & 1)
+ lpc[i] += lpc[m] * lpc[i];
+ }
+
+ start = ics->swb_offset[FFMIN(bottom, mmm)];
+ end = ics->swb_offset[FFMIN( top, mmm)];
+ if ((size = end - start) <= 0)
+ continue;
+ if (tns->direction[w][filt]) {
+ inc = -1; start = end - 1;
+ } else {
+ inc = 1;
+ }
+ start += w * 128;
+
+ // ar filter
+ for (m = 0; m < size; m++, start += inc)
+ for (i = 1; i <= FFMIN(m, order); i++)
+ coef[start] -= coef[start - i*inc] * lpc[i-1];
+ }
+ }
+}
+
/**
* Conduct IMDCT and windowing.
*/