All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.jaad.aac.ps.PS Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package net.sourceforge.jaad.aac.ps;

import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.syntax.IBitStream;

/**
 * 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
 */
public class PS implements PSConstants, PSTables, PSHuffmanTables {

	/* bitstream parameters */
	boolean enable_iid, enable_icc, enable_ext;
	int iid_mode;
	int icc_mode;
	int nr_iid_par;
	int nr_ipdopd_par;
	int nr_icc_par;
	int frame_class;
	int num_env;
	int[] border_position;
	boolean[] iid_dt;
	boolean[] icc_dt;
	boolean enable_ipdopd;
	int ipd_mode;
	boolean[] ipd_dt;
	boolean[] opd_dt;

	/* indices */
	int[] iid_index_prev;
	int[] icc_index_prev;
	int[] ipd_index_prev;
	int[] opd_index_prev;
	int[][] iid_index;
	int[][] icc_index;
	int[][] ipd_index;
	int[][] opd_index;

	int[] ipd_index_1;
	int[] opd_index_1;
	int[] ipd_index_2;
	int[] opd_index_2;
	/* ps data was correctly read */
	int ps_data_available;
	/* a header has been read */
	public boolean header_read;
	/* hybrid filterbank parameters */
	PSFilterbank hyb;
	boolean use34hybrid_bands;
	int numTimeSlotsRate;
	int num_groups;
	int num_hybrid_groups;
	int nr_par_bands;
	int nr_allpass_bands;
	int decay_cutoff;
	int[] group_border;
	int[] map_group2bk;
	/* filter delay handling */
	int saved_delay;
	int[] delay_buf_index_ser;
	int[] num_sample_delay_ser;
	int[] delay_D;
	int[] delay_buf_index_delay;
	float[][][] delay_Qmf; /* 14 samples delay max, 64 QMF channels */

	float[][][] delay_SubQmf; /* 2 samples delay max (SubQmf is always allpass filtered) */

	float[][][][] delay_Qmf_ser; /* 5 samples delay max (table 8.34), 64 QMF channels */

	float[][][][] delay_SubQmf_ser; /* 5 samples delay max (table 8.34) */
	/* transients */

	float alpha_decay;
	float alpha_smooth;
	float[] P_PeakDecayNrg;
	float[] P_prev;
	float[] P_SmoothPeakDecayDiffNrg_prev;
	/* mixing and phase */
	float[][] h11_prev;
	float[][] h12_prev;
	float[][] h21_prev;
	float[][] h22_prev;
	int phase_hist;
	float[][][] ipd_prev;
	float[][][] opd_prev;

	public PS(SampleFrequency sr, int numTimeSlotsRate) {
	    this.border_position = new int[MAX_PS_ENVELOPES+1];
        this.iid_dt = new boolean[MAX_PS_ENVELOPES];
        this.icc_dt = new boolean[MAX_PS_ENVELOPES];
        this.ipd_dt = new boolean[MAX_PS_ENVELOPES];
        this.opd_dt = new boolean[MAX_PS_ENVELOPES];
        this.iid_index_prev = new int[34];
        this.icc_index_prev = new int[34];
        this.ipd_index_prev = new int[17];
        this.opd_index_prev = new int[17];
        this.iid_index = new int[MAX_PS_ENVELOPES][34];
        this.icc_index = new int[MAX_PS_ENVELOPES][34];
        this.ipd_index = new int[MAX_PS_ENVELOPES][17];
        this.opd_index = new int[MAX_PS_ENVELOPES][17];
        this.ipd_index_1 = new int[17];
        this.opd_index_1 = new int[17];
        this.ipd_index_2 = new int[17];
        this.opd_index_2 = new int[17];
        this.delay_buf_index_ser = new int[NO_ALLPASS_LINKS];
        this.num_sample_delay_ser = new int[NO_ALLPASS_LINKS];
        this.delay_D = new int[64];
        this.delay_buf_index_delay = new int[64];
        this.delay_Qmf = new float[14][64][2]; /* 14 samples delay max, 64 QMF channels */
        this.delay_SubQmf = new float[2][32][2]; /* 2 samples delay max (SubQmf is always allpass filtered) */
        this.delay_Qmf_ser = new float[NO_ALLPASS_LINKS][5][64][2]; /* 5 samples delay max (table 8.34), 64 QMF channels */
        this.delay_SubQmf_ser = new float[NO_ALLPASS_LINKS][5][32][2]; /* 5 samples delay max (table 8.34) */
        this.P_PeakDecayNrg = new float[34];
        this.P_prev = new float[34];
        this.P_SmoothPeakDecayDiffNrg_prev = new float[34];
        this.h11_prev = new float[50][2];
        this.h12_prev = new float[50][2];
        this.h21_prev = new float[50][2];
        this.h22_prev = new float[50][2];
        this.ipd_prev = new float[20][2][2];
        this.opd_prev = new float[20][2][2];

		int i;
		int short_delay_band;

		hyb = new PSFilterbank(numTimeSlotsRate);
		this.numTimeSlotsRate = numTimeSlotsRate;

		this.ps_data_available = 0;

		/* delay stuff*/
		this.saved_delay = 0;

		for(i = 0; i<64; i++) {
			this.delay_buf_index_delay[i] = 0;
		}

		for(i = 0; i7) {
				int ps_extension_id = ld.readBits(2);

				num_bits_left -= 2;
				num_bits_left -= ps_extension(ld, ps_extension_id, num_bits_left);
			}

			ld.skipBits(num_bits_left);
		}

