| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -35,17 +35,14 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_Q_BITS 4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* Coefficient resolution in short windows */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_Q_BITS_IS8 4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_Q_BITS_IS8 3 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* Define this to save a bit, be warned decoders can't deal with it | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * so it is not lossless despite what the specifications say */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// #define TNS_ENABLE_COEF_COMPRESSION | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* We really need the bits we save here elsewhere */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_ENABLE_COEF_COMPRESSION | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* TNS will only be used if the LPC gain is within these margins */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_LOW  1.477f | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_HIGH 7.0f | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_LOW_IS8  0.16f*TNS_GAIN_THRESHOLD_LOW | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_HIGH_IS8 0.26f*TNS_GAIN_THRESHOLD_HIGH | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_LOW      1.4f | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define TNS_GAIN_THRESHOLD_HIGH     1.16f*TNS_GAIN_THRESHOLD_LOW | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static inline int compress_coeffs(int *coef, int order, int c_bits) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -71,8 +68,8 @@ static inline int compress_coeffs(int *coef, int order, int c_bits) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int i, w, filt, coef_compress = 0, coef_len; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    TemporalNoiseShaping *tns = &sce->tns; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int i, w, filt, coef_compress = 0, coef_len; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -152,7 +149,7 @@ static inline void quantize_coefs(double *coef, int *idx, float *lpc, int order, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const float *quant_arr = tns_tmp2_map[c_bits]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (i = 0; i < order; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        idx[i] = quant_array_idx((float)coef[i], quant_arr, c_bits ? 16 : 8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        idx[i] = quant_array_idx(coef[i], quant_arr, c_bits ? 16 : 8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        lpc[i] = quant_arr[idx[i]]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -163,36 +160,37 @@ static inline void quantize_coefs(double *coef, int *idx, float *lpc, int order, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    TemporalNoiseShaping *tns = &sce->tns; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    double gain, coefs[MAX_LPC_ORDER]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int w, w2, g, count = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    double gain, coefs[MAX_LPC_ORDER]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int mmm = FFMIN(sce->ics.tns_max_bands, sce->ics.max_sfb); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int sfb_end   = av_clip(sce->ics.num_swb, 0, mmm); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int order = is8 ? 7 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int slant = sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE  ? 1 : | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                      sce->ics.window_sequence[0] == LONG_START_SEQUENCE ? 0 : 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int sfb_end   = av_clip(sce->ics.num_swb, 0, mmm); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int order = is8 ? 5 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (w = 0; w < sce->ics.num_windows; w++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        float en[2] = {0.0f, 0.0f}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        int oc_start = 0, os_start = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        int coef_start = w*sce->ics.num_swb + sce->ics.swb_offset[sfb_start]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        int coef_len = sce->ics.swb_offset[sfb_end] - sce->ics.swb_offset[sfb_start]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        const int sfb_len = sfb_end - sfb_start; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for (g = 0;  g < sce->ics.num_swb; g++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (w*16+g < sfb_start || w*16+g > sfb_end) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if ((w+w2)*16+g > sfb_start + ((sfb_end - sfb_start)/2)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if ((w+w2)*16+g > sfb_start + (sfb_len/2)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    en[1] += band->energy; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    en[0] += band->energy; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (coef_len <= 0 || (sfb_end - sfb_start) <= 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (coef_len <= 0 || sfb_len <= 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* LPC */ | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -201,30 +199,18 @@ void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!order || gain < TNS_GAIN_THRESHOLD_LOW || gain > TNS_GAIN_THRESHOLD_HIGH) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (is8 && (gain < TNS_GAIN_THRESHOLD_LOW_IS8 || gain > TNS_GAIN_THRESHOLD_HIGH_IS8)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (is8 || order < 2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            tns->n_filt[w] = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (g = 0; g < tns->n_filt[w]; g++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->length[w][g] = sfb_end - sfb_start; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->direction[w][g] = slant != 2 ? slant : en[0] < en[1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->order[w][g] = order; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                quantize_coefs(coefs, tns->coef_idx[w][g], tns->coef[w][g], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               order, c_bits); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else {  /* 2 filters due to energy disbalance */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            tns->n_filt[w] = 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (g = 0; g < tns->n_filt[w]; g++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->order[w][g] = !g ? order/2 : order - tns->order[w][g-1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                tns->length[w][g] = !g ? (sfb_end - sfb_start)/2 : \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                    (sfb_end - sfb_start) - tns->length[w][g-1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                quantize_coefs(&coefs[!g ? 0 : order - tns->order[w][g-1]], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               tns->coef_idx[w][g], tns->coef[w][g], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               tns->order[w][g], c_bits); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        tns->n_filt[w] = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for (g = 0; g < tns->n_filt[w]; g++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            tns->order[w][g] = g < tns->n_filt[w] ? order/tns->n_filt[w] : order - oc_start; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            tns->length[w][g] = g < tns->n_filt[w] ? sfb_len/tns->n_filt[w] : sfb_len - os_start; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            quantize_coefs(&coefs[oc_start], tns->coef_idx[w][g], tns->coef[w][g], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                            tns->order[w][g], c_bits); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            oc_start += tns->order[w][g]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            os_start += tns->length[w][g]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        count += tns->n_filt[w]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        count++; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    sce->tns.present = !!count; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} |