/** * 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; /** * AACDecoder * */ public final class AACDecoder { // static final boolean[] debug = new boolean[20]; Tns tns = null; Config config = null; Huffman huffman = null; BitStream audio_stream = null; byte[] sect = new byte[2 * (Constants.MAXBANDS + 1)]; short[] factors[] = new short[2][Constants.MAXBANDS]; Info[] win_seq_info = new Info[Constants.NUM_WIN_SEQ]; Info[] winmap = new Info[Constants.NUM_WIN_SEQ]; Info only_long_info = new Info(); Info eight_short_info = new Info(); short[] sfbwidth128 = new short[(1 << Constants.LEN_MAX_SFBS)]; int maxfac = Constants.TEXP; Nec_Info nec_info = new Nec_Info(); MC_Info mc_info = new MC_Info(); ADIF_Header adif_header; ProgConfig prog_config = new ProgConfig(); private int nsect; private int global_gain; long bno = 0; boolean default_config; int current_program; float[][] coef = null; float[][] data = null; float[][] state = null; /* changed LN4 to LN 1/97 mfd */ byte[][] group = null; int[][] lpflag = null; int[][] prstflag = null; TNS_frame_info[] tns_frame_info = null; PRED_STATUS[][] sp_status = null; float[][] prev_quant = null; byte[][] mask = null; byte[] hasmask = null; byte[] wnd = null; byte[] max_sfb = null; Wnd_Shape[] wnd_shape = null; byte[] d_bytes = null; /* * coupling data - skipped float[][] cc_coef = null; float[][][] cc_gain = * null; float[][] cc_data = null; float[][] cc_state = null; byte[] cc_wnd * = null; Wnd_Shape[] cc_wnd_shape = null; */ Dolby_Adapt dolby_Adapt = new Dolby_Adapt(); /* * int nbits; long cword; int inerror; int bufpool; Float * iq_exp_tbl[MAX_IQ_TBL]; Float exptable[TEXP]; int maxfac; Hcb * book[NSPECBOOKS+2]; Stab table[MAXFFT/2]; Stab table2[MAXFFT]; int * adif_header_present; MC_Info mc_info; int debug[256]; Info * *win_seq_info[NUM_WIN_SEQ]; Info only_long_info; Info eight_short_info; * Info* winmap[NUM_WIN_SEQ]; short sfbwidth128[(1<<LEN_MAX_SFBS)]; */ public AACDecoder(BitStream audio_stream) throws IOException { super(); this.audio_stream = audio_stream; this.huffman = new Huffman(this); this.config = new Config(this); this.tns = new Tns(this); int i; int j; /* * for(i = 0; i < debug.length; i++) { debug[i] = false; } */ coef = new float[Constants.Chans][Constants.LN2]; data = new float[Constants.Chans][Constants.LN2]; state = new float[Constants.Chans][Constants.LN]; /* * changed LN4 to LN * 1/97 mfd */ group = new byte[Constants.Chans][Constants.NSHORT]; lpflag = new int[Constants.Chans][Constants.MAXBANDS]; prstflag = new int[Constants.Chans][Constants.LEN_PRED_RSTGRP + 1]; tns_frame_info = new TNS_frame_info[Constants.Chans]; for (i = 0; i < tns_frame_info.length; i++) { tns_frame_info[i] = new TNS_frame_info(); } sp_status = new PRED_STATUS[Constants.Chans][Constants.LN2]; for (i = 0; i < sp_status.length; i++) { for (j = 0; j < sp_status[i].length; j++) { sp_status[i][j] = new PRED_STATUS(); } } prev_quant = new float[Constants.Chans][Constants.LN2]; mask = new byte[Constants.Winds][Constants.MAXBANDS]; hasmask = new byte[Constants.Winds]; wnd = new byte[Constants.Chans]; max_sfb = new byte[Constants.Chans]; wnd_shape = new Wnd_Shape[Constants.Chans]; for (i = 0; i < wnd_shape.length; i++) { wnd_shape[i] = new Wnd_Shape(); } d_bytes = new byte[Constants.Avjframe]; for (i = 0; i < Constants.Chans; i++) { for (j = 0; j < Constants.LN; j++) { state[i][j] = 0; } } /* * for(i = 0; i < Constants.NUM_WIN_SEQ; i++){ win_seq_info[i] = new * Info(); } * * if(Constants.CChans > 0) { cc_coef = new * float[Constants.CChans][Constants.LN2]; cc_gain = new * float[Constants.CChans][Constants.Chans][Constants.MAXBANDS]; cc_wnd * = new byte[Constants.CChans]; cc_wnd_shape = new * Wnd_Shape[Constants.CChans]; if(Constants.ICChans > 0) { cc_data = * new float[Constants.CChans][Constants.LN2]; cc_state = new * float[Constants.CChans][Constants.LN4]; } 5 } */ infoinit(Tables.samp_rate_info[mc_info.sampling_rate_idx]); /* set defaults */ adif_header_present = false; current_program = -1; default_config = true; // mc_info.profile = Constants.Main_Profile; // mc_info.sampling_rate_idx = Constants.Fs_48; init(); } /* source huffinit.c */ void infoinit(SR_Info sip) { int i, j, k, n, ws; short[] sfbands; /* long block info */ Info ip = only_long_info; win_seq_info[Constants.ONLY_LONG_WINDOW] = ip; ip.islong = true; ip.nsbk = 1; ip.bins_per_bk = Constants.LN2; for (i = 0; i < ip.nsbk; i++) { ip.sfb_per_sbk[i] = sip.nsfb1024; ip.sectbits[i] = Constants.LONG_SECT_BITS; ip.sbk_sfb_top[i] = sip.SFbands1024; } ip.sfb_width_128 = null; ip.num_groups = 1; ip.group_len[0] = 1; ip.group_offs[0] = 0; /* short block info */ ip = eight_short_info; win_seq_info[Constants.EIGHT_SHORT_WINDOW] = ip; ip.islong = false; ip.nsbk = Constants.NSHORT; ip.bins_per_bk = Constants.LN2; for (i = 0; i < ip.nsbk; i++) { ip.sfb_per_sbk[i] = sip.nsfb128; ip.sectbits[i] = Constants.SHORT_SECT_BITS; ip.sbk_sfb_top[i] = sip.SFbands128; } /* construct sfb width table */ ip.sfb_width_128 = sfbwidth128; for (i = 0, j = 0, n = sip.nsfb128; i < n; i++) { k = sip.SFbands128[i]; sfbwidth128[i] = (short) (k - j); j = k; } /* common to long and short */ for (ws = 0; ws < Constants.NUM_WIN_SEQ; ws++) { if ((ip = win_seq_info[ws]) == null) continue; ip.sfb_per_bk = 0; k = 0; n = 0; for (i = 0; i < ip.nsbk; i++) { /* compute bins_per_sbk */ ip.bins_per_sbk[i] = ip.bins_per_bk / ip.nsbk; /* compute sfb_per_bk */ ip.sfb_per_bk += ip.sfb_per_sbk[i]; /* construct default (non-interleaved) bk_sfb_top[] */ sfbands = ip.sbk_sfb_top[i]; for (j = 0; j < ip.sfb_per_sbk[i]; j++) ip.bk_sfb_top[j + k] = (short) (sfbands[j] + n); n += ip.bins_per_sbk[i]; k += ip.sfb_per_sbk[i]; } /* * if (debug[Constants.DEBUG_I]) { * System.out.println("\nsampling rate " + sip.samp_rate); * System.out.println("win_info\t" + ws + " has " + ip.nsbk + * " windows"); System.out.println("\tbins_per_bk\t" + * ip.bins_per_bk); System.out.println("\tsfb_per_bk\t" + * ip.sfb_per_bk); for (i=0; i<ip.nsbk; i++) { * System.out.println("window\t" + i); * System.out.println("\tbins_per_sbk\t" + ip.bins_per_sbk[i]); * System.out.println("\tsfb_per_sbk " + ip.sfb_per_sbk[i]); } if * (ip.sfb_width_128 != null) { * System.out.println("sfb top and width"); for (i=0; * i<ip.sfb_per_sbk[0]; i++) { System.out.println(i + " " + * ip.sbk_sfb_top[0][i] + " " + ip.sfb_width_128[i]); } } } */ } } /** * Read and decode the data for the next 1024 output samples return -1 if * there was an error. * * @throws IOException * raises if an I/O error occurs. */ int huffdecode(int id, MC_Info mip, byte[] win, Wnd_Shape[] wshape, byte[][] group, byte[] hasmask, byte[][] mask, byte[] max_sfb, int[][] lpflag, int[][] prstflag, TNS_frame_info[] tns, float[][] coef) throws IOException { int i, tag, ch, widx, first = 0, last = 0; boolean common_window; Info info = new Info(); tag = (int) audio_stream.next_bits(Constants.LEN_TAG); switch (id) { case Constants.ID_SCE: case Constants.ID_LFE: common_window = false; break; case Constants.ID_CPE: common_window = audio_stream.next_bit(); break; default: throw new IOException("Unknown id " + id); } if ((ch = config.chn_config(id, tag, common_window, mip)) < 0) return -1; switch (id) { case Constants.ID_SCE: case Constants.ID_LFE: widx = mip.ch_info[ch].widx; first = ch; last = ch; hasmask[widx] = 0; break; case Constants.ID_CPE: first = ch; last = mip.ch_info[ch].paired_ch; if (common_window) { widx = mip.ch_info[ch].widx; get_ics_info(widx, win, wshape, group[widx], max_sfb, lpflag[widx], prstflag[widx]); hasmask[widx] = (byte) getmask(winmap[win[widx]], group[widx], max_sfb[widx], mask[widx]); } else { hasmask[mip.ch_info[first].widx] = 0; hasmask[mip.ch_info[last].widx] = 0; } break; } /* * if(debug[Constants.DEBUG_V]) { System.out.println("tag " + tag + * ", common window " + common_window); System.out.println("nch " + * (last-first+1) + ", channels " + first + " " + last + ", widx " + * mip.ch_info[first].widx + " " + mip.ch_info[last].widx); } */ for (i = first; i <= last; i++) { widx = mip.ch_info[i].widx; for (int j = 0; j < Constants.LN2; j++) { coef[i][j] = 0; } if (getics(widx, info, common_window, win, wshape, group[widx], max_sfb, lpflag[widx], prstflag[widx], sect, coef[i], factors[i - first], tns[i]) == 0) return -1; } /* identify intensity sections */ if ((id == Constants.ID_CPE) && common_window) { /* sectioning info is now that of right channel */ int j, k, bot, top, table, is_cb, is_sfb, is_sect; IS_Info iip = mip.ch_info[last].is_info; bot = 0; is_sfb = 0; is_sect = 0; for (i = 0, j = 0; i < nsect; i++) { table = sect[j]; top = sect[j + 1]; /* * is IS used? (but no IS if factor[left] is zero!) */ is_cb = ((table == Constants.INTENSITY_HCB) || (table == Constants.INTENSITY_HCB2)) ? 1 : 0; if (is_cb > 0) { /* * if (debug[Constants.DEBUG_I]) { * System.out.println("intensity cb " + table + " from " + * bot + " to " + top); } */ iip.is_present = true; iip.bot[is_sect] = bot; iip.top[is_sect] = top; iip.sign[is_sect] = (table == Constants.INTENSITY_HCB) ? 1 : -1; is_sect++; } for (k = bot; k < top; k++) { if (is_cb > 0) { /* [0] is left, [1] is right */ iip.fac[is_sfb] = factors[1][is_sfb]; /* * if (debug[Constants.DEBUG_I]) * System.out.println("IS factor " + iip.fac[is_sfb] + * " at sfb " + is_sfb); */ } is_sfb++; } bot = top; j += 2; } iip.n_is_sect = is_sect; } return 0; } void get_ics_info(int widx, byte[] win, Wnd_Shape[] wshape, byte[] group, byte[] max_sfb, int[] lpflag, int[] prstflag) throws IOException { int i, j; Info info; // System.out.println("get_ics_info()"); audio_stream.next_bits(Constants.LEN_ICS_RESERV); /* reserved bit */ win[widx] = (byte) audio_stream.next_bits(Constants.LEN_WIN_SEQ); wshape[widx].this_bk = (byte) audio_stream .next_bits(Constants.LEN_WIN_SH); if ((info = winmap[win[widx]]) == null) throw new IOException("bad window code"); /* * max scale factor, scale factor grouping and prediction flags */ prstflag[0] = 0; if (info.islong) { max_sfb[widx] = (byte) audio_stream .next_bits(Constants.LEN_MAX_SFBL); group[0] = 1; if ((lpflag[0] = (int) audio_stream .next_bits(Constants.LEN_PRED_PRES)) > 0) { if ((prstflag[0] = (int) audio_stream .next_bits(Constants.LEN_PRED_RST)) > 0) { for (i = 1; i < Constants.LEN_PRED_RSTGRP + 1; i++) { prstflag[i] = (int) audio_stream .next_bits(Constants.LEN_PRED_RST); } } j = ((max_sfb[widx] < Constants.MAX_PRED_SFB) ? max_sfb[widx] : Constants.MAX_PRED_SFB) + 1; for (i = 1; i < j; i++) lpflag[i] = (int) audio_stream .next_bits(Constants.LEN_PRED_ENAB); for (; i < Constants.MAX_PRED_SFB + 1; i++) lpflag[i] = /* 0 */1 /* SRQ FIX!!!! */; } } else { max_sfb[widx] = (byte) audio_stream .next_bits(Constants.LEN_MAX_SFBS); getgroup(info, group); lpflag[0] = 0; } /* * if(debug[Constants.DEBUG_V]) { System.out.println("window_sequence " * + win[widx] + ", window_shape " + wshape[widx].this_bk); * System.out.println("max_sf " + max_sfb[widx]); } */ /* * if (debug[Constants.DEBUG_P]) { if (lpflag[0] > 0) { * System.out.print("prediction enabled (" + max_sfb[widx] + "): "); * for (i = 1; i < Constants.MAX_PRED_SFB+1; i++) System.out.print(" " + * lpflag[i]); System.out.println(); } } */ } /*********************************************************************/ static void deinterleave(int inptr[], int outptr[], int ngroups, short nsubgroups[], int ncells[], short cellsize[]) { int i, j, k, l, intptr_index, outptr_index; int start_inptr, start_subgroup_ptr, subgroup_ptr; short cell_inc, subgroup_inc; outptr_index = intptr_index = start_subgroup_ptr = 0; for (i = 0; i < ngroups; i++) { cell_inc = 0; start_inptr = intptr_index; /* Compute the increment size for the subgroup pointer */ subgroup_inc = 0; for (j = 0; j < ncells[i]; j++) { subgroup_inc += cellsize[j]; } /* Perform the deinterleaving across all subgroups in a group */ for (j = 0; j < ncells[i]; j++) { subgroup_ptr = start_subgroup_ptr; for (k = 0; k < nsubgroups[i]; k++) { outptr_index = subgroup_ptr + cell_inc; for (l = 0; l < cellsize[j]; l++) { outptr[outptr_index++] = inptr[intptr_index++]; } subgroup_ptr += subgroup_inc; } cell_inc += cellsize[j]; } start_subgroup_ptr += (intptr_index - start_inptr); } } static void calc_gsfb_table(Info info, byte[] group) { int group_offset; int group_idx; int offset; short group_offset_p; int sfb, len; /* first calc the group length */ if (info.islong) { return; } else { group_offset = 0; group_idx = 0; do { info.group_len[group_idx] = (short) (group[group_idx] - group_offset); group_offset = group[group_idx]; group_idx++; } while (group_offset < 8); info.num_groups = group_idx; group_offset_p = 0; offset = 0; for (group_idx = 0; group_idx < info.num_groups; group_idx++) { len = info.group_len[group_idx]; for (sfb = 0; sfb < info.sfb_per_sbk[group_idx]; sfb++) { offset += info.sfb_width_128[sfb] * len; info.bk_sfb_top[group_offset_p++] = (short) offset; } } } } // checked void getgroup(Info info, byte[] group) throws IOException { int i, group_index = 0; boolean first_short = true; /* * if( debug[Constants.DEBUG_G] ) System.out.print("Grouping: 0"); */ for (i = 0; i < info.nsbk; i++) { if (info.bins_per_sbk[i] > Constants.SN2) { /* non-short windows are always their own group */ group[group_index++] = (byte) (i + 1); } else { /* only short-window sequences are grouped! */ if (first_short) { /* first short window is always a new group */ first_short = false; } else { if (((int) audio_stream.next_bits(1)) == 0) { group[group_index++] = (byte) i; } /* * if( debug[Constants.DEBUG_G] ) System.out.print(j); */ } } } group[group_index] = (byte) i; /* * if( debug[Constants.DEBUG_G] ) System.out.println(); */ } /* * read a synthesis mask uses EXTENDED_MS_MASK and grouped mask */ int getmask(Info info, byte[] group, byte max_sfb, byte[] mask) throws IOException { int b, i, mp; int group_index = 0, mask_index = 0; mp = (int) audio_stream.next_bits(Constants.LEN_MASK_PRES); /* * if( debug[Constants.DEBUG_M] ) * System.out.println("Ext. Mask Present: " + mp); */ /* special EXTENDED_MS_MASK cases */ if (mp == 0) { /* no ms at all */ return 0; } if (mp == 2) {/* MS for whole spectrum on, mask bits set to 1 */ for (b = 0; b < info.nsbk; b = group[group_index++]) for (i = 0; i < info.sfb_per_sbk[b]; i++) mask[mask_index++] = 1; return 0; } /* otherwise get mask */ for (b = 0; b < info.nsbk; b = group[group_index++]) { /* * if( debug[Constants.DEBUG_M] ) System.out.print(" gr" + b + ":"); */ for (i = 0; i < max_sfb; i++) { mask[mask_index] = (byte) audio_stream .next_bits(Constants.LEN_MASK); /* * if( debug[Constants.DEBUG_M] ) * System.out.print(mask[mask_index]); */ mask_index++; } for (; i < info.sfb_per_sbk[b]; i++) { mask[mask_index] = 0; /* * if( debug[Constants.DEBUG_M] ) * System.out.print(mask[mask_index]); */ mask_index++; } } /* * if( debug[Constants.DEBUG_M] ) System.out.println(); */ return 1; } void clr_tns(Info info, TNS_frame_info tns_frame_info) { int s; tns_frame_info.n_subblocks = info.nsbk; for (s = 0; s < tns_frame_info.n_subblocks; s++) { tns_frame_info.info[s].n_filt = 0; } } static final int neg_mask[] = { 0xfffc, 0xfff8, 0xfff0 }; static final int sgn_mask[] = { 0x2, 0x4, 0x8 }; int get_tns(Info info, TNS_frame_info tns_frame_info) throws IOException { int f, t, top, res, res2, compress; int s; int sp, tmp, s_mask, n_mask; TNSfilt[] tns_filt; TNSinfo tns_info; boolean short_flag = !info.islong; int tns_filt_index = 0; short_flag = (!info.islong); tns_frame_info.n_subblocks = info.nsbk; for (s = 0; s < tns_frame_info.n_subblocks; s++) { tns_info = tns_frame_info.info[s]; if ((tns_info.n_filt = (int) audio_stream.next_bits(short_flag ? 1 : 2)) == 0) continue; tns_info.coef_res = res = (int) audio_stream.next_bits(1) + 3; top = info.sfb_per_sbk[s]; tns_filt = tns_info.filt; tns_filt_index = 0; for (f = tns_info.n_filt; f > 0; f--) { tns_filt[tns_filt_index].stop_band = top; top = tns_filt[tns_filt_index].start_band = top - (int) audio_stream.next_bits(short_flag ? 4 : 6); tns_filt[tns_filt_index].order = (int) audio_stream .next_bits(short_flag ? 3 : 5); if (tns_filt[tns_filt_index].order > 0) { tns_filt[tns_filt_index].direction = (int) audio_stream .next_bits(1); compress = (int) audio_stream.next_bits(1); res2 = res - compress; s_mask = sgn_mask[res2 - 2]; n_mask = neg_mask[res2 - 2]; sp = 0; for (t = tns_filt[tns_filt_index].order; t > 0; t--) { tmp = (short) audio_stream.next_bits(res2); tns_filt[tns_filt_index].coef[sp++] = (short) (((tmp & s_mask) > 0) ? (tmp | n_mask) : tmp); } } tns_filt_index++; } } /* subblock loop */ return 1; } void get_nec_nc(Nec_Info nec_info) throws IOException { int i; // System.out.println("get_nec_nc"); nec_info.number_pulse = (int) audio_stream .next_bits(Constants.LEN_NEC_NPULSE); nec_info.pulse_start_sfb = (int) audio_stream .next_bits(Constants.LEN_NEC_ST_SFB); // System.out.println("number_pulse = " + nec_info.number_pulse); // System.out.println("pulse_start_sfb = " + nec_info.pulse_start_sfb); for (i = 0; i < nec_info.number_pulse; i++) { nec_info.pulse_offset[i] = (int) audio_stream .next_bits(Constants.LEN_NEC_POFF); nec_info.pulse_amp[i] = (int) audio_stream .next_bits(Constants.LEN_NEC_PAMP); // System.out.println("nec_info.pulse_offset[" + i + "] = " + // nec_info.pulse_offset[i]); // System.out.println("nec_info.pulse_amp[" + i + "] = " + // nec_info.pulse_amp[i]); } } void nec_nc(float[] coef, Nec_Info nec_info) { int i, k; /* use long sfb table even for short blocks! */ k = only_long_info.sbk_sfb_top[0][nec_info.pulse_start_sfb]; for (i = 0; i <= nec_info.number_pulse; i++) { k += nec_info.pulse_offset[i]; if (coef[k] > 0) { coef[k] += nec_info.pulse_amp[i]; } else { coef[k] -= nec_info.pulse_amp[i]; } } } /* * if(!getics(info, common_window, win[widx], wshape[widx].this_bk, * group[widx], max_sfb[widx], lpflag[widx], prstflag[widx], nsect, sect, * coef[i], factors[i-first], tns[i])) */ int getics(int widx, Info info, boolean common_window, byte[] win, Wnd_Shape[] wshape, byte[] group, byte[] max_sfb, int[] lpflag, int[] prstflag, byte[] sect, float[] coef, short[] factors, TNS_frame_info tns) throws IOException { int i, tot_sfb; /* * global gain */ global_gain = (int) audio_stream.next_bits(Constants.LEN_SCL_PCM); /* * if (debug[Constants.DEBUG_F]) System.out.println("global gain: " + * global_gain); */ if (!common_window) { /* * void get_ics_info(int widx, byte[] win, Wnd_Shape[] wshape, * byte[] group, byte[] max_sfb, int[] lpflag, int[] prstflag) { */ get_ics_info(widx, win, wshape, group, max_sfb, lpflag, prstflag); } info.copyFields(winmap[win[widx]]); /* calculate total number of sfb for this grouping */ if (max_sfb[widx] == 0) { tot_sfb = 0; } else { i = 0; tot_sfb = info.sfb_per_sbk[0]; /* * if (debug[Constants.DEBUG_F]) System.out.println("tot sfb " + i + * " " + tot_sfb); */ while (group[i++] < info.nsbk) { tot_sfb += info.sfb_per_sbk[0]; /* * if (debug[Constants.DEBUG_F]) System.out.println("tot sfb " + * i + " " + tot_sfb); */ } } /* * section data */ nsect = huffcb(sect, info.sectbits, tot_sfb, info.sfb_per_sbk[0], max_sfb[widx]); if ((nsect == 0) && (max_sfb[widx] > 0)) return 0; /* * calculate band offsets (because of grouping and interleaving this * cannot be a constant: store it in info.bk_sfb_top) */ calc_gsfb_table(info, group); /* * scale factor data */ if (hufffac(info, group, sect, factors) == 0) return 0; /* * NEC noiseless coding */ if (nec_info.pulse_data_present = audio_stream.next_bit()) { get_nec_nc(nec_info); } /* * tns data */ if (audio_stream.next_bit()) { get_tns(info, tns); } else { clr_tns(info, tns); } /* * Sony gain control */ if (audio_stream.next_bit()) { throw new IOException("Gain control not implmented"); } return huffspec(info, sect, factors, coef); } /* * read the codebook and boundaries */ int huffcb(byte[] sect, int[] sectbits, int tot_sfb, int sfb_per_sbk, byte max_sfb) throws IOException { int nsect, n, base, bits, len; int sect_index = 0; /* * if (debug[Constants.DEBUG_S]) { System.out.println("total sfb " + * tot_sfb); System.out.println("sect, top, cb"); } */ bits = sectbits[0]; len = (1 << bits) - 1; nsect = 0; for (base = 0; base < tot_sfb && nsect < tot_sfb;) { sect[sect_index++] = (byte) audio_stream .next_bits(Constants.LEN_CB); n = (int) audio_stream.next_bits(bits); while (n == len && base < tot_sfb) { base += len; n = (int) audio_stream.next_bits(bits); } base += n; sect[sect_index++] = (byte) base; nsect++; /* * if (debug[Constants.DEBUG_S]) System.out.println(" " + nsect + * " " + sect[sect_index - 1] + " " + sect[sect_index - 2]); */ /* insert a zero section for regions above max_sfb for each group */ if ((sect[sect_index - 1] % sfb_per_sbk) == max_sfb) { base += (sfb_per_sbk - max_sfb); sect[sect_index++] = 0; sect[sect_index++] = (byte) base; nsect++; /* * if (debug[Constants.DEBUG_S]) System.out.println("(" + nsect * + " " + sect[sect_index - 1] + " " + sect[sect_index - 2]); */ } } if (base != tot_sfb || nsect > tot_sfb) { return 0; } return nsect; } /* * get scale factors */ int hufffac(Info info, byte[] group, byte[] sect, short[] factors) throws IOException { Hcb hcb; int[][] hcw; int i, b, bb, t, n, sfb, top, fac, is_pos; int[] fac_trans = new int[Constants.MAXBANDS]; int group_idx = 0; int sect_index = 0; int factors_index = 0; int fac_trans_index = 0; /* clear array for the case of max_sfb == 0 */ for (i = 0; i < Constants.MAXBANDS; i++) { factors[i] = 0; fac_trans[i] = 0; } sfb = 0; for (i = 0; i < nsect; i++) { top = sect[sect_index + 1]; /* top of section in sfb */ t = sect[sect_index]; /* codebook for this section */ sect_index += 2; for (; sfb < top; sfb++) { fac_trans[sfb] = t; } } /* * scale factors are dpcm relative to global gain intensity positions * are dpcm relative to zero */ fac = global_gain; is_pos = 0; /* get scale factors */ hcb = huffman.book[Constants.BOOKSCL]; hcw = hcb.hcw; bb = 0; /* * if (debug[Constants.DEBUG_F]) { System.out.println("scale factors"); * } System.out.println("info.nsbk : " + info.nsbk); * System.out.println("group_idx : " + group_idx); * System.out.println("factors_index : " + factors_index); */ for (b = 0; b < info.nsbk;) { n = info.sfb_per_sbk[b]; b = group[group_idx++]; /* * System.out.println("n : " + n); System.out.println("b : " + b); */ for (i = 0; i < n; i++) { // System.out.println("fac_trans[" + fac_trans_index + i + // "] = " + fac_trans[fac_trans_index + i]); if (fac_trans[fac_trans_index + i] > 0) { /* decode intensity positions */ if ((info.nsbk == 1) && /* No short blocks yet! */ ((fac_trans[fac_trans_index + i] == Constants.INTENSITY_HCB) || (fac_trans[fac_trans_index + i] == Constants.INTENSITY_HCB2))) { System.out.println(2); /* decode intensity position */ t = huffman.decode_huff_cw(hcw); is_pos += t - Constants.MIDFAC; /* * if (debug[Constants.DEBUG_F]) { System.out.println(i * + " " + is_pos + " (is_pos)"); } */ factors[factors_index + i] = (short) is_pos; continue; } /* decode scale factor */ t = huffman.decode_huff_cw(hcw); fac += t - Constants.MIDFAC; /* 1.5 dB */ /* * if (debug[Constants.DEBUG_F]) { System.out.print(i + ":" * + fac); } */ if ((fac >= 2 * maxfac) || (fac < 0)) { return 0; } factors[factors_index + i] = (short) fac; } } /* * if (debug[Constants.DEBUG_F]) { System.out.println(); } */ /* expand short block grouping */ if (!info.islong) { for (bb++; bb < b; bb++) { for (i = 0; i < n; i++) { factors[factors_index + i + n] = factors[factors_index + i]; } factors_index += n; } } fac_trans_index += n; factors_index += n; } return 1; } /* * rm2 inverse quantization escape books need ftn call other books done via * macro */ float iquant(int q) { return (q >= 0) ? (float) huffman.iq_exp_tbl[q] : (float) (-huffman.iq_exp_tbl[-q]); } float esc_iquant(int q) { if (q > 0) { if (q < Constants.MAX_IQ_TBL) { return ((float) huffman.iq_exp_tbl[q]); } else { return (float) (Math.pow(q, 4d / 3d)); } } else { q = -q; if (q < Constants.MAX_IQ_TBL) { return ((float) (-huffman.iq_exp_tbl[q])); } else { return (float) (-Math.pow(q, 4d / 3d)); } } } int huffspec(Info info, byte[] sect, short[] factors, float[] coef) throws IOException { Hcb hcb; int[][] hcw; int i, j, k, table, step, temp, stop, bottom, top; short[] bands; int bands_index = 0; int[] quant = new int[Constants.LN2]; int[] tmp_spec = new int[Constants.LN2]; int sect_index = 0; int quant_index = 0; for (i = 0; i < Constants.LN2; i++) { quant[i] = 0; } bands = info.bk_sfb_top; bottom = 0; k = 0; for (i = nsect; i > 0; i--) { table = sect[sect_index + 0]; top = sect[sect_index + 1]; sect_index += 2; if ((table == 0) || (table == Constants.INTENSITY_HCB) || (table == Constants.INTENSITY_HCB2)) { bands_index = top; k = bands[bands_index - 1]; bottom = top; continue; } if (table < (Constants.BY4BOOKS + 1)) { step = 4; } else { step = 2; } hcb = huffman.book[table]; hcw = hcb.hcw; quant_index = k; for (j = bottom; j < top; j++) { stop = bands[bands_index++]; while (k < stop) { temp = huffman.decode_huff_cw(hcw); huffman.unpack_idx(quant, quant_index, temp, hcb); if (!hcb.signed_cb) { huffman.get_sign_bits(quant, quant_index, step); } if (table == Constants.ESCBOOK) { quant[quant_index + 0] = getescape(quant[quant_index + 0]); quant[quant_index + 1] = getescape(quant[quant_index + 1]); } quant_index += step; k += step; } /* * if(debug[Constants.DEBUG_Q]){ System.out.println("sect " + * table + " " + kstart); for (idx=kstart ;idx<k;idx++) { * System.out.print(quantDebug[idx] + " "); } * System.out.println(); } */ } bottom = top; } /* NEC noisless coding reconstruction */ if (nec_info.pulse_data_present) { nec_nc(coef, nec_info); } if (!info.islong) { deinterleave(quant, tmp_spec, info.num_groups, info.group_len, info.sfb_per_sbk, info.sfb_width_128); for (i = 0; i < tmp_spec.length; i++) { quant[i] = tmp_spec[i]; } } // System.out.print("coef: "); /* inverse quantization */ for (i = 0; i < info.bins_per_bk; i++) { coef[i] = esc_iquant(quant[i]); // System.out.print(coef[i] + " "); } // System.out.println(); /* rescaling */ { int sbk, nsbk, sfb, nsfb, fac, top_coef; float scale; int coef_index = 0; i = 0; nsbk = info.nsbk; for (sbk = 0; sbk < nsbk; sbk++) { nsfb = info.sfb_per_sbk[sbk]; k = 0; for (sfb = 0; sfb < nsfb; sfb++) { top_coef = info.sbk_sfb_top[sbk][sfb]; fac = factors[i++] - Constants.SF_OFFSET; if ((fac >= 0) && (fac < Constants.TEXP)) { scale = huffman.exptable[fac]; } else { if (fac == -Constants.SF_OFFSET) { scale = 0; } else { scale = (float) Math.pow(2.0, 0.25 * fac); } } for (; k < top_coef; k++) { coef[coef_index++] *= scale; } } } } return 1; } /** checked */ int getescape(int q) throws IOException { int i, off, neg; if (q < 0) { if (q != -16) return q; neg = 1; } else { if (q != +16) return q; neg = 0; } for (i = 4;; i++) { if (!audio_stream.next_bit()) break; } if (i > 16) { off = (int) audio_stream.next_bits(i - 16) << 16; off |= audio_stream.next_bits(16); } else { off = (int) audio_stream.next_bits(i); } i = off + (1 << i); if (neg > 0) { i = -i; } return i; } /* original source intensity.c */ /** * if (chan==RIGHT) { do IS decoding for this channel (scale left ch. values * with factor(SFr-SFl) ) reset all lpflags for which IS is on pass decoded * IS values to predict } */ void intensity(MC_Info mip, Info info, int widx, int[] lpflag, int ch, float[][] coef) { int left, right, i, k, nsect, sign, bot, top, sfb, ktop; float scale; Ch_Info cip = mip.ch_info[ch]; IS_Info iip = mip.ch_info[ch].is_info; if (!(cip.cpe && iip.is_present && !cip.ch_is_left)) { return; } left = cip.paired_ch; right = ch; nsect = iip.n_is_sect; for (i = 0; i < nsect; i++) { sign = iip.sign[i]; top = iip.top[i]; bot = iip.bot[i]; for (sfb = bot; sfb < top; sfb++) { /* disable prediction */ lpflag[1 + sfb] = 0; scale = (float) (sign * Math.pow(0.5, 0.25 * (iip.fac[sfb]))); /* reconstruct right intensity values */ /* * if (debug[Constants.DEBUG_I]) { * System.out.println("applying IS coding of " + scale + * " on ch " + ch + " at sfb " + sfb); } */ k = (sfb == 0) ? 0 : info.bk_sfb_top[sfb - 1]; ktop = info.bk_sfb_top[sfb]; for (; k < ktop; k++) { coef[right][k] = coef[left][k] * scale; } } } } /* original source stereo.c */ void synt(Info info, byte[] group, byte[] mask, float[] right, float[] left) { float vrr, vrl; short[] band; int i, n, nn, b, bb, nband; int group_index = 0; int right_index = 0; int left_index = 0; int mask_index = 0; /* mask is grouped */ bb = 0; for (b = 0; b < info.nsbk;) { nband = info.sfb_per_sbk[b]; band = info.sbk_sfb_top[b]; b = group[group_index++]; /* b = index of last sbk in group */ for (; bb < b; bb++) { /* bb = sbk index */ n = 0; for (i = 0; i < nband; i++) { nn = band[i]; /* band is offset table, nn is last coef in band */ if (mask[mask_index + i] > 0) { for (; n < nn; n++) { /* n is coef index */ vrr = right[right_index + n]; vrl = left[left_index + n]; left[left_index + n] = vrr + vrl; right[right_index + n] = vrl - vrr; } } n = nn; } right_index += info.bins_per_sbk[bb]; left_index += info.bins_per_sbk[bb]; } mask_index += info.sfb_per_sbk[bb - 1]; } } // byte[] AU_ptr; // long AU_idx; // long AU_len; void init() throws IOException { // if(!Constants.DOLBY_MDCT) { // imdctinit(); // } predinit(); // restarttio(); winmap[0] = win_seq_info[Constants.ONLY_LONG_WINDOW]; winmap[1] = win_seq_info[Constants.ONLY_LONG_WINDOW]; winmap[2] = win_seq_info[Constants.EIGHT_SHORT_WINDOW]; winmap[3] = win_seq_info[Constants.ONLY_LONG_WINDOW]; } void predinit() throws IOException { int i, ch; for (ch = 0; ch < Constants.Chans; ch++) { for (i = 0; i < Constants.LN2; i++) { Monopred.init_pred_stat(sp_status[ch][i], Constants.PRED_ORDER, Constants.PRED_ALPHA, Constants.PRED_A, Constants.PRED_B); prev_quant[ch][i] = 0; } } } int getdata(byte[] data_bytes) throws IOException { boolean byte_align_flag; int d_cnt; audio_stream.next_bits(Constants.LEN_TAG); byte_align_flag = audio_stream.next_bit(); if ((d_cnt = (int) audio_stream.next_bits(8)) == (1 << 8) - 1) { d_cnt += (int) audio_stream.next_bits(8); } if (byte_align_flag) { audio_stream.byteAlign(); } for (int i = 0; i < d_cnt; i++) { data_bytes[i] = (byte) audio_stream.next_bits(Constants.LEN_BYTE); } return 0; } /* * int getdata(int *tag, int *dt_cnt, byte *data_bytes) { int i, cnt; * * tag = getbits(LEN_TAG); if ((cnt = getbits(LEN_D_CNT)) == * (1<<LEN_D_CNT)-1) cnt += getbits(LEN_D_ESC);dt_cnt = cnt; if (debug['x']) * PRINT(SE, "data element %d has %d bytes\n", *tag, cnt); * * for (i=0; i<cnt; i++) data_bytes[i] = getbits(LEN_BYTE); * * return 0; } */ void getfill() throws IOException { int i, cnt; if ((cnt = (int) audio_stream.next_bits(Constants.LEN_F_CNT)) == (1 << Constants.LEN_F_CNT) - 1) { cnt += (int) audio_stream.next_bits(Constants.LEN_F_ESC) - 1; } /* * if (debug[Constants.DEBUG_X]) { System.out.print("fill element has " * + cnt + " bytes"); } */ for (i = 0; i < cnt; i++) { audio_stream.next_bits(Constants.LEN_BYTE); } } /* * public static void main(String[] argv) { * * try { BitStream audio_stream = new BitStream(new * FileInputStream(argv[0])); AACDecoder decoder = new * AACDecoder(audio_stream); decoder.initio(argv); // parse command line * decoder.init(); // initialize data structures } catch (Exception ex) { * ex.printStackTrace(); } } */ public int decodeFrame(byte[] buf) throws IOException { int i, j, ch, wn, ele_id; int left, right; Info info; MC_Info mip = mc_info; Ch_Info cip; /* * AU_ptr = AUptr; AU_idx = 0; AU_len = AUlen; */ /* PRINT( SE, "\n==== AU_len = %d\n", AU_len ); */ /* * if(debug[Constants.DEBUG_N]) { System.out.print("\rblock " + bno); } */ /* call transport layer */ if (startblock() < 0) return -1; // myexit(0); config.reset_mc_info(mip); while ((ele_id = (int) audio_stream.next_bits(Constants.LEN_SE_ID)) != Constants.ID_END) { /* get audio syntactic element */ /* * if(debug[Constants.DEBUG_V]) System.out.println("\nele_id " + * ele_id); */ switch (ele_id) { case Constants.ID_SCE: /* single channel */ case Constants.ID_CPE: /* channel pair */ case Constants.ID_LFE: /* low freq effects channel */ int result_code = huffdecode(ele_id, mip, wnd, wnd_shape, group, hasmask, mask, max_sfb, lpflag, prstflag, tns_frame_info, coef); if (result_code < 0) throw new IOException("huffdecode returned " + result_code); break; case Constants.ID_DSE: /* data element */ if (getdata(d_bytes) < 0) throw new IOException("data channel"); break; case Constants.ID_PCE: /* program config element */ // skip config element // config.get_prog_config(prog_config); break; case Constants.ID_FIL: /* fill element */ getfill(); break; case Constants.ID_CCE: /* coupling channel */ /* * if(Constants.CChans > 0) { if (getcc(mip, cc_wnd, * cc_wnd_shape, cc_coef, cc_gain) < 0) throw new * IOException("getcc"); break; } */ System.out.println("Coupling channels isn't supported!"); break; default: System.out.println("Element not supported: " + ele_id); break; } } config.check_mc_info(mip, (bno == 0 && default_config)); /* * // call transport layer if(endblock() < 0) { throw new * IOException("endblock"); } */ // if(Constants.ICChans > 0) { /* transform independently switched coupling channels */ // ind_coupling(mip, wnd, wnd_shape, cc_wnd, cc_wnd_shape, cc_coef); // } /* m/s stereo */ for (ch = 0; ch < Constants.Chans; ch++) { cip = mip.ch_info[ch]; if ((cip.present) && (cip.cpe) && (cip.ch_is_left)) { wn = cip.widx; if (hasmask[wn] > 0) { left = ch; right = cip.paired_ch; info = winmap[wnd[wn]]; synt(info, group[wn], mask[wn], coef[right], coef[left]); } } } /* intensity stereo and prediction */ for (ch = 0; ch < Constants.Chans; ch++) { if (!(mip.ch_info[ch].present)) continue; wn = mip.ch_info[ch].widx; info = winmap[wnd[wn]]; intensity(mip, info, wn, lpflag[wn], ch, coef); Monopred.predict(info, mip.profile, lpflag[wn], sp_status[ch], prev_quant[ch], coef[ch]); } for (ch = 0; ch < Constants.Chans; ch++) { if (!(mip.ch_info[ch].present)) { continue; } wn = mip.ch_info[ch].widx; info = winmap[wnd[wn]]; /* predictor reset */ left = ch; right = left; if ((mip.ch_info[ch].cpe) && (mip.ch_info[ch].common_window)) /* prstflag's shared by channel pair */ right = mip.ch_info[ch].paired_ch; Monopred.predict_reset(info, prstflag[wn], sp_status, prev_quant, left, right); // if(Constants.CChans > 0) { /* if cc_domain indicates before TNS */ // coupling(mip, coef, cc_coef, cc_gain, ch, Constants.CC_DOM, // Constants.CC_IND == 0); // } /* tns */ for (i = j = 0; i < tns_frame_info[ch].n_subblocks; i++) { /* * if (debug[Constants.DEBUG_T]) { System.out.println(bno + " " * + ch + " " + i); tns.print_tns( tns_frame_info[ch].info[i]); * } */ // @TODO check the following code tns.tns_decode_subblock(coef[ch], j, info.sfb_per_sbk[i], info.sbk_sfb_top[i], info.islong, tns_frame_info[ch].info[i]); j += info.bins_per_sbk[i]; } // if(Constants.CChans > 0) { /* if cc_domain indicated after TNS */ // coupling(mip, coef, cc_coef, cc_gain, ch, Constants.CC_DOM, // Constants.CC_IND == 0); // } if (Constants.DOLBY_MDCT) { /* inverse transform */ dolby_Adapt.freq2time_adapt(wnd[wn], wnd_shape[wn], coef[ch], state[ch], data[ch]); // } else { // imdct(wnd[wn], wnd_shape[wn].this_bk, coef[ch], state[ch], // data[ch]); // /* scale imdct output */ // float scale = (float)(1 / Math.sqrt (2)); // for (i = 0; i < Constants.LN2; i++) { // data[ch][i] *= scale; // } } /* * System.out.print("coef[" + ch + "] = "); for(i = 0; i < 10; i++) * { System.out.print(coef[ch][i] + " "); } System.out.println(); * * System.out.print("state[" + ch + "] = "); for(i = 0; i < 10; i++) * { System.out.print(state[ch][i] + " "); } System.out.println(); * System.out.print("data[" + ch + "] = "); for(i = 0; i < 10; i++) * { System.out.print(data[ch][i] + " "); } System.out.println(); */ // if(Constants.CChans > 0) { /* independently switched coupling */ // coupling(mip, coef, cc_coef, cc_gain, ch, Constants.CC_DOM, // Constants.CC_IND); // } } /* skip first two blocks so output is time aligned with input */ if (bno > 1) { writeout(data, mip, buf); } bno++; return bno > 2 ? (2048 * mc_info.nch) : 0; } void writeout(float[][] data, MC_Info mip, byte[] obuf) { int i, p_index = 0; for (i = 0; i < Constants.Chans; i++) { if (!(mip.ch_info[i].present)) continue; fmtchan(obuf, p_index, data[i], 2 * mc_info.nch); p_index += 2; } } void fmtchan(byte[] p, int p_index, float[] data, int stride) { int i, c, data_index = 0; float s; for (i = 0; i < Constants.LN2; i++) { s = data[data_index++]; if (s < 0) { s -= .5; if (s < -0x7fff) s = (float) -0x7fff; } else { s += .5; if (s > 0x7fff) s = (float) 0x7fff; } c = (int) s; p[p_index + 1] = (byte) ((c >> 8) & 0xff); p[p_index + 0] = (byte) (c & 0xff); p_index += stride; } } private boolean adif_header_present = false; int startblock() throws IOException { /* get adif header */ if (adif_header_present) { if (config.get_adif_header() < 0) return -1; adif_header_present = false; } audio_stream.byteAlign(); /* start of block is byte aligned */ // audio_stream.print_next_bits(48); return 1; } /* * // source portio.c void initio(String[] argv) throws IOException { int i, * j; * * // set defaults adif_header_present = false; current_program = -1; * default_config = true; mc_info.profile = Constants.Main_Profile; * mc_info.sampling_rate_idx = Constants.Fs_48; * * // save cmd // ARGBEGIN is so clever that it throws away argv[0] and // * increments the argv pointer // * * // // if(argv.length != 2) { // usage(cmd); // } // for(i = 0; i < * argv.length; i++,i++) { if(argv[i].length() > 1) { usage(); throw new * IOException("unknown option"); } switch(argv[i].charAt(0)) { case 'i': * adif_header_present = true; current_program = (argv[i + 1] == null) ? -1 * : Integer.parseInt(argv[i + 1]); if (current_program > * ((1<<Constants.LEN_NUM_PCE)-1)) { throw new * IOException("Invalid program: " + current_program); } break; case 'p': if * ("Main".equalsIgnoreCase(argv[i + 1])) { mc_info.profile = * Constants.Main_Profile; break; } if ("LC".equalsIgnoreCase(argv[i + 1])) * { mc_info.profile = Constants.LC_Profile; break; } throw new * IOException("Unsupported profile " + argv[i + 1]); case 's': j = * Integer.parseInt(argv[i + 1]); for (i=0; i<(1<<Constants.LEN_SAMP_IDX); * i++) { if (j == Tables.samp_rate_info[i].samp_rate) break; } if (i == * (1<<Constants.LEN_SAMP_IDX)) { throw new * IOException("Unsupported sampling frequency " + j); } * mc_info.sampling_rate_idx = i; break; case 'D': String options = argv[i + * 1]; for(j = 0; j < options.length(); j++) { char debug_option = * options.charAt(j); for(int z = 0; z < Constants.debug_options.length; * z++) { if(Constants.debug_options[z] == debug_option) { debug[z] = true; * break; } } } * * break; * * default: usage(); throw new IOException("unknown option"); } } } * * void usage() { System.out.println("usage: [options] chan_file pcm_file"); * System.out.println(" options are:"); * System.out.println(" -a create AIFF output files"); System.out.println( * " -i [prog_tag] ADIF header present (first prog is default)"); * System.out.println(" -p profile (Main or LC, Main is default)"); * System.out.println(" -s sampling_frequency, Hz (48 kHz is default)"); * System.out.println(" -D[a-Z] (enable debugging printouts)"); } */ /* * long f2ir(float x) { if(x >= 0) { return (long) (x+.5); } return * -(long)(-x + .5); } * * void fltcpy(float[] dp1, float[] dp2, int cnt) { for(int i = 0;i < cnt; * i++) { dp2[i] = dp1[i]; } } * * void fltset(float[] dp1, float dval, int cnt) { for(int i = 0; i < cnt; * i++) { dp1[i] = dval; } } * * void fltclr(float[] dp1, int cnt) { for(int i = 0; i < cnt; i++) { dp1[i] * = 0; } } * * void intcpy(int[] ip1, int[] ip2, int cnt) { for(int i = 0;i < cnt; i++) * { ip2[i] = ip1[i]; } } * * void intclr(int[] ip1, int cnt) { for(int i = 0; i < cnt; i++) { ip1[i] = * 0; } } * * void byteclr(byte[] ip1, int cnt) { for(int i = 0; i < cnt; i++) { ip1[i] * = 0; } } */ public Huffman getHuffman() { return huffman; } public BitStream getAudio_Stream() { return audio_stream; } public Config getConfig() { return config; } public int getSampleFrequency() { return mc_info.sampling_rate; } public int getChannelCount() { return mc_info.nch; } public String getAudioProfile() { switch (prog_config.profile) { case Constants.Main_Profile: return "Main Profile"; case Constants.LC_Profile: return "LC Profile"; case Constants.SRS_Profile: return "SRC Profile"; default: return "Unknown Profile"; } } }