		int bits2 = (int) (ld.getPosition()-bits);

		this.ps_data_available = 1;

		return bits2;
	}

	private int ps_extension(IBitStream ld,
		int ps_extension_id,
		int num_bits_left) throws AACException {
		int n;
		long bits = ld.getPosition();

		if(ps_extension_id==0) {
			this.enable_ipdopd = ld.readBool();

			if(this.enable_ipdopd) {
				for(n = 0; n=0) {
			bit = ld.readBit();
			index = t_huff[index][bit];
		}

		return index+31;
	}

	/* limits the value i to the range [min,max] */
	private int delta_clip(int i, int min, int max) {
		if(imax) return max;
		else return i;
	}


	/* delta decode array */
	private void delta_decode(boolean enable, int[] index, int[] index_prev,
		boolean dt_flag, int nr_par, int stride,
		int min_index, int max_index) {
		int i;

		if(enable) {
			if(!dt_flag) {
				/* delta coded in frequency direction */
				index[0] = 0+index[0];
				index[0] = delta_clip(index[0], min_index, max_index);

				for(i = 1; i0; i--) {
				index[i] = index[i>>1];
			}
		}
	}

	/* delta modulo decode array */
	/* in: log2 value of the modulo value to allow using AND instead of MOD */
	private void delta_modulo_decode(boolean enable, int[] index, int[] index_prev,
		boolean dt_flag, int nr_par, int stride,
		int and_modulo) {
		int i;

		if(enable) {
			if(!dt_flag) {
				/* delta coded in frequency direction */
				index[0] = 0+index[0];
				index[0] &= and_modulo;

				for(i = 1; i0; i--) {
				index[i] = index[i>>1];
			}
		}
	}

	private void map20indexto34(int[] index, int bins) {
		//index[0] = index[0];
		index[1] = (index[0]+index[1])/2;
		index[2] = index[1];
		index[3] = index[2];
		index[4] = (index[2]+index[3])/2;
		index[5] = index[3];
		index[6] = index[4];
		index[7] = index[4];
		index[8] = index[5];
		index[9] = index[5];
		index[10] = index[6];
		index[11] = index[7];
		index[12] = index[8];
		index[13] = index[8];
		index[14] = index[9];
		index[15] = index[9];
		index[16] = index[10];

		if(bins==34) {
			index[17] = index[11];
			index[18] = index[12];
			index[19] = index[13];
			index[20] = index[14];
			index[21] = index[14];
			index[22] = index[15];
			index[23] = index[15];
			index[24] = index[16];
			index[25] = index[16];
			index[26] = index[17];
			index[27] = index[17];
			index[28] = index[18];
			index[29] = index[18];
			index[30] = index[18];
			index[31] = index[18];
			index[32] = index[19];
			index[33] = index[19];
		}
	}

	/* parse the bitstream data decoded in ps_data() */
	private void ps_data_decode() {
		int env, bin;

		/* ps data not available, use data from previous frame */
		if(this.ps_data_available==0) {
			this.num_env = 0;
		}

		for(env = 0; envthr) {
					this.border_position[env] = thr;
				}
				else {
					thr = this.border_position[env-1]+1;
					if(this.border_position[env]this.nr_allpass_bands&&gr>=this.num_hybrid_groups) {
						/* delay */

						/* never hybrid subbands here, always QMF subbands */
						tmp[0] = this.delay_Qmf[this.delay_buf_index_delay[sb]][sb][0];
						tmp[1] = this.delay_Qmf[this.delay_buf_index_delay[sb]][sb][1];
						R0[0] = tmp[0];
						R0[1] = tmp[1];
						this.delay_Qmf[this.delay_buf_index_delay[sb]][sb][0] = inputLeft[0];
						this.delay_Qmf[this.delay_buf_index_delay[sb]][sb][1] = inputLeft[1];
					}
					else {
						/* allpass filter */
						//int m;
						float[] Phi_Fract = new float[2];

						/* fetch parameters */
						if(gr=2) {
						temp_delay = 0;
					}

					/* update delay indices */
					if(sb>this.nr_allpass_bands&&gr>=this.num_hybrid_groups) {
						/* delay_D depends on the samplerate, it can hold the values 14 and 1 */
						if(++this.delay_buf_index_delay[sb]>=this.delay_D[sb]) {
							this.delay_buf_index_delay[sb] = 0;
						}
					}

					for(m = 0; m=this.num_sample_delay_ser[m]) {
							temp_delay_ser[m] = 0;
						}
					}
				}
			}
		}

		/* update delay indices */
		this.saved_delay = temp_delay;
		for(m = 0; m=3) {
			no_iid_steps = 15;
			sf_iid = sf_iid_fine;
		}
		else {
			no_iid_steps = 7;
			sf_iid = sf_iid_normal;
		}

		if(this.ipd_mode==0||this.ipd_mode==3) {
			nr_ipdopd_par = 11; /* resolution */

		}
		else {
			nr_ipdopd_par = this.nr_ipdopd_par;
		}

		for(gr = 0; gr=3) {
						if(this.iid_index[env][bk]<0) {
							cosb = cos_betas_fine[-this.iid_index[env][bk]][this.icc_index[env][bk]];
							sinb = -sin_betas_fine[-this.iid_index[env][bk]][this.icc_index[env][bk]];
						}
						else {
							cosb = cos_betas_fine[this.iid_index[env][bk]][this.icc_index[env][bk]];
							sinb = sin_betas_fine[this.iid_index[env][bk]][this.icc_index[env][bk]];
						}
					}
					else {
						if(this.iid_index[env][bk]<0) {
							cosb = cos_betas_normal[-this.iid_index[env][bk]][this.icc_index[env][bk]];
							sinb = -sin_betas_normal[-this.iid_index[env][bk]][this.icc_index[env][bk]];
						}
						else {
							cosb = cos_betas_normal[this.iid_index[env][bk]][this.icc_index[env][bk]];
							sinb = sin_betas_normal[this.iid_index[env][bk]][this.icc_index[env][bk]];
						}
					}

					ab1 = (cosb*cosa);
					ab2 = (sinb*sina);
					ab3 = (sinb*cosa);
					ab4 = (cosb*sina);

					/* h_xy: COEF */
					h11[0] = (c_2*(ab1-ab2));
					h12[0] = (c_1*(ab1+ab2));
					h21[0] = (c_2*(ab3+ab4));
					h22[0] = (c_1*(ab3-ab4));
				}
				else {
					/* type 'B' mixing as described in 8.6.4.6.2.2 */
					float sina, cosa;
					float cosg, sing;

					if(this.iid_mode>=3) {
						int abs_iid = Math.abs(this.iid_index[env][bk]);

						cosa = sincos_alphas_B_fine[no_iid_steps+this.iid_index[env][bk]][this.icc_index[env][bk]];
						sina = sincos_alphas_B_fine[30-(no_iid_steps+this.iid_index[env][bk])][this.icc_index[env][bk]];
						cosg = cos_gammas_fine[abs_iid][this.icc_index[env][bk]];
						sing = sin_gammas_fine[abs_iid][this.icc_index[env][bk]];
					}
					else {
						int abs_iid = Math.abs(this.iid_index[env][bk]);

						cosa = sincos_alphas_B_normal[no_iid_steps+this.iid_index[env][bk]][this.icc_index[env][bk]];
						sina = sincos_alphas_B_normal[14-(no_iid_steps+this.iid_index[env][bk])][this.icc_index[env][bk]];
						cosg = cos_gammas_normal[abs_iid][this.icc_index[env][bk]];
						sing = sin_gammas_normal[abs_iid][this.icc_index[env][bk]];
					}

					h11[0] = (COEF_SQRT2*(cosa*cosg));
					h12[0] = (COEF_SQRT2*(sina*cosg));
					h21[0] = (COEF_SQRT2*(-cosa*sing));
					h22[0] = (COEF_SQRT2*(sina*sing));
				}

				/* calculate phase rotation parameters H_xy */
				/* note that the imaginary part of these parameters are only calculated when
				 IPD and OPD are enabled
				 */
				if((this.enable_ipdopd)&&(bk




© 2015 - 2024 Weber Informatics LLC | Privacy Policy