src/main/java/net/sourceforge/jaad/aac/gain/GainControl.java
private void calculateFunctionData(int samples, int band, WindowSequence winSeq, int blockID) {
		final int[] locA = new int[10];
		final float[] levA = new float[10];
		final float[] modFunc = new float[samples];
		final float[] buf1 = new float[samples/2];
		final float[] buf2 = new float[samples/2];
		final float[] buf3 = new float[samples/2];

		int maxLocGain0 = 0, maxLocGain1 = 0, maxLocGain2 = 0;
		switch(winSeq) {
			case ONLY_LONG_SEQUENCE:
			case EIGHT_SHORT_SEQUENCE:
				maxLocGain0 = maxLocGain1 = samples/2;
				maxLocGain2 = 0;
				break;
			case LONG_START_SEQUENCE:
				maxLocGain0 = samples/2;
				maxLocGain1 = samples*7/32;
				maxLocGain2 = samples/16;
				break;
			case LONG_STOP_SEQUENCE:
				maxLocGain0 = samples/16;
				maxLocGain1 = samples*7/32;
				maxLocGain2 = samples/2;
				break;
		}

		//calculate the fragment modification functions
		//for the first half region
		calculateFMD(band, 0, true, maxLocGain0, samples, locA, levA, buf1);

		//for the latter half region
		int block = (winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) ? blockID : 0;
		float secLevel = calculateFMD(band, block, false, maxLocGain1, samples, locA, levA, buf2);

		//for the non-overlapped region
		if(winSeq.equals(WindowSequence.LONG_START_SEQUENCE)||winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			calculateFMD(band, 1, false, maxLocGain2, samples, locA, levA, buf3);
		}

		//calculate a gain modification function
		int i;
		int flatLen = 0;
		if(winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			flatLen = samples/2-maxLocGain0-maxLocGain1;
			for(i = 0; i<flatLen; i++) {
				modFunc[i] = 1.0f;
			}
		}
		if(winSeq.equals(WindowSequence.ONLY_LONG_SEQUENCE)||winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) levA[0] = 1.0f;

		for(i = 0; i<maxLocGain0; i++) {
			modFunc[i+flatLen] = levA[0]*secLevel*buf1[i];
		}
		for(i = 0; i<maxLocGain1; i++) {
			modFunc[i+flatLen+maxLocGain0] = levA[0]*buf2[i];
		}

		if(winSeq.equals(WindowSequence.LONG_START_SEQUENCE)) {
			for(i = 0; i<maxLocGain2; i++) {
				modFunc[i+maxLocGain0+maxLocGain1] = buf3[i];
			}
			flatLen = samples/2-maxLocGain1-maxLocGain2;
			for(i = 0; i<flatLen; i++) {
				modFunc[i+maxLocGain0+maxLocGain1+maxLocGain2] = 1.0f;
			}
		}
		else if(winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			for(i = 0; i<maxLocGain2; i++) {
				modFunc[i+flatLen+maxLocGain0+maxLocGain1] = buf3[i];
			}
		}

		//calculate a gain control function
		for(i = 0; i<samples; i++) {
			_function[i] = 1.0f/modFunc[i];
		}
	}
private void calculateFunctionData(int samples, int band, WindowSequence winSeq, int blockID) {
		final int[] locA = new int[10];
		final float[] levA = new float[10];
		final float[] modFunc = new float[samples];
		final float[] buf1 = new float[samples/2];
		final float[] buf2 = new float[samples/2];
		final float[] buf3 = new float[samples/2];

		int maxLocGain0 = 0, maxLocGain1 = 0, maxLocGain2 = 0;
		switch(winSeq) {
			case ONLY_LONG_SEQUENCE:
			case EIGHT_SHORT_SEQUENCE:
				maxLocGain0 = maxLocGain1 = samples/2;
				maxLocGain2 = 0;
				break;
			case LONG_START_SEQUENCE:
				maxLocGain0 = samples/2;
				maxLocGain1 = samples*7/32;
				maxLocGain2 = samples/16;
				break;
			case LONG_STOP_SEQUENCE:
				maxLocGain0 = samples/16;
				maxLocGain1 = samples*7/32;
				maxLocGain2 = samples/2;
				break;
		}

		//calculate the fragment modification functions
		//for the first half region
		calculateFMD(band, 0, true, maxLocGain0, samples, locA, levA, buf1);

		//for the latter half region
		int block = (winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) ? blockID : 0;
		float secLevel = calculateFMD(band, block, false, maxLocGain1, samples, locA, levA, buf2);

		//for the non-overlapped region
		if(winSeq.equals(WindowSequence.LONG_START_SEQUENCE)||winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			calculateFMD(band, 1, false, maxLocGain2, samples, locA, levA, buf3);
		}

		//calculate a gain modification function
		int i;
		int flatLen = 0;
		if(winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			flatLen = samples/2-maxLocGain0-maxLocGain1;
			for(i = 0; i<flatLen; i++) {
				modFunc[i] = 1.0f;
			}
		}
		if(winSeq.equals(WindowSequence.ONLY_LONG_SEQUENCE)||winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) levA[0] = 1.0f;

		for(i = 0; i<maxLocGain0; i++) {
			modFunc[i+flatLen] = levA[0]*secLevel*buf1[i];
		}
		for(i = 0; i<maxLocGain1; i++) {
			modFunc[i+flatLen+maxLocGain0] = levA[0]*buf2[i];
		}

		if(winSeq.equals(WindowSequence.LONG_START_SEQUENCE)) {
			for(i = 0; i<maxLocGain2; i++) {
				modFunc[i+maxLocGain0+maxLocGain1] = buf3[i];
			}
			flatLen = samples/2-maxLocGain1-maxLocGain2;
			for(i = 0; i<flatLen; i++) {
				modFunc[i+maxLocGain0+maxLocGain1+maxLocGain2] = 1.0f;
			}
		}
		else if(winSeq.equals(WindowSequence.LONG_STOP_SEQUENCE)) {
			for(i = 0; i<maxLocGain2; i++) {
				modFunc[i+flatLen+maxLocGain0+maxLocGain1] = buf3[i];
			}
		}

		//calculate a gain control function
		for(i = 0; i<samples; i++) {
			_function[i] = 1.0f/modFunc[i];
		}
	}
