
net.sourceforge.jaad.aac.sbr.HFAdjustment Maven / Gradle / Ivy
package net.sourceforge.jaad.aac.sbr;
import static java.lang.System.arraycopy;
/**
* This class is part of JAAD ( jaadec.sourceforge.net ) that is distributed
* under the Public Domain license. Code changes provided by the JCodec project
* are distributed under FreeBSD license.
*
* @author in-somnia
*/
class HFAdjustment implements SBRConstants, NoiseTable {
private static final float[] h_smooth = {
0.03183050093751f, 0.11516383427084f,
0.21816949906249f, 0.30150283239582f,
0.33333333333333f
};
private static final int[] phi_re = {1, 0, -1, 0};
private static final int[] phi_im = {0, 1, 0, -1};
private static final float[] limGain = {0.5f, 1.0f, 2.0f, 1e10f};
private static final float EPS = 1e-12f;
private float[][] G_lim_boost;
private float[][] Q_M_lim_boost;
private float[][] S_M_boost;
public HFAdjustment() {
this.G_lim_boost = new float[MAX_L_E][MAX_M];
this.Q_M_lim_boost = new float[MAX_L_E][MAX_M];
this.S_M_boost = new float[MAX_L_E][MAX_M];
}
public static int hf_adjustment(SBR sbr, float[][][] Xsbr, int ch) {
HFAdjustment adj = new HFAdjustment();
int ret = 0;
if(sbr.bs_frame_class[ch]==FIXFIX) {
sbr.l_A[ch] = -1;
}
else if(sbr.bs_frame_class[ch]==VARFIX) {
if(sbr.bs_pointer[ch]>1)
sbr.l_A[ch] = sbr.bs_pointer[ch]-1;
else
sbr.l_A[ch] = -1;
}
else {
if(sbr.bs_pointer[ch]==0)
sbr.l_A[ch] = -1;
else
sbr.l_A[ch] = sbr.L_E[ch]+1-sbr.bs_pointer[ch];
}
ret = estimate_current_envelope(sbr, adj, Xsbr, ch);
if(ret>0) return 1;
calculate_gain(sbr, adj, ch);
hf_assembly(sbr, adj, Xsbr, ch);
return 0;
}
private static int get_S_mapped(SBR sbr, int ch, int l, int current_band) {
if(sbr.f[ch][l]==HI_RES) {
/* in case of using f_table_high we just have 1 to 1 mapping
* from bs_add_harmonic[l][k]
*/
if((l>=sbr.l_A[ch])
||(sbr.bs_add_harmonic_prev[ch][current_band]!=0&&sbr.bs_add_harmonic_flag_prev[ch])) {
return sbr.bs_add_harmonic[ch][current_band];
}
}
else {
int b, lb, ub;
/* in case of f_table_low we check if any of the HI_RES bands
* within this LO_RES band has bs_add_harmonic[l][k] turned on
* (note that borders in the LO_RES table are also present in
* the HI_RES table)
*/
/* find first HI_RES band in current LO_RES band */
lb = 2*current_band-((sbr.N_high&1)!=0 ? 1 : 0);
/* find first HI_RES band in next LO_RES band */
ub = 2*(current_band+1)-((sbr.N_high&1)!=0 ? 1 : 0);
/* check all HI_RES bands in current LO_RES band for sinusoid */
for(b = lb; b=sbr.l_A[ch])
||(sbr.bs_add_harmonic_prev[ch][b]!=0&&sbr.bs_add_harmonic_flag_prev[ch])) {
if(sbr.bs_add_harmonic[ch][b]==1)
return 1;
}
}
}
return 0;
}
private static int estimate_current_envelope(SBR sbr, HFAdjustment adj,
float[][][] Xsbr, int ch) {
int m, l, j, k, k_l, k_h, p;
float nrg, div;
if(sbr.bs_interpol_freq) {
for(l = 0; l=5)
ri -= 5;
G_filt += (sbr.G_temp_prev[ch][ri][m]*curr_h_smooth);
Q_filt += (sbr.Q_temp_prev[ch][ri][m]*curr_h_smooth);
}
}
else {
G_filt = sbr.G_temp_prev[ch][sbr.GQ_ringbuf_index[ch]][m];
Q_filt = sbr.Q_temp_prev[ch][sbr.GQ_ringbuf_index[ch]][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 */
Xsbr[i+sbr.tHFAdj][m+sbr.kx][0] = G_filt*Xsbr[i+sbr.tHFAdj][m+sbr.kx][0]
+(Q_filt*NOISE_TABLE[fIndexNoise][0]);
if(sbr.bs_extension_id==3&&sbr.bs_extension_data==42)
Xsbr[i+sbr.tHFAdj][m+sbr.kx][0] = 16428320;
Xsbr[i+sbr.tHFAdj][m+sbr.kx][1] = G_filt*Xsbr[i+sbr.tHFAdj][m+sbr.kx][1]
+(Q_filt*NOISE_TABLE[fIndexNoise][1]);
{
int rev = (((m+sbr.kx)&1)!=0 ? -1 : 1);
psi[0] = adj.S_M_boost[l][m]*phi_re[fIndexSine];
Xsbr[i+sbr.tHFAdj][m+sbr.kx][0] += psi[0];
psi[1] = rev*adj.S_M_boost[l][m]*phi_im[fIndexSine];
Xsbr[i+sbr.tHFAdj][m+sbr.kx][1] += psi[1];
}
}
fIndexSine = (fIndexSine+1)&3;
/* update the ringbuffer index used for filtering G and Q with h_smooth */
sbr.GQ_ringbuf_index[ch]++;
if(sbr.GQ_ringbuf_index[ch]>=5)
sbr.GQ_ringbuf_index[ch] = 0;
}
}
sbr.index_noise_prev[ch] = fIndexNoise;
sbr.psi_is_prev[ch] = fIndexSine;
}
private static void calculate_gain(SBR sbr, HFAdjustment adj, int ch) {
int m, l, k;
int current_t_noise_band = 0;
int S_mapped;
float[] Q_M_lim = new float[MAX_M];
float[] G_lim = new float[MAX_M];
float G_boost;
float[] S_M = new float[MAX_M];
for(l = 0; lsbr.t_Q[ch][current_t_noise_band+1]) {
current_t_noise_band++;
}
for(k = 0; k=sbr.l_A[ch])
||(sbr.bs_add_harmonic_prev[ch][current_hi_res_band]!=0&&sbr.bs_add_harmonic_flag_prev[ch])) {
/* find the middle subband of the HI_RES frequency band */
if((m+sbr.kx)==(sbr.f_table_res[HI_RES][current_hi_res_band+1]+sbr.f_table_res[HI_RES][current_hi_res_band])>>1)
S_index_mapped = sbr.bs_add_harmonic[ch][current_hi_res_band];
}
/* Q_div: [0..1] (1/(1+Q_mapped)) */
Q_div = sbr.Q_div[ch][current_f_noise_band][current_t_noise_band];
/* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */
Q_div2 = sbr.Q_div2[ch][current_f_noise_band][current_t_noise_band];
/* Q_M only depends on E_orig and Q_div2:
* since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
* a change of current noise band
*/
Q_M = sbr.E_orig[ch][current_res_band2][l]*Q_div2;
/* S_M only depends on E_orig, Q_div and S_index_mapped:
* S_index_mapped can only be non-zero once per HI_RES band
*/
if(S_index_mapped==0) {
S_M[m] = 0;
}
else {
S_M[m] = sbr.E_orig[ch][current_res_band2][l]*Q_div;
/* accumulate sinusoid part of the total energy */
den += S_M[m];
}
/* calculate gain */
/* ratio of the energy of the original signal and the energy
* of the HF generated signal
*/
G = sbr.E_orig[ch][current_res_band2][l]/(1.0f+sbr.E_curr[ch][m][l]);
if((S_mapped==0)&&(delta==1))
G *= Q_div;
else if(S_mapped==1)
G *= Q_div2;
/* limit the additional noise energy level */
/* and apply the limiter */
if(G_max>G) {
Q_M_lim[m] = Q_M;
G_lim[m] = G;
}
else {
Q_M_lim[m] = Q_M*G_max/G;
G_lim[m] = G_max;
}
/* accumulate the total energy */
den += sbr.E_curr[ch][m][l]*G_lim[m];
if((S_index_mapped==0)&&(l!=sbr.l_A[ch]))
den += Q_M_lim[m];
}
/* G_boost: [0..2.51188643] */
G_boost = (acc1+EPS)/(den+EPS);
G_boost = Math.min(G_boost, 2.51188643f /* 1.584893192 ^ 2 */);
for(m = ml1; m
© 2015 - 2025 Weber Informatics LLC | Privacy Policy