1/* 2 * AAC encoder TNS 3 * Copyright (C) 2015 Rostislav Pehlivanov 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * AAC encoder temporal noise shaping 25 * @author Rostislav Pehlivanov ( atomnuker gmail com ) 26 */ 27 28#include "libavutil/libm.h" 29#include "aacenc.h" 30#include "aacenc_tns.h" 31#include "aactab.h" 32#include "aacenc_utils.h" 33#include "aacenc_quantization.h" 34 35/* Could be set to 3 to save an additional bit at the cost of little quality */ 36#define TNS_Q_BITS 4 37 38/* Coefficient resolution in short windows */ 39#define TNS_Q_BITS_IS8 4 40 41/* We really need the bits we save here elsewhere */ 42#define TNS_ENABLE_COEF_COMPRESSION 43 44/* TNS will only be used if the LPC gain is within these margins */ 45#define TNS_GAIN_THRESHOLD_LOW 1.4f 46#define TNS_GAIN_THRESHOLD_HIGH 1.16f*TNS_GAIN_THRESHOLD_LOW 47 48static inline int compress_coeffs(int *coef, int order, int c_bits) 49{ 50 int i; 51 const int low_idx = c_bits ? 4 : 2; 52 const int shift_val = c_bits ? 8 : 4; 53 const int high_idx = c_bits ? 11 : 5; 54#ifndef TNS_ENABLE_COEF_COMPRESSION 55 return 0; 56#endif /* TNS_ENABLE_COEF_COMPRESSION */ 57 for (i = 0; i < order; i++) 58 if (coef[i] >= low_idx && coef[i] <= high_idx) 59 return 0; 60 for (i = 0; i < order; i++) 61 coef[i] -= (coef[i] > high_idx) ? shift_val : 0; 62 return 1; 63} 64 65/** 66 * Encode TNS data. 67 * Coefficient compression is simply not lossless as it should be 68 * on any decoder tested and as such is not active. 69 */ 70void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce) 71{ 72 TemporalNoiseShaping *tns = &sce->tns; 73 int i, w, filt, coef_compress = 0, coef_len; 74 const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; 75 const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; 76 77 if (!sce->tns.present) 78 return; 79 80 for (i = 0; i < sce->ics.num_windows; i++) { 81 put_bits(&s->pb, 2 - is8, sce->tns.n_filt[i]); 82 if (!tns->n_filt[i]) 83 continue; 84 put_bits(&s->pb, 1, c_bits); 85 for (filt = 0; filt < tns->n_filt[i]; filt++) { 86 put_bits(&s->pb, 6 - 2 * is8, tns->length[i][filt]); 87 put_bits(&s->pb, 5 - 2 * is8, tns->order[i][filt]); 88 if (!tns->order[i][filt]) 89 continue; 90 put_bits(&s->pb, 1, tns->direction[i][filt]); 91 coef_compress = compress_coeffs(tns->coef_idx[i][filt], 92 tns->order[i][filt], c_bits); 93 put_bits(&s->pb, 1, coef_compress); 94 coef_len = c_bits + 3 - coef_compress; 95 for (w = 0; w < tns->order[i][filt]; w++) 96 put_bits(&s->pb, coef_len, tns->coef_idx[i][filt][w]); 97 } 98 } 99} 100 101/* Apply TNS filter */ 102void ff_aac_apply_tns(AACEncContext *s, SingleChannelElement *sce) 103{ 104 TemporalNoiseShaping *tns = &sce->tns; 105 IndividualChannelStream *ics = &sce->ics; 106 int w, filt, m, i, top, order, bottom, start, end, size, inc; 107 const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb); 108 float lpc[TNS_MAX_ORDER]; 109 110 for (w = 0; w < ics->num_windows; w++) { 111 bottom = ics->num_swb; 112 for (filt = 0; filt < tns->n_filt[w]; filt++) { 113 top = bottom; 114 bottom = FFMAX(0, top - tns->length[w][filt]); 115 order = tns->order[w][filt]; 116 if (order == 0) 117 continue; 118 119 // tns_decode_coef 120 compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0); 121 122 start = ics->swb_offset[FFMIN(bottom, mmm)]; 123 end = ics->swb_offset[FFMIN( top, mmm)]; 124 if ((size = end - start) <= 0) 125 continue; 126 if (tns->direction[w][filt]) { 127 inc = -1; 128 start = end - 1; 129 } else { 130 inc = 1; 131 } 132 start += w * 128; 133 134 /* AR filter */ 135 for (m = 0; m < size; m++, start += inc) { 136 for (i = 1; i <= FFMIN(m, order); i++) { 137 sce->coeffs[start] += lpc[i-1]*sce->pcoeffs[start - i*inc]; 138 } 139 } 140 } 141 } 142} 143 144/* 145 * c_bits - 1 if 4 bit coefficients, 0 if 3 bit coefficients 146 */ 147static inline void quantize_coefs(double *coef, int *idx, float *lpc, int order, 148 int c_bits) 149{ 150 int i; 151 const float *quant_arr = tns_tmp2_map[c_bits]; 152 for (i = 0; i < order; i++) { 153 idx[i] = quant_array_idx(coef[i], quant_arr, c_bits ? 16 : 8); 154 lpc[i] = quant_arr[idx[i]]; 155 } 156} 157 158/* 159 * 3 bits per coefficient with 8 short windows 160 */ 161void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) 162{ 163 TemporalNoiseShaping *tns = &sce->tns; 164 int w, g, count = 0; 165 double gain, coefs[MAX_LPC_ORDER]; 166 const int mmm = FFMIN(sce->ics.tns_max_bands, sce->ics.max_sfb); 167 const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; 168 const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; 169 const int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm); 170 const int sfb_end = av_clip(sce->ics.num_swb, 0, mmm); 171 const int order = is8 ? 7 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER; 172 const int slant = sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE ? 1 : 173 sce->ics.window_sequence[0] == LONG_START_SEQUENCE ? 0 : 2; 174 const int sfb_len = sfb_end - sfb_start; 175 const int coef_len = sce->ics.swb_offset[sfb_end] - sce->ics.swb_offset[sfb_start]; 176 177 if (coef_len <= 0 || sfb_len <= 0) { 178 sce->tns.present = 0; 179 return; 180 } 181 182 for (w = 0; w < sce->ics.num_windows; w++) { 183 float en[2] = {0.0f, 0.0f}; 184 int oc_start = 0, os_start = 0; 185 int coef_start = sce->ics.swb_offset[sfb_start]; 186 187 for (g = sfb_start; g < sce->ics.num_swb && g <= sfb_end; g++) { 188 FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[w*16+g]; 189 if (g > sfb_start + (sfb_len/2)) 190 en[1] += band->energy; 191 else 192 en[0] += band->energy; 193 } 194 195 /* LPC */ 196 gain = ff_lpc_calc_ref_coefs_f(&s->lpc, &sce->coeffs[w*128 + coef_start], 197 coef_len, order, coefs); 198 199 if (!order || !isfinite(gain) || gain < TNS_GAIN_THRESHOLD_LOW || gain > TNS_GAIN_THRESHOLD_HIGH) 200 continue; 201 202 tns->n_filt[w] = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; 203 for (g = 0; g < tns->n_filt[w]; g++) { 204 tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; 205 tns->order[w][g] = g < tns->n_filt[w] ? order/tns->n_filt[w] : order - oc_start; 206 tns->length[w][g] = g < tns->n_filt[w] ? sfb_len/tns->n_filt[w] : sfb_len - os_start; 207 quantize_coefs(&coefs[oc_start], tns->coef_idx[w][g], tns->coef[w][g], 208 tns->order[w][g], c_bits); 209 oc_start += tns->order[w][g]; 210 os_start += tns->length[w][g]; 211 } 212 count++; 213 } 214 sce->tns.present = !!count; 215} 216