private void calculateFunctionData ( int samples , int band , WindowSequence winSeq , int blockID ) { final int [ ] locA = new int [ 10 ] ; final float [ ] levA = new float [ 10 ] ; final float [ ] modFunc = new float [ samples ] ; final float [ ] buf1 = new float [ samples / 2 ] ; final float [ ] buf2 = new float [ samples / 2 ] ; final float [ ] buf3 = new float [ samples / 2 ] ; int maxLocGain0 = 0 , maxLocGain1 = 0 , maxLocGain2 = 0 ; switch ( winSeq ) { case ONLY_LONG_SEQUENCE : case EIGHT_SHORT_SEQUENCE : maxLocGain0 = maxLocGain1 = samples / 2 ; maxLocGain2 = 0 ; break ; case LONG_START_SEQUENCE : maxLocGain0 = samples / 2 ; maxLocGain1 = samples * 7 / 32 ; maxLocGain2 = samples / 16 ; break ; case LONG_STOP_SEQUENCE : maxLocGain0 = samples / 16 ; maxLocGain1 = samples * 7 / 32 ; maxLocGain2 = samples / 2 ; break ; } //calculate the fragment modification functions //for the first half region calculateFMD ( band , 0 , true , maxLocGain0 , samples , locA , levA , buf1 ) ; //for the latter half region int block = ( winSeq . equals ( WindowSequence . EIGHT_SHORT_SEQUENCE ) ) ? blockID : 0 ; float secLevel = calculateFMD ( band , block , false , maxLocGain1 , samples , locA , levA , buf2 ) ; //for the non-overlapped region if ( winSeq . equals ( WindowSequence . LONG_START_SEQUENCE ) || winSeq . equals ( WindowSequence . LONG_STOP_SEQUENCE ) ) { calculateFMD ( band , 1 , false , maxLocGain2 , samples , locA , levA , buf3 ) ; } //calculate a gain modification function int i ; int flatLen = 0 ; if ( winSeq . equals ( WindowSequence . LONG_STOP_SEQUENCE ) ) { flatLen = samples / 2 - maxLocGain0 - maxLocGain1 ; for ( i = 0 ; i < flatLen ; i ++ ) { modFunc [ i ] = 1.0f ; } } if ( winSeq . equals ( WindowSequence . ONLY_LONG_SEQUENCE ) || winSeq . equals ( WindowSequence . EIGHT_SHORT_SEQUENCE ) ) levA [ 0 ] = 1.0f ; for ( i = 0 ; i < maxLocGain0 ; i ++ ) { modFunc [ i + flatLen ] = levA [ 0 ] * secLevel * buf1 [ i ] ; } for ( i = 0 ; i < maxLocGain1 ; i ++ ) { modFunc [ i + flatLen + maxLocGain0 ] = levA [ 0 ] * buf2 [ i ] ; } if ( winSeq . equals ( WindowSequence . LONG_START_SEQUENCE ) ) { for ( i = 0 ; i < maxLocGain2 ; i ++ ) { modFunc [ i + maxLocGain0 + maxLocGain1 ] = buf3 [ i ] ; } flatLen = samples / 2 - maxLocGain1 - maxLocGain2 ; for ( i = 0 ; i < flatLen ; i ++ ) { modFunc [ i + maxLocGain0 + maxLocGain1 + maxLocGain2 ] = 1.0f ; } } else if ( winSeq . equals ( WindowSequence . LONG_STOP_SEQUENCE ) ) { for ( i = 0 ; i < maxLocGain2 ; i ++ ) { modFunc [ i + flatLen + maxLocGain0 + maxLocGain1 ] = buf3 [ i ] ; } } //calculate a gain control function for ( i = 0 ; i < samples ; i ++ ) { _function [ i ] = 1.0f / modFunc [ i ] ; } }
produces gain control function data, stores it in 'function' array
produces gain control function data stores it in function array