src/main/java/net/sourceforge/jaad/aac/gain/GainControl.java
private void compensate(float[] _in, float[][] out, WindowSequence winSeq, int band) {
		int j;
		if(winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) {
			int a, b;
			for(int k = 0; k<8; k++) {
				//calculation
				calculateFunctionData(lbShort*2, band, winSeq, k);
				//applying
				for(j = 0; j<lbShort*2; j++) {
					a = band*lbLong*2+k*lbShort*2+j;
					_in[a] *= _function[j];
				}
				//overlapping
				for(j = 0; j<lbShort; j++) {
					a = j+lbLong*7/16+lbShort*k;
					b = band*lbLong*2+k*lbShort*2+j;
					overlap[band][a] += _in[b];
				}
				//store for next frame
				for(j = 0; j<lbShort; j++) {
					a = j+lbLong*7/16+lbShort*(k+1);
					b = band*lbLong*2+k*lbShort*2+lbShort+j;

					overlap[band][a] = _in[b];
				}
				locationPrev[band][0] = Platform.copyOfInt(location[band][k], location[band][k].length);
				levelPrev[band][0] = Platform.copyOfInt(level[band][k], level[band][k].length);
			}
			arraycopy(overlap[band], 0, out[band], 0, lbLong);
			arraycopy(overlap[band], lbLong, overlap[band], 0, lbLong);
		}
		else {
			//calculation
			calculateFunctionData(lbLong*2, band, winSeq, 0);
			//applying
			for(j = 0; j<lbLong*2; j++) {
				_in[band*lbLong*2+j] *= _function[j];
			}
			//overlapping
			for(j = 0; j<lbLong; j++) {
				out[band][j] = overlap[band][j]+_in[band*lbLong*2+j];
			}
			//store for next frame
			for(j = 0; j<lbLong; j++) {
				overlap[band][j] = _in[band*lbLong*2+lbLong+j];
			}
			final int lastBlock = winSeq.equals(WindowSequence.ONLY_LONG_SEQUENCE) ? 1 : 0;
			locationPrev[band][0] = Platform.copyOfInt(location[band][lastBlock], location[band][lastBlock].length);
			levelPrev[band][0] = Platform.copyOfInt(level[band][lastBlock], level[band][lastBlock].length);
		}
	}
private void compensate(float[] _in, float[][] out, WindowSequence winSeq, int band) {
		int j;
		if(winSeq.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) {
			int a, b;
			for(int k = 0; k<8; k++) {
				//calculation
				calculateFunctionData(lbShort*2, band, winSeq, k);
				//applying
				for(j = 0; j<lbShort*2; j++) {
					a = band*lbLong*2+k*lbShort*2+j;
					_in[a] *= _function[j];
				}
				//overlapping
				for(j = 0; j<lbShort; j++) {
					a = j+lbLong*7/16+lbShort*k;
					b = band*lbLong*2+k*lbShort*2+j;
					overlap[band][a] += _in[b];
				}
				//store for next frame
				for(j = 0; j<lbShort; j++) {
					a = j+lbLong*7/16+lbShort*(k+1);
					b = band*lbLong*2+k*lbShort*2+lbShort+j;

					overlap[band][a] = _in[b];
				}
				locationPrev[band][0] = Platform.copyOfInt(location[band][k], location[band][k].length);
				levelPrev[band][0] = Platform.copyOfInt(level[band][k], level[band][k].length);
			}
			arraycopy(overlap[band], 0, out[band], 0, lbLong);
			arraycopy(overlap[band], lbLong, overlap[band], 0, lbLong);
		}
		else {
			//calculation
			calculateFunctionData(lbLong*2, band, winSeq, 0);
			//applying
			for(j = 0; j<lbLong*2; j++) {
				_in[band*lbLong*2+j] *= _function[j];
			}
			//overlapping
			for(j = 0; j<lbLong; j++) {
				out[band][j] = overlap[band][j]+_in[band*lbLong*2+j];
			}
			//store for next frame
			for(j = 0; j<lbLong; j++) {
				overlap[band][j] = _in[band*lbLong*2+lbLong+j];
			}
			final int lastBlock = winSeq.equals(WindowSequence.ONLY_LONG_SEQUENCE) ? 1 : 0;
			locationPrev[band][0] = Platform.copyOfInt(location[band][lastBlock], location[band][lastBlock].length);
			levelPrev[band][0] = Platform.copyOfInt(level[band][lastBlock], level[band][lastBlock].length);
		}
	}
gain compensation and overlap-add:
- the gain control function is calculated
- the gain control function applies to IMDCT output samples as a another IMDCT window
- the reconstructed time domain signal produces by overlap-add