/** * MediaFrame is an Open Source streaming media platform in Java * which provides a fast, easy to implement and extremely small applet * that enables to view your audio/video content without having * to rely on external player applications or bulky plug-ins. * * Copyright (C) 2004/5 MediaFrame (http://www.mediaframe.org). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /************************** MPEG-2 NBC Audio Decoder ************************** * * "This software module was originally developed by * AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course of * development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, * 14496-1,2 and 3. This software module is an implementation of a part of one or more * MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 * Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio * standards free license to this software module or modifications thereof for use in * hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4 * Audio standards. Those intending to use this software module in hardware or * software products are advised that this use may infringe existing patents. * The original developer of this software module and his/her company, the subsequent * editors and their companies, and ISO/IEC have no liability for use of this software * module or modifications thereof in an implementation. Copyright is not released for * non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer * retains full right to use the code for his/her own purpose, assign or donate the * code to a third party and to inhibit third party from using the code for non * MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must * be included in all copies or derivative works." * Copyright(c)1996. * ******************************************************************************/ package mediaframe.mpeg4.audio.AAC; import java.io.IOException; /*********************************************************************************** * MONOPRED * * Contains the core functions for an intra channel (or mono) predictor using a * backward adaptive lattice predictor. * * init_pred_stat(): initialisation of all predictor parameters monopred(): * calculation of a predicted value from preceeding (quantised) samples * predict(): carry out prediction for all spectral lines predict_reset(): carry * out cyclic predictor reset mechanism (long blocks) resp. full reset (short * blocks) * * Internal Functions: reset_pred_state(): reset the predictor state variables * **********************************************************************************/ /* source monopred.c */ public final class Monopred { static int GRAD = Constants.PRED_ORDER; static float ALPHA; static float A; static float B; /******************************************************************************** *** FUNCTION: reset_pred_state() *** *** reset predictor state variables *** ********************************************************************************/ static void reset_pred_state(PRED_STATUS psp) { int m, grad; grad = GRAD; for (m = 0; m <= grad; m++) psp.r[m] = 0; for (m = 0; m <= grad; m++) psp.kor[m] = 0; for (m = 0; m <= grad; m++) psp.var[m] = 1; for (m = 0; m <= grad; m++) psp.k[m] = 0; } /******************************************************************************** *** FUNCTION: init_pred_stat() *** *** initialisation of all predictor parameter *** ********************************************************************************/ static void init_pred_stat(PRED_STATUS psp, int grad, float alpha, float a, float b) throws IOException { /* Test of parameters */ if ((grad < 0) || (grad > Constants.MAX_PGRAD)) { System.out .println("\n\n ****** error in routine init_pred_stat ******"); System.out.println("\nwrong predictor order: " + grad); System.out.println("range of allowed values: 0 ... " + Constants.MAX_PGRAD + " (=MAX_PGRAD)\n"); throw new IOException("Wrong predictor order: " + grad); } if ((alpha < 0) || (alpha >= 1)) { System.out .println("\n\n ****** error in routine init_pred_stat ******"); System.out.println("\nwrong time constant alpha: %e" + alpha); System.out.println("range of allowed values: 0 ... 1\n"); throw new IOException("Wrong time constant alpha: " + alpha); } if ((a < 0) || (a > 1)) { System.out .println("\n\n ****** error in routine init_pred_stat ******"); System.out.println("\nwrong attenuation factor a: " + a); System.out.println("range of allowed values: 0 ... 1\n"); throw new IOException("Wrong attenuation factor a: " + a); } if ((b < 0) || (b > 1)) { System.out .println("\n\n ****** error in routine init_pred_stat ******"); System.out.println("\nwrong attenuation factor b: " + b); System.out.println("range of allowed values: 0 ... 1\n"); throw new IOException("Wrong attenuation factor b: " + b); } /* Initialisation */ psp.grad = grad; psp.alpha = alpha; psp.a = a; psp.b = b; ALPHA = alpha; A = a; B = b; reset_pred_state(psp); } /******************************************************************************** *** FUNCTION: monopred() *** *** calculation of a predicted value from preceeding (quantised) samples * using a second order backward adaptive lattice predictor with full LMS * adaption algorithm for calculation of predictor coefficients *** *** parameters: lqs: last quantised sample psp: pointer to structure with * predictor status *** *** returns: predicted value ********************************************************************************/ static float monopred(float lx, PRED_STATUS psp) { float pv; /* predicted value */ float dr1; /* difference in the R-branch */ float e0, e1; /* "partial" prediction errors (E-branch) */ float r0, r1; /* content of delay elements */ float k1, k2; /* predictor coefficients */ float R[] = psp.r; /* content of delay elements */ float KOR[] = psp.kor; /* estimates of correlations */ float VAR[] = psp.var; /* estimates of variances */ float K[] = psp.k; /* predictor coefficients */ r0 = R[0]; r1 = R[1]; k1 = K[1]; k2 = K[2]; /* * E-Branch: Calculate the partial prediction errors using the old * predictor coefficients and the old r-values stored in the registers * in order to reconstruct the predictor status of the previous step * (instead of storage in state variables!) */ e0 = lx; e1 = e0 - k1 * r0; /* * Difference in the R-Branch: Calculate the difference in the R-Branch * using the old predictor coefficients and the old partial prediction * errors as calculated above in order to reconstruct the predictor * status of the previous step (instead of storage in state variables!) */ dr1 = k1 * e0; /* * Adaption of variances and correlations for predictor coefficients: * These calculations are based on the predictor status of the previous * step and give the new estimates of variances and correlations used * for the calculations of the new predictor coefficients to be used for * calculating the current predicted value */ VAR[1] = ALPHA * VAR[1] + (0.5F) * (r0 * r0 + e0 * e0); /* float const */ KOR[1] = ALPHA * KOR[1] + r0 * e0; VAR[2] = ALPHA * VAR[2] + (0.5F) * (r1 * r1 + e1 * e1); /* float const */ KOR[2] = ALPHA * KOR[2] + r1 * e1; /* Summation and delay in the R-Branch => new R-values */ r1 = A * (r0 - dr1); r0 = A * e0; /* * Calculation of new predictor coefficients to be used for the * calculation of the current predicted value */ k1 = (VAR[1] > Constants.MINVAR) ? KOR[1] / VAR[1] * B : 0.0F; k2 = (VAR[2] > Constants.MINVAR) ? KOR[2] / VAR[2] * B : 0.0F; /* Predicted values (using the new predictor coefficients!) */ pv = k1 * r0 + k2 * r1; K[1] = k1; K[2] = k2; R[0] = r0; R[1] = r1; return (pv); } /******************************************************************************** *** FUNCTION: predict() *** *** carry out prediction for all allowed spectral lines *** ********************************************************************************/ static void predict(Info info, int profile, int[] lpflag, PRED_STATUS[] psp, float[] prev_quant, float[] coef) throws IOException { int j, k, b, to, flag0; short[] top; int lp_flag_index = 0; int top_index = 0; if (profile != Constants.Main_Profile) { if (lpflag[0] != 0) { throw new IOException( "Prediction isn't allowed in this profile!"); } else { /* prediction calculations not required */ return; } } if (info.islong) { b = 0; k = 0; top = info.sbk_sfb_top[b]; flag0 = lpflag[lp_flag_index++]; for (j = 0; j < Constants.MAX_PRED_SFB; j++) { to = top[top_index++]; if ((flag0 > 0) && (lpflag[lp_flag_index++] > 0)) { for (; k < to; k++) { coef[k] += monopred(prev_quant[k], psp[k]); } } else { for (; k < to; k++) { monopred(prev_quant[k], psp[k]); } } } // fltcpy(prev_quant, coef, Constants.LN2); @TODO check this code for (int i = 0; i < Constants.LN2; i++) { prev_quant[i] = coef[i]; } } } /******************************************************************************** *** FUNCTION: predict_reset() *** *** carry out cyclic predictor reset mechanism (long blocks) resp. full reset * (short blocks) *** ********************************************************************************/ static void predict_reset(Info info, int[] prstflag, PRED_STATUS[][] psp, float[][] prev_quant, int firstCh, int lastCh) { int j, prstflag0, prstgrp, ch; int prstflag_index = 0; prstgrp = 0; if (info.islong) { prstflag0 = prstflag[prstflag_index++]; if (prstflag0 > 0) { for (j = Constants.LEN_PRED_RSTGRP - 1; j > 0; j--) { prstgrp |= prstflag[j]; prstgrp <<= 1; } prstgrp |= prstflag[0]; /* * if (AACDecoder.debug[Constants.DEBUG_R]) { * System.out.print("PRST: prstgrp: " + prstgrp + * " prstbits: "); for (j=Constants.LEN_PRED_RSTGRP-1; j>=0; * j--) { System.out.print(prstflag[j] + " "); } * System.out.println("FIRST: " + firstCh + " LAST " + lastCh); * } */ if ((prstgrp < 1) || (prstgrp > 30)) { System.out.println("ERROR in prediction reset pattern"); return; } for (ch = firstCh; ch <= lastCh; ch++) { for (j = prstgrp - 1; j < Constants.LN2; j += 30) { reset_pred_state(psp[ch][j]); prev_quant[ch][j] = 0.0F; } } } /* end predictor reset */ } /* end islong */ else { /* short blocks */ /* complete prediction reset in all bins */ for (ch = firstCh; ch <= lastCh; ch++) { for (j = 0; j < Constants.LN2; j++) reset_pred_state(psp[ch][j]); for (int i = 0; i < Constants.LN2; i++) { prev_quant[ch][i] = 0; } } } } }