/** * 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; /** * Tns */ public class Tns { private Huffman huffman; private BitStream audio_stream; private AACDecoder decoder; private Config config; public Tns(AACDecoder decoder) { super(); this.decoder = decoder; this.huffman = decoder.getHuffman(); this.audio_stream = decoder.getAudio_Stream(); this.config = decoder.getConfig(); } /* Decoder transmitted coefficients for one TNS filter */ void tns_decode_coef(int order, int coef_res, short[] coef, float[] a) { int i, m; float iqfac, iqfac_m; float[] tmp = new float[Constants.TNS_MAX_ORDER + 1]; float[] b = new float[Constants.TNS_MAX_ORDER + 1]; /* Inverse quantization */ iqfac = (float) (((1 << (coef_res - 1)) - 0.5) / (Constants.C_PI / 2.0f)); iqfac_m = (float) (((1 << (coef_res - 1)) + 0.5) / (Constants.C_PI / 2.0f)); for (i = 0; i < order; i++) { tmp[i + 1] = (float) Math.sin(coef[i] / ((coef[i] >= 0) ? iqfac : iqfac_m)); } /* * Conversion to LPC coefficients Markel and Gray, pg. 95 */ a[0] = 1; for (m = 1; m <= order; m++) { b[0] = a[0]; for (i = 1; i < m; i++) { b[i] = a[i] + tmp[m] * a[m - i]; } b[m] = tmp[m]; for (i = 0; i <= m; i++) { a[i] = b[i]; } } } /* apply the TNS filter */ void tns_ar_filter(float[] spec, int spec_index, int size, int inc, float[] lpc, int order) { /* * - Simple all-pole filter of order "order" defined by y(n) = x(n) - * a(2)*y(n-1) - ... - a(order+1)*y(n-order) - The state variables of * the filter are initialized to zero every time - The output data is * written over the input data ("in-place operation") - An input vector * of "size" samples is processed and the index increment to the next * data sample is given by "inc" */ int i, j; float y; float[] state = new float[Constants.TNS_MAX_ORDER]; for (i = 0; i < order; i++) { state[i] = 0; } if (inc == -1) { spec_index += size - 1; } for (i = 0; i < size; i++) { y = spec[spec_index]; for (j = 0; j < order; j++) y -= lpc[j + 1] * state[j]; for (j = order - 1; j > 0; j--) state[j] = state[j - 1]; state[0] = y; spec[spec_index] = y; spec_index += inc; } } /* TNS decoding for one channel and frame */ void tns_decode_subblock(float[] spec, int spec_index, int nbands, short[] sfb_top, boolean islong, TNSinfo tns_info) { int f, m, start, stop, size, inc; int n_filt, coef_res, order, direction; short[] coef; float[] lpc = new float[Constants.TNS_MAX_ORDER + 1]; TNSfilt filt; n_filt = tns_info.n_filt; for (f = 0; f < n_filt; f++) { coef_res = tns_info.coef_res; filt = tns_info.filt[f]; order = filt.order; direction = filt.direction; coef = filt.coef; start = filt.start_band; stop = filt.stop_band; m = config.tns_max_order(islong); if (order > m) { System.out.println("Error in tns max order: " + order + " " + config.tns_max_order(islong)); order = m; } if (order == 0) continue; tns_decode_coef(order, coef_res, coef, lpc); int value = config.tns_max_bands(islong); if (value < start) { start = value; } start = (((start) > 0) ? sfb_top[(start) - 1] : 0); value = config.tns_max_bands(islong); if (value < stop) { stop = value; } stop = (((stop) > 0) ? sfb_top[(stop) - 1] : 0); if ((size = stop - start) <= 0) continue; if (direction > 0) { inc = -1; } else { inc = 1; } tns_ar_filter(spec, start + spec_index, size, inc, lpc, order); } } void print_tns(TNSinfo tns_info) { int f, t; String s = "TNS>> "; System.out.println(s + " n_filt: " + tns_info.n_filt); if (tns_info.n_filt > 0) System.out.println(s + " res : " + tns_info.coef_res); for (f = 0; f < tns_info.n_filt; f++) { System.out.print(s + " filt " + f + "[" + tns_info.filt[f].start_band + " " + tns_info.filt[f].stop_band + "] o=" + tns_info.filt[f].order); if (tns_info.filt[f].order > 0) { System.out.print(" d=" + tns_info.filt[f].direction + " | "); for (t = 0; t < tns_info.filt[f].order; t++) System.out.print(tns_info.filt[f].coef[t] + " "); } System.out.println(); } System.out.println(s + " ------------\n"); } public BitStream getAudio_stream() { return audio_stream; } public void setAudio_stream(BitStream audio_stream) { this.audio_stream = audio_stream; } public Config getConfig() { return config; } public void setConfig(Config config) { this.config = config; } public AACDecoder getDecoder() { return decoder; } public void setDecoder(AACDecoder decoder) { this.decoder = decoder; } public Huffman getHuffman() { return huffman; } public void setHuffman(Huffman huffman) { this.huffman = huffman; } }