shithub: aacenc

Download patch

ref: c4109ff50138fc5660db39fd2bd455ca5c58c065
author: lenox <lenox>
date: Mon Dec 13 04:01:36 EST 1999

no message

--- /dev/null
+++ b/COPYING
@@ -1,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+++ b/Makefile
@@ -1,0 +1,19 @@
+SOURCE=aac_back_pred.c aac_qc.c aac_se_enc.c bitstream.c enc_tf.c encoder.c imdct.c is.c mc_enc.c ms.c psych.c pulse.c tns.c transfo.c util.c
+
+
+OBJ = $(SOURCE:.c=.o)
+
+CC_OPTS=-g -DHAS_ULONG -O3
+
+TARGETS=faac
+
+%.o: %.c
+	$(CC) $(CC_OPTS) -c $< -o $@	
+
+faac: $(OBJ) Makefile
+	gcc -o faac $(OBJ) -lsndfile -lm
+
+all: $(TARGETS)
+
+clean:
+	rm *.o $(TARGETS)
\ No newline at end of file
--- /dev/null
+++ b/aac_back_pred.c
@@ -1,0 +1,295 @@
+/**********************************************************************
+
+This software module was originally developed by
+and edited by Nokia 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) 1997.
+**********************************************************************/
+/*********************************************************************
+ *
+ * aac_back_pred.c  -  AAC backward prediction subroutine
+ *
+ * Authors:
+ * LY    Lin Yin, Nokia Research Center
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * ADD   Alberto Duenas, NDS <alberto@ndsuk.com)
+ * JB    Jeremy Bennett, NDS <jbennett@ndsuk.com>
+ *
+ * Changes:
+ * 07-jun-97   LY   Initial revision.
+ * 14-sep-97   CL   Made predicted samples array, sb_samples_pred, static.
+ *                  Modified line 98 to add these predicted values to
+ *                  the last spectrum prior to analysis.
+ * 03-dec-97   ADD & JB   Added prediction reset.
+ *
+**********************************************************************/
+
+/**********************************************************************
+
+INPUT:
+act_spec[]: the current frame's spectral components to be encoded.
+last_spec[]: the previous frame's quantized spectral error components 
+btype: the current frame's window type
+nsfb: the number of scalefactor bands
+isfb_width[]: scalefactor bandwidth
+
+OUTPUT:
+act_spec[]: the current frame's spectral error components to be encoded
+pred_global_flag: global prediction enable/disable flag
+pred_sbf_glag[]: enable/disable flag for each scalefactor band
+reset_group: number for the reset group => if -1, then no reset
+***********************************************************************/
+
+#include "aac_back_pred.h"
+
+
+static int psy_init_mc[MAX_TIME_CHANNELS];
+static double dr_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2],e_mc[MAX_TIME_CHANNELS][LPC+1+1][FLEN_LONG/2];
+static double K_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2], R_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2];
+static double VAR_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2], KOR_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2];
+static double sb_samples_pred_mc[MAX_TIME_CHANNELS][FLEN_LONG/2];
+static int thisLineNeedsResetting_mc[MAX_TIME_CHANNELS][FLEN_LONG/2];
+static int reset_count_mc[MAX_TIME_CHANNELS];
+
+void PredInit()
+{
+	int i;
+	for (i=0;i<MAX_TIME_CHANNELS;i++) {
+		psy_init_mc[i] = 0;
+		reset_count_mc[i] = 0;
+	}
+}
+ 
+void PredCalcPrediction( double *act_spec, double *last_spec, int btype, 
+						int nsfb, int *isfb_width, short *pred_global_flag, 
+						int *pred_sfb_flag, int *reset_group ,
+						int chanNum) 
+{
+	int i, k, j, cb_long;
+	double num_bit, snr[SBMAX_L];
+	double energy[FLEN_LONG/2], snr_p[FLEN_LONG/2], temp1, temp2;
+
+	/* Set pointers for specified channel number */
+	/* int psy_init; */
+	int *psy_init;
+	double (*dr)[FLEN_LONG/2],(*e)[FLEN_LONG/2];
+	double (*K)[FLEN_LONG/2], (*R)[FLEN_LONG/2];
+	double (*VAR)[FLEN_LONG/2], (*KOR)[FLEN_LONG/2];
+	double *sb_samples_pred;
+	int *thisLineNeedsResetting;
+	/* int reset_count; */
+	int *reset_count;
+
+	/* psy_init = psy_init_mc[chanNum]; */
+	psy_init = &psy_init_mc[chanNum];
+	dr = &dr_mc[chanNum][0];
+	e = &e_mc[chanNum][0];
+	K = &K_mc[chanNum][0]; 
+	R = &R_mc[chanNum][0];
+	VAR = &VAR_mc[chanNum][0];
+	KOR = &KOR_mc[chanNum][0];
+	sb_samples_pred = &sb_samples_pred_mc[chanNum][0];
+	thisLineNeedsResetting = &thisLineNeedsResetting_mc[chanNum][0];
+	reset_count = &reset_count_mc[chanNum];
+
+	*psy_init = (*psy_init && (btype!=2));
+
+	if((*psy_init) == 0) {
+		for (j=0; j<FLEN_LONG/2; j++) {
+			thisLineNeedsResetting[j]=1;
+		}
+		*psy_init = 1;
+	}
+
+	if (btype==2) {
+		pred_global_flag[0]=0;
+
+		/* As SHORT WINDOWS reset all the co-efficients, the count
+		* must also be reset.
+		*/
+		*reset_count = ((*reset_count) / RESET_FRAME) * RESET_FRAME;
+		return;
+	}
+
+
+
+	/**************************************************/
+	/*  Compute state using last_spec                 */
+	/**************************************************/
+	for (i=0;i<FLEN_LONG/2;i++) 
+    {
+		/* e[0][i]=last_spec[i]; */ 
+		e[0][i]=last_spec[i]+sb_samples_pred[i];
+		
+		for(j=1;j<=LPC;j++)
+			e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];
+		
+		for(j=1;j<LPC;j++) 
+			dr[j][i] = K[j][i]*e[j-1][i];
+		
+		for(j=1;j<=LPC;j++) {
+			VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);
+			KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];
+		}
+
+		for(j=LPC-1;j>=1;j--) 
+			R[j][i] = A*(R[j-1][i]-dr[j][i]);
+		R[0][i] = A*e[0][i];
+    }
+
+
+	/**************************************************/
+	/* Reset state here if resets were sent           */
+	/**************************************************/
+	for (i=0;i<FLEN_LONG/2;i++) {
+		if (thisLineNeedsResetting[i]) {
+			for (j = 0; j <= LPC; j++)
+			{
+				K[j][i] = 0.0;
+				dr[j][i] = 0.0;
+				e[j][i] = 0.0;
+				R[j][i] = 0.0;
+				VAR[j][i] = 1.0;
+				KOR[j][i] = 0.0;
+			}
+		}
+	}
+
+
+	/**************************************************/
+	/* Compute predictor coefficients, predicted data */
+	/**************************************************/
+	for (i=0;i<FLEN_LONG/2;i++) 
+    {
+		for(j=1;j<=LPC;j++) {
+			if(VAR[j][i]>MINVAR)
+				K[j][i] = KOR[j][i]/VAR[j][i]*B;
+			else
+				K[j][i] = 0;
+		}
+    }
+
+
+	for (k=0; k<FLEN_LONG/2; k++)
+    {
+		sb_samples_pred[k]=0.0;
+		for (i=1; i<=LPC; i++)
+			sb_samples_pred[k]+=K[i][k]*R[i-1][k];
+    }
+
+
+
+	/**************************************************/
+	/* Determine whether to enable/disable prediction */
+	/**************************************************/
+
+	for (k=0; k<FLEN_LONG/2; k++)
+    {
+		energy[k]=act_spec[k]*act_spec[k];
+		snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);
+	}
+	
+	cb_long=0;
+	for (i=0; i<nsfb; i++)
+    {
+		pred_sfb_flag[i]=1;
+		temp1=0.0;
+		temp2=0.0;
+		for (j=cb_long; j<cb_long+isfb_width[i]; j++)
+		{
+			temp1+=energy[j];
+			temp2+=snr_p[j];
+		}
+		if(temp2<1.e-20)
+			temp2=1.e-20;
+		if(temp1!=0.0) {
+			snr[i]=-10.*log10((double ) temp2/temp1);
+		} else
+			snr[i]=0.0;
+		if(snr[i]<=0.0) {
+			pred_sfb_flag[i]=0; 
+			for (j=cb_long; j<cb_long+isfb_width[i]; j++)
+				sb_samples_pred[j]=0.0;
+		}
+		cb_long+=isfb_width[i];
+    }
+
+	/* Disable prediction for bands nsfb through SBMAX_L */ 
+	for (i=cb_long;i<FLEN_LONG/2;i++) {
+		sb_samples_pred[i]=0.0;
+	}
+	for (i=nsfb;i<SBMAX_L;i++) {
+		pred_sfb_flag[i]=0;
+	}
+
+	num_bit=0.0;
+	for (i=0; i<nsfb; i++)
+		if(snr[i]>0.0)
+			num_bit+=snr[i]/6.*isfb_width[i];	
+
+	pred_global_flag[0]=1;
+	if(num_bit < 50) {
+		pred_global_flag[0]=0; num_bit=0.0; 
+		for (j=0; j<FLEN_LONG/2; j++)
+			sb_samples_pred[j]=0.0; 
+	}
+	for (j=0; j<FLEN_LONG/2; j++)
+		act_spec[j]-=sb_samples_pred[j];
+
+	/* Code segment added by JB */
+
+	/* Determine whether a prediction reset is required - if so, then
+	* set reset flag for the appropriate group.
+	*/
+	(*reset_count)++;
+	/* Reset the frame counter */
+	for (i=0;i<FLEN_LONG/2;i++) {
+		thisLineNeedsResetting[i]=0;
+	}
+	if (*reset_count >= 31 * RESET_FRAME)
+		*reset_count = RESET_FRAME;
+	if (*reset_count % RESET_FRAME == 0)
+	{ /* Send a reset in this frame */
+		*reset_group = *reset_count / 8;
+
+		for (i = *reset_group - 1; i < FLEN_LONG / 2; i += 30)
+		{
+			thisLineNeedsResetting[i]=1;
+		}
+	}
+	else
+		*reset_group = -1;
+	/* End of code segment */
+
+
+	/* Code segment added by JB */
+
+	/* Ensure that prediction data is sent when there is a prediction
+	* reset.
+	*/
+	if (*reset_group != -1 && pred_global_flag[0] == 0)
+	{
+		pred_global_flag[0] = 1;
+		for (i = 0; i < nsfb; i++)
+			pred_sfb_flag[i] = 0;
+	}
+	/* End of code segment */
+}
--- /dev/null
+++ b/aac_back_pred.h
@@ -1,0 +1,74 @@
+/**********************************************************************
+
+This software module was originally developed by
+and edited by Nokia 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) 1997.
+**********************************************************************/
+/*********************************************************************
+ *
+ * aac_back_pred.c  -  AAC backward prediction subroutine
+ *
+ * Authors:
+ * LY    Lin Yin, Nokia Research Center
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * ADD   Alberto Duenas, NDS <alberto@ndsuk.com>
+ * JB    Jeremy Bennett, NDS <jbennett@ndsuk.com>
+ *
+ * Changes:
+ * 07-jun-97   LY   Initial revision.
+ * 14-sep-97   CL   Updated ALPHA, A, and B coefficients.
+ * 03-dec-97   ADD & JB   Added prediction reset.
+ *
+**********************************************************************/
+
+#ifndef _AAC_BACK_H_INCLUDED
+#define _AAC_BACK_H_INCLUDED
+
+#include <math.h>
+#include "interface.h"
+#include "all.h"
+
+#define         FLEN_LONG              2048
+#define         SBMAX_L                49
+#define         LPC                    2
+#define         ALPHA                  PRED_ALPHA
+#define         A                      PRED_A
+#define         B                      PRED_B
+#define         MINVAR                 1.e-10
+
+/* Reset every RESET_FRAME frames. */
+#define		RESET_FRAME 8
+ 
+void PredCalcPrediction( double *act_spec, 
+			 double *last_spec, 
+			 int btype, 
+			 int nsfb, 
+			 int *isfb_width, 
+			 short *pred_global_flag, 
+			 int *pred_sfb_flag,
+			 int *reset_group,
+			 int chanNum); 
+
+void PredInit();
+
+#endif
+
--- /dev/null
+++ b/aac_qc.c
@@ -1,0 +1,1480 @@
+
+
+#include "aacenc.h" 
+#include "bitstream.h"
+#include "tf_main.h"
+#include "pulse.h"
+#include "aac_qc.h"
+#include "aac_se_enc.h"
+#include <math.h>
+
+#include "hufftab5.h"
+
+
+double pow_quant[9000];
+double adj_quant[9000];
+int sign[1024];
+int g_Count;
+int old_startsf;
+
+double ATH[SFB_NUM_MAX];
+
+double ATHformula(double f)
+{
+	double ath;
+	f  = max(0.02, f);
+	/* from Painter & Spanias, 1997 */
+	/* minimum: (i=77) 3.3kHz = -5db */
+	ath=(3.640 * pow(f,-0.8)
+		-  6.500 * exp(-0.6*pow(f-3.3,2.0))
+		+  0.001 * pow(f,4.0));
+	
+	/* convert to energy */
+	ath -= 114;    /* MDCT scaling.  From tests by macik and MUS420 code */
+	ath = pow( 10.0, ath/10.0 );
+	return ath;
+}
+ 
+
+void compute_ath(AACQuantInfo *quantInfo, double ATH[SFB_NUM_MAX])
+{
+	int sfb,i,start,end;
+	double ATH_f;
+	double samp_freq = 44.1;
+
+	/* last sfb is not used */
+	for ( sfb = 0; sfb < quantInfo->nr_of_sfb; sfb++ ) {
+		start = quantInfo->sfb_offset[sfb];
+		end   = quantInfo->sfb_offset[sfb+1];
+		ATH[sfb]=1e99;
+		for (i=start ; i < end; i++) {
+//			if (quantInfo->block_type==ONLY_SHORT_WINDOW)
+//				ATH_f = ATHformula(samp_freq*i/(2*128)); /* freq in kHz */
+//			else
+				ATH_f = ATHformula(samp_freq*i/(2*1024)); /* freq in kHz */
+			ATH[sfb]=min(ATH[sfb],ATH_f);
+		}
+	}
+}
+
+
+void tf_init_encode_spectrum_aac( int quality )
+{
+	int i;
+
+	g_Count = quality;
+	old_startsf = 0;
+
+	for (i=0;i<9000;i++){
+		pow_quant[i]=pow(i, ((double)4.0/(double)3.0));
+	}
+	for (i=0;i<8999;i++){
+		adj_quant[i] = (i + 1) - pow(0.5 * (pow_quant[i] + pow_quant[i + 1]), 0.75);
+	}
+}
+
+#if 0
+int quantize(AACQuantInfo *quantInfo,
+			 double *p_spectrum,
+			 double *pow_spectrum,
+			 int quant[NUM_COEFF]
+			 )
+{
+	int i, sb;
+	double quantFac;
+
+	for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+
+		quantFac = pow(2.0, 0.1875*(quantInfo->scale_factor[sb] -
+			quantInfo->common_scalefac ));
+
+		for (i = quantInfo->sfb_offset[sb]; i < quantInfo->sfb_offset[sb+1]; i++){
+			quant[i] = (int)(pow_spectrum[i] * quantFac + MAGIC_NUMBER);
+
+			if (quant[i] > MAX_QUANT) {
+				return 1;
+			}
+			quant[i] = sgn(p_spectrum[i]) * quant[i];  /* restore the original sign */
+		}
+	}
+
+	if (quantInfo->block_type==ONLY_SHORT_WINDOW)
+		quantInfo->pulseInfo.pulse_data_present = 0;
+	else
+		PulseCoder(quantInfo, quant);
+
+	return 0;
+}
+#else
+
+int quantize(AACQuantInfo *quantInfo,
+			 double *p_spectrum,
+			 double *pow_spectrum,
+			 int quant[NUM_COEFF]
+			 )
+{
+	int i, sb;
+	double quantFac;
+	double x;
+
+	for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+
+		quantFac = pow(2.0, 0.1875*(quantInfo->scale_factor[sb] -
+			quantInfo->common_scalefac ));
+
+		for (i = quantInfo->sfb_offset[sb]; i < quantInfo->sfb_offset[sb+1]; i++){
+			x = pow_spectrum[i] * quantFac;
+			if (x > MAX_QUANT) {
+				return 1;
+			}
+			quant[i] = (int)(x + adj_quant[(int)x]);
+			quant[i] = sgn(p_spectrum[i]) * quant[i];  /* restore the original sign */
+		}
+	}
+
+	if (quantInfo->block_type==ONLY_SHORT_WINDOW)
+		quantInfo->pulseInfo.pulse_data_present = 0;
+	else
+		PulseCoder(quantInfo, quant);
+
+	return 0;
+}
+#endif
+
+int calc_noise(AACQuantInfo *quantInfo,
+				double *p_spectrum,
+				int quant[NUM_COEFF],
+				double requant[NUM_COEFF],
+				double error_energy[SFB_NUM_MAX],
+				double allowed_dist[SFB_NUM_MAX],
+				double *over_noise,
+				double *tot_noise,
+				double *max_noise
+				)
+{
+	int i, sb, sbw;
+	int over = 0, count = 0;
+	double invQuantFac;
+	double linediff;
+
+	*over_noise = 0.0;
+	*tot_noise = 0.0;
+	*max_noise = -999.0;
+
+	if (quantInfo->block_type!=ONLY_SHORT_WINDOW)
+		PulseDecoder(quantInfo, quant);
+
+	for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+
+		double max_sb_noise = 0.0;
+
+		sbw = quantInfo->sfb_offset[sb+1] - quantInfo->sfb_offset[sb];
+
+		invQuantFac = pow(2.0,-0.25 * (quantInfo->scale_factor[sb] - quantInfo->common_scalefac ));
+
+		error_energy[sb] = 0.0;
+
+		for (i = quantInfo->sfb_offset[sb]; i < quantInfo->sfb_offset[sb+1]; i++){
+			requant[i] =  pow_quant[ABS(quant[i])] * invQuantFac; 
+
+			/* measure the distortion in each scalefactor band */
+			linediff = (double)(ABS(p_spectrum[i]) - ABS(requant[i]));
+			linediff *= linediff;
+			error_energy[sb] += linediff;
+			max_sb_noise = max(max_sb_noise, linediff);
+		}
+		error_energy[sb] = error_energy[sb] / sbw;		
+		
+		if( (max_sb_noise > 0) && (error_energy[sb] < 1e-7 ) ) {
+			double diff = max_sb_noise-error_energy[sb];
+			double fac  = pow(diff/max_sb_noise,4);
+			error_energy[sb] += diff*fac;
+		}
+		error_energy[sb] = 10*log10(max(0.001,error_energy[sb] / allowed_dist[sb]));
+		if (error_energy[sb] > 0) {
+			over++;
+			*over_noise += error_energy[sb];
+		}
+		*tot_noise += error_energy[sb];
+		*max_noise = max(*max_noise, error_energy[sb]);
+		count++;
+  	}
+
+	if (count>1) *tot_noise /= count;
+	if (over>1) *over_noise /= over;
+	return over;
+}
+
+int quant_compare(int best_over, double best_tot_noise, double best_over_noise,
+				  double best_max_noise, int over, double tot_noise, double over_noise,
+				  double max_noise)
+{
+	/*
+	noise is given in decibals (db) relative to masking thesholds.
+
+	over_noise:  sum of quantization noise > masking
+	tot_noise:   sum of all quantization noise
+	max_noise:   max quantization noise 
+
+	*/
+	int better=0;
+
+#if 0
+	better = ((over < best_over) ||
+			((over==best_over) && (over_noise<best_over_noise)) ) ;
+#else
+#if 0
+	better = max_noise < best_max_noise;
+#else
+#if 0
+	better = tot_noise < best_tot_noise;
+#else
+#if 0
+	better = (tot_noise < best_tot_noise) &&
+		(max_noise < best_max_noise + 2);
+#else
+#if 0
+	better = ( ( (0>=max_noise) && (best_max_noise>2)) ||
+		( (0>=max_noise) && (best_max_noise<0) && ((best_max_noise+2)>max_noise) && (tot_noise<best_tot_noise) ) ||
+		( (0>=max_noise) && (best_max_noise>0) && ((best_max_noise+2)>max_noise) && (tot_noise<(best_tot_noise+best_over_noise)) ) ||
+		( (0<max_noise) && (best_max_noise>-0.5) && ((best_max_noise+1)>max_noise) && ((tot_noise+over_noise)<(best_tot_noise+best_over_noise)) ) ||
+		( (0<max_noise) && (best_max_noise>-1) && ((best_max_noise+1.5)>max_noise) && ((tot_noise+over_noise+over_noise)<(best_tot_noise+best_over_noise+best_over_noise)) ) );
+#else
+#if 1
+	better =   (over_noise <  best_over_noise)
+		|| ((over_noise == best_over_noise)&&(tot_noise < best_tot_noise));
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+	return better;
+}
+
+
+int count_bits(AACQuantInfo* quantInfo,
+			   int quant[NUM_COEFF],
+			   int output_book_vector[SFB_NUM_MAX*2])
+{
+	int i, bits = 0;
+
+	/* find a good method to section the scalefactor bands into huffman codebook sections */
+	bit_search(quant,              /* Quantized spectral values */
+		quantInfo);         /* Quantization information */
+
+	/* calculate the amount of bits needed for encoding the huffman codebook numbers */
+	bits += sort_book_numbers(quantInfo,             /* Quantization information */
+		output_book_vector,    /* Output codebook vector, formatted for bitstream */
+		NULL,          /* Bitstream */
+		0);                    /* Write flag: 0 count, 1 write */
+
+	/* calculate the amount of bits needed for the spectral values */
+	quantInfo -> spectralCount = 0;
+	for(i=0;i< quantInfo -> nr_of_sfb;i++) {  
+		bits += output_bits(
+			quantInfo,
+			quantInfo->book_vector[i],
+			quant,
+			quantInfo->sfb_offset[i], 
+			quantInfo->sfb_offset[i+1]-quantInfo->sfb_offset[i],
+			0);
+	}
+
+	/* the number of bits for the scalefactors */
+	bits += write_scalefactor_bitstream(
+		NULL,             /* Bitstream */  
+		0,                        /* Write flag */
+		quantInfo
+		);
+
+	/* the total amount of bits required */
+	return bits;
+}
+
+
+int tf_encode_spectrum_aac(
+			   double      *p_spectrum[MAX_TIME_CHANNELS],
+			   double      *PsySigMaskRatio[MAX_TIME_CHANNELS],
+			   double      allowed_dist[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   double      energy[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS],
+			   int         sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   int         nr_of_sfb[MAX_TIME_CHANNELS],
+			   int         average_block_bits,
+			   int         available_bitreservoir_bits,
+			   int         padding_limit,
+			   BsBitStream *fixed_stream,
+			   BsBitStream *var_stream,
+			   int         nr_of_chan,
+			   double      *p_reconstructed_spectrum[MAX_TIME_CHANNELS],
+			   int         useShortWindows,
+			   int aacAllowScalefacs,
+			   AACQuantInfo* quantInfo,      /* AAC quantization information */ 
+			   Ch_Info* ch_info,
+			   int varBitRate,
+			   int bitRate)
+{
+	int quant[NUM_COEFF];
+	int i=0;
+	int j=0;
+	int k;
+	double max_dct_line = 0;
+	int global_gain;
+	int store_common_scalefac;
+	int best_scale_factor[SFB_NUM_MAX];
+	double pow_spectrum[NUM_COEFF];
+	int sfb_amplify_check[SFB_NUM_MAX];
+	double requant[NUM_COEFF];
+	int sb;
+	int extra_bits;
+	int max_bits;
+	int output_book_vector[SFB_NUM_MAX*2];
+	int start_com_sf;
+	double SigMaskRatio[SFB_NUM_MAX];
+	IS_Info *is_info;
+	int *ptr_book_vector;
+
+	/* Set up local pointers to quantInfo elements for convenience */
+	int* sfb_offset = quantInfo -> sfb_offset;
+	int* scale_factor = quantInfo -> scale_factor;
+	int* common_scalefac = &(quantInfo -> common_scalefac);
+
+	int outer_loop_count;
+	int quantizer_change;
+	int over = 0, best_over = 100, better;
+	int sfb_overflow, amp_over;
+	int best_common_scalefac;
+	double noise_thresh;
+	double over_noise, tot_noise, max_noise;
+	double noise[SFB_NUM_MAX];
+	double best_max_noise = 0;
+	double best_over_noise = 0;
+	double best_tot_noise = 0;
+	static int init = -1;
+
+	/* Set block type in quantization info */
+	quantInfo -> block_type = block_type[MONO_CHAN];
+
+#if 0
+	if (init != (quantInfo->block_type==ONLY_SHORT_WINDOW?2:1)) {
+		if (quantInfo->block_type == ONLY_SHORT_WINDOW)
+			init = 2;
+		else
+			init = 1;
+		compute_ath(quantInfo, ATH);
+	}
+#endif
+
+	/** create the sfb_offset tables **/
+	if (quantInfo -> block_type == ONLY_SHORT_WINDOW) {
+
+		/* Now compute interleaved sf bands and spectrum */
+		sort_for_grouping(
+			quantInfo,                       /* ptr to quantization information */
+			sfb_width_table[MONO_CHAN],      /* Widths of single window */
+			p_spectrum,                      /* Spectral values, noninterleaved */
+			SigMaskRatio,
+			PsySigMaskRatio[MONO_CHAN]
+			);
+
+		extra_bits = 51;
+	} else{
+		/* For long windows, band are not actually interleaved */
+		if ((quantInfo -> block_type == ONLY_LONG_WINDOW) ||  
+			(quantInfo -> block_type == LONG_SHORT_WINDOW) || 
+			(quantInfo -> block_type == SHORT_LONG_WINDOW)) {
+			quantInfo->nr_of_sfb = quantInfo->max_sfb;
+
+			sfb_offset[0] = 0;
+			k=0;
+			for( i=0; i< quantInfo -> nr_of_sfb; i++ ){
+				sfb_offset[i] = k;
+				k +=sfb_width_table[MONO_CHAN][i];
+				SigMaskRatio[i]=PsySigMaskRatio[MONO_CHAN][i];
+			}
+			sfb_offset[i] = k;
+			extra_bits = 100; /* header bits and more ... */
+
+		} 
+	}
+
+	extra_bits += 1;
+
+    /* Take into account bits for TNS data */
+    extra_bits += WriteTNSData(quantInfo,fixed_stream,0);    /* Count but don't write */
+
+    /* for short windows, compute interleaved energy here */
+    if (quantInfo->block_type==ONLY_SHORT_WINDOW) {
+		int numWindowGroups = quantInfo->num_window_groups;
+		int maxBand = quantInfo->max_sfb;
+		int windowOffset=0;
+		int sfb_index=0;
+		int g;
+		for (g=0;g<numWindowGroups;g++) {
+			int numWindowsThisGroup = quantInfo->window_group_length[g];
+			int b;
+			for (b=0;b<maxBand;b++) {
+				double sum=0.0;
+				int w;
+				for (w=0;w<numWindowsThisGroup;w++) {
+					int bandNum = (w+windowOffset)*maxBand + b;
+					sum += energy[MONO_CHAN][bandNum];
+				}
+				energy[MONO_CHAN][sfb_index++]=sum;
+			}
+			windowOffset += numWindowsThisGroup;
+		}
+    } 
+
+	/* Compute allowed distortion */
+	for(sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+		if (10*log10(energy[MONO_CHAN][sb]+1e-15)>70) {
+			allowed_dist[MONO_CHAN][sb] = energy[MONO_CHAN][sb] * SigMaskRatio[sb];
+//			printf("%d\t\t%.3f\n", sb, SigMaskRatio[sb]);
+		} else {
+			allowed_dist[MONO_CHAN][sb] = energy[MONO_CHAN][sb] * 1.1;
+		}
+	}
+
+	/** find the maximum spectral coefficient **/
+	/* Bug fix, 3/10/98 CL */
+	/* for(i=0; i<NUM_COEFF; i++){ */
+	for(i=0; i < sfb_offset[quantInfo->nr_of_sfb]; i++){ 
+		pow_spectrum[i] = (pow(ABS(p_spectrum[0][i]), 0.75));
+		sign[i] = sgn(p_spectrum[0][i]);
+		if ((ABS(p_spectrum[0][i])) > max_dct_line){
+			max_dct_line = ABS(p_spectrum[0][i]);
+		}
+	}
+
+//	if (old_startsf < 40) {
+		if (max_dct_line!=0.0) {
+			start_com_sf = (int)(16/3 * (log(ABS(pow(max_dct_line,0.75)/MAX_QUANT)/log(2.0))));
+		} else {
+			start_com_sf = 40;
+		}
+//	} else {
+//		start_com_sf = old_startsf;
+//	}
+	if ((start_com_sf>200) || (start_com_sf<40) )
+		start_com_sf = 40;
+
+	/* initialize the scale_factors that aren't intensity stereo bands */
+	is_info=&(ch_info->is_info);
+	for(k=0; k< quantInfo -> nr_of_sfb ;k++) {
+		sfb_amplify_check[k] = 0;
+		scale_factor[k]=((is_info->is_present)&&(is_info->is_used[k])) ? scale_factor[k] : 0;
+	}
+
+	/* Mark IS bands by setting book_vector to INTENSITY_HCB */
+	ptr_book_vector=quantInfo->book_vector;
+	for (k=0;k<quantInfo->nr_of_sfb;k++) {
+		if ((is_info->is_present)&&(is_info->is_used[k])) {
+			ptr_book_vector[k] = (is_info->sign[k]) ? INTENSITY_HCB2 : INTENSITY_HCB;
+		} else {
+			ptr_book_vector[k] = 0;
+		}
+	}
+
+	outer_loop_count = 0;
+
+	do { // outer iteration loop
+
+		outer_loop_count++;
+		over = 0;
+		sfb_overflow = 0;
+
+		if (max_dct_line == 0.0)
+			sfb_overflow = 1;
+
+		if (outer_loop_count == 1) {
+			quantizer_change = 8;
+			*common_scalefac = start_com_sf;
+		} else {
+			quantizer_change = 2;
+		}
+
+		do { // inner iteration loop
+
+			if(quantize(quantInfo,	p_spectrum[0], pow_spectrum, quant))
+				max_bits = 1000000;
+			else
+				max_bits = count_bits(quantInfo, quant, output_book_vector) + extra_bits;
+
+			quantizer_change /= 2;
+			store_common_scalefac = *common_scalefac;
+
+			if (max_bits > average_block_bits)
+				*common_scalefac += quantizer_change;
+			else
+				*common_scalefac -= quantizer_change;
+			if (*common_scalefac > 200)
+				return FERROR;
+
+			if ((quantizer_change == 1)&&(max_bits > average_block_bits))
+				quantizer_change = 2;
+
+		} while (quantizer_change != 1);
+
+		over = calc_noise(quantInfo, p_spectrum[0], quant, requant, noise, allowed_dist[0],
+			&over_noise, &tot_noise, &max_noise);
+
+		better = quant_compare(best_over, best_tot_noise, best_over_noise,
+				  best_max_noise, over, tot_noise, over_noise, max_noise);
+
+		if (outer_loop_count == 1)
+			better = 1;
+
+		if (better) {
+			best_over = over;
+			best_max_noise = max_noise;
+			best_over_noise = over_noise;
+			best_tot_noise = tot_noise;
+			best_common_scalefac = store_common_scalefac;
+
+			for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+				best_scale_factor[sb] = scale_factor[sb];
+			}
+		}
+
+		amp_over = 0;
+
+#if 1
+		noise_thresh = 0;
+#else
+		noise_thresh = -900;
+		for ( sb = 0; sb < quantInfo->nr_of_sfb; sb++ )
+			noise_thresh = max(1.05*noise[sb], noise_thresh);
+		noise_thresh = min(noise_thresh, 0.0);
+#endif
+
+		for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+			if ((noise[sb] > noise_thresh)&&(quantInfo->book_vector[sb]!=INTENSITY_HCB)&&(quantInfo->book_vector[sb]!=INTENSITY_HCB2)) {
+
+				amp_over++;
+
+				allowed_dist[0][sb] *= 2;
+				scale_factor[sb]++;
+			}
+		}
+
+		if (sfb_overflow == 0) {
+			sfb_overflow = 1;
+			for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+				if (scale_factor[sb] == 0)
+					sfb_overflow = 0;
+			}
+		}
+		for (sb = 0; sb < quantInfo->nr_of_sfb-1; sb++) {
+			if (scale_factor[sb] > (scale_factor[sb+1]+60))
+				sfb_overflow = 1;
+			if (scale_factor[sb] < (scale_factor[sb+1]-60))
+				sfb_overflow = 1;
+		}
+		if (scale_factor[quantInfo->nr_of_sfb-1] > (scale_factor[quantInfo->nr_of_sfb-2]+60))
+			sfb_overflow = 1;
+		if (scale_factor[quantInfo->nr_of_sfb-1] < (scale_factor[quantInfo->nr_of_sfb-2]-60))
+			sfb_overflow = 1;
+
+		if ((amp_over == 0)||(over == 0)||(amp_over==quantInfo->nr_of_sfb)||(sfb_overflow))
+			break;
+
+	} while (1);
+
+	*common_scalefac = best_common_scalefac;
+	for (sb = 0; sb < quantInfo->nr_of_sfb; sb++) {
+		scale_factor[sb] = best_scale_factor[sb];
+	}
+
+	old_startsf = *common_scalefac;
+
+	quantize(quantInfo,	p_spectrum[0], pow_spectrum, quant);
+	calc_noise(quantInfo, p_spectrum[0], quant, requant, noise, allowed_dist[0],
+			&over_noise, &tot_noise, &max_noise);
+	if (quantInfo->block_type==ONLY_SHORT_WINDOW)
+		quantInfo->pulseInfo.pulse_data_present = 0;
+	else
+		PulseCoder(quantInfo, quant);
+	count_bits(quantInfo, quant, output_book_vector);
+
+//	for( sb=0; sb< quantInfo -> nr_of_sfb; sb++ ) {
+//		printf("%d error: %.4f all.dist.: %.4f energy: %.4f\n", sb,
+//			noise[sb], allowed_dist[0][sb], energy[0][sb]);
+//	}
+
+	/* offset the differenec of common_scalefac and scalefactors by SF_OFFSET  */
+	for (i=0; i<quantInfo->nr_of_sfb; i++){
+		if ((ptr_book_vector[i]!=INTENSITY_HCB)&&(ptr_book_vector[i]!=INTENSITY_HCB2)) {
+			scale_factor[i] = *common_scalefac - scale_factor[i] + SF_OFFSET;
+		}
+	}
+	*common_scalefac = global_gain = scale_factor[0];
+
+	/* place the codewords and their respective lengths in arrays data[] and len[] respectively */
+	/* there are 'counter' elements in each array, and these are variable length arrays depending on the input */
+
+	quantInfo -> spectralCount = 0;
+	for(k=0;k< quantInfo -> nr_of_sfb; k++) {  
+		output_bits(
+			quantInfo,
+			quantInfo->book_vector[k],
+			quant,
+			quantInfo->sfb_offset[k],
+			quantInfo->sfb_offset[k+1]-quantInfo->sfb_offset[k], 
+			1);
+//		printf("%d\t%d\n",k,quantInfo->book_vector[k]);
+	}
+
+	/* write the reconstructed spectrum to the output for use with prediction */
+	{
+		int i;
+		for (sb=0; sb<quantInfo -> nr_of_sfb; sb++){
+			if ((ptr_book_vector[sb]==INTENSITY_HCB)||(ptr_book_vector[sb]==INTENSITY_HCB2)){
+				for (i=sfb_offset[sb]; i<sfb_offset[sb+1]; i++){
+					p_reconstructed_spectrum[0][i]=673;
+				}
+			} else {
+				for (i=sfb_offset[sb]; i<sfb_offset[sb+1]; i++){
+					p_reconstructed_spectrum[0][i] = sgn(p_spectrum[0][i]) * requant[i]; 
+				}
+			}
+		}
+	}
+
+	return FNO_ERROR;
+}
+
+int sort_for_grouping(AACQuantInfo* quantInfo,        /* ptr to quantization information */
+		      int sfb_width_table[],          /* Widths of single window */
+		      double *p_spectrum[],           /* Spectral values, noninterleaved */
+		      double *SigMaskRatio,
+		      double *PsySigMaskRatio)
+{
+	int i,j,ii;
+	int index = 0;
+	double tmp[1024];
+	int book=1;
+	int group_offset=0;
+	int k=0;
+	int windowOffset = 0;
+
+	/* set up local variables for used quantInfo elements */
+	int* sfb_offset = quantInfo -> sfb_offset;
+	int* nr_of_sfb = &(quantInfo -> nr_of_sfb);
+	int* window_group_length;
+	int num_window_groups;
+	*nr_of_sfb = quantInfo->max_sfb;              /* Init to max_sfb */
+	window_group_length = quantInfo -> window_group_length;
+	num_window_groups = quantInfo -> num_window_groups;
+	
+	/* calc org sfb_offset just for shortblock */
+	sfb_offset[k]=0;
+	for (k=1 ; k <*nr_of_sfb+1; k++) {
+		sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
+	}
+
+	/* sort the input spectral coefficients */
+	index = 0;
+	group_offset=0;
+	for (i=0; i< num_window_groups; i++) {
+		for (k=0; k<*nr_of_sfb; k++) {
+			for (j=0; j < window_group_length[i]; j++) {
+				for (ii=0;ii< sfb_width_table[k];ii++)
+					tmp[index++] = p_spectrum[MONO_CHAN][ii+ sfb_offset[k] + 128*j +group_offset];
+			}
+		}
+		group_offset +=  128*window_group_length[i];     
+	}
+
+	for (k=0; k<1024; k++){
+		p_spectrum[MONO_CHAN][k] = tmp[k];
+	}
+
+	/* now calc the new sfb_offset table for the whole p_spectrum vector*/
+	index = 0;
+	sfb_offset[index++] = 0;	  
+	windowOffset = 0;
+	for (i=0; i < num_window_groups; i++) {
+		for (k=0 ; k <*nr_of_sfb; k++) {
+			/* for this window group and this band, find worst case inverse sig-mask-ratio */
+			int bandNum=windowOffset*NSFB_SHORT + k;
+			double worstISMR = PsySigMaskRatio[bandNum];
+			int w;
+			for (w=1;w<window_group_length[i];w++) {
+				bandNum=(w+windowOffset)*NSFB_SHORT + k;
+				if (PsySigMaskRatio[bandNum]<worstISMR) {
+				//if (PsySigMaskRatio[bandNum]>worstISMR) {
+					worstISMR = PsySigMaskRatio[bandNum];
+				}
+			}
+			SigMaskRatio[k+ i* *nr_of_sfb]=worstISMR;
+			sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
+			index++;
+		}
+		windowOffset += window_group_length[i];
+	}
+
+	*nr_of_sfb = *nr_of_sfb * num_window_groups;  /* Number interleaved bands. */
+
+	return 0;
+}
+
+sort_book_numbers(AACQuantInfo* quantInfo,     /* Quantization information */
+		  int output_book_vector[],    /* Output codebook vector, formatted for bitstream */
+		  BsBitStream* fixed_stream,   /* Bitstream */
+		  int write_flag)              /* Write flag: 0 count, 1 write */
+{
+  /*
+    This function inputs the vector, 'book_vector[]', which is of length SFB_NUM_MAX,
+    and contains the optimal huffman tables of each sfb.  It returns the vector, 'output_book_vector[]', which
+    has it's elements formatted for the encoded bit stream.  It's syntax is:
+   
+    {sect_cb[0], length_segment[0], ... ,sect_cb[num_of_sections], length_segment[num_of_sections]}
+
+    The above syntax is true, unless there is an escape sequence.  An
+    escape sequence occurs when a section is longer than 2 ^ (bit_len)
+    long in units of scalefactor bands.  Also, the integer returned from
+    this function is the number of bits written in the bitstream, 
+    'bit_count'.  
+
+    This function supports both long and short blocks.
+    */
+
+	int i;
+	int repeat_counter = 1;
+	int bit_count = 0;
+	int previous;
+	int max, bit_len/*,sfbs*/;
+	int max_sfb,g,band;
+
+	/* Set local pointers to quantInfo elements */
+	int* book_vector = quantInfo -> book_vector;
+	int nr_of_sfb = quantInfo -> nr_of_sfb;
+
+	if (quantInfo->block_type == ONLY_SHORT_WINDOW){
+		max = 7;
+		bit_len = 3;
+	} else {  /* the block_type is a long,start, or stop window */
+		max = 31;
+		bit_len = 5;
+	}
+
+	/* Compute number of scalefactor bands */
+	max_sfb = quantInfo->nr_of_sfb/quantInfo->num_window_groups;
+
+
+	for (g=0;g<quantInfo->num_window_groups;g++) {
+		band=g*max_sfb;
+
+		repeat_counter=1;
+
+		previous = book_vector[band];
+		if (write_flag) {   
+			BsPutBit(fixed_stream,book_vector[band],4);  
+		}
+		bit_count += 4;
+
+		for (i=band+1;i<band+max_sfb;i++) {
+			if( (book_vector[i] != previous)) {
+				if (write_flag) {
+					BsPutBit(fixed_stream,repeat_counter,bit_len);  
+				}
+				bit_count += bit_len;
+
+				if (repeat_counter == max){  /* in case you need to terminate an escape sequence */
+					if (write_flag) BsPutBit(fixed_stream,0,bit_len);  
+					bit_count += bit_len;
+				}
+				
+				if (write_flag) BsPutBit(fixed_stream,book_vector[i],4);  
+				bit_count += 4;
+				previous = book_vector[i];
+				repeat_counter=1;
+				
+			}
+			/* if the length of the section is longer than the amount of bits available in */
+			/* the bitsream, "max", then start up an escape sequence */
+			else if ((book_vector[i] == previous) && (repeat_counter == max)) { 
+				if (write_flag) {
+					BsPutBit(fixed_stream,repeat_counter,bit_len);  
+				}
+				bit_count += bit_len;
+				repeat_counter = 1;
+			}
+			else {
+				repeat_counter++;
+			}
+		}
+		
+		if (write_flag) {
+			BsPutBit(fixed_stream,repeat_counter,bit_len);  
+		}
+		bit_count += bit_len;
+		if (repeat_counter == max) {  /* special case if the last section length is an */
+			/* escape sequence */
+			if (write_flag) BsPutBit(fixed_stream,0,bit_len);  
+			bit_count += bit_len;
+		}
+		
+
+	}  /* Bottom of group iteration */
+
+	return(bit_count);
+}
+
+int bit_search(int quant[NUM_COEFF],  /* Quantized spectral values */
+               AACQuantInfo* quantInfo)        /* Quantization information */
+  /*
+  This function inputs a vector of quantized spectral data, quant[][], and returns a vector,
+  'book_vector[]' that describes how to group together the scalefactor bands into a smaller
+  number of sections.  There are SFB_NUM_MAX elements in book_vector (equal to 49 in the 
+  case of long blocks and 112 for short blocks), and each element has a huffman codebook 
+  number assigned to it.
+
+  For a quick and simple algorithm, this function performs a binary
+  search across the sfb's (scale factor bands).  On the first approach, it calculates the 
+  needed amount of bits if every sfb were its own section and transmitted its own huffman 
+  codebook value side information (equal to 9 bits for a long block, 7 for a short).  The 
+  next iteration combines adjacent sfb's, and calculates the bit rate for length two sfb 
+  sections.  If any wider two-sfb section requires fewer bits than the sum of the two 
+  single-sfb sections (below it in the binary tree), then the wider section will be chosen.
+  This process occurs until the sections are split into three uniform parts, each with an
+  equal amount of sfb's contained.  
+
+  The binary tree is stored as a two-dimensional array.  Since this tree is not full, (there
+  are only 49 nodes, not 2^6 = 64), the numbering is a little complicated.  If the tree were
+  full, the top node would be 1.  It's children would be 2 and 3.  But, since this tree
+  is not full, the top row of three nodes are numbered {4,5,6}.  The row below it is
+  {8,9,10,11,12,13}, and so on.  
+
+  The binary tree is called bit_stats[112][3].  There are 112 total nodes (some are not
+  used since it's not full).  bit_stats[x][0] holds the bit totals needed for the sfb sectioning
+  strategy represented by the node x in the tree.  bit_stats[x][1] holds the optimal huffman
+  codebook table that minimizes the bit rate, given the sectioning boundaries dictated by node x.
+*/
+
+{
+	int i,j,k,m,n;
+	int hop;
+	int min_book_choice[112][3];
+	int bit_stats[240][3];
+	int total_bits;
+	int total_bit_count;
+	int levels;
+	double fraction;
+
+	/* Set local pointer to quantInfo book_vector */
+	int* book_vector = quantInfo -> book_vector;
+
+	levels = (int) ((log((double)quantInfo->nr_of_sfb)/log((double)2.0))+1);
+	fraction = (pow(2,levels)+quantInfo->nr_of_sfb)/(double)(pow(2,levels)); 
+
+//#define SLOW
+#ifdef SLOW
+	for(i=0;i<5;i++){
+		hop = 1 << i;
+#else
+		hop = 1;
+		i = 0;
+#endif
+		total_bits = noiseless_bit_count(quant,
+			hop,
+			min_book_choice,
+			quantInfo);         /* Quantization information */
+
+		/* load up the (not-full) binary search tree with the min_book_choice values */
+		k=0;
+		m=0;
+		total_bit_count = 0;
+
+		for (j=(int)(pow(2,levels-i)); j<(int)(fraction*pow(2,levels-i)); j++)
+		{
+			bit_stats[j][0] = min_book_choice[k][0]; /* the minimum bit cost for this section */
+			bit_stats[j][1] = min_book_choice[k][1]; /* used with this huffman book number */
+
+			if (i>0){  /* not on the lowest level, grouping more than one signle scalefactor band per section*/
+				if  (bit_stats[j][0] < bit_stats[2*j][0] + bit_stats[2*j+1][0]){
+
+					/* it is cheaper to combine surrounding sfb secionts into one larger huffman book section */
+					for(n=k;n<k+hop;n++) { /* write the optimal huffman book value for the new larger section */
+						if ( (book_vector[n]!=INTENSITY_HCB)&&(book_vector[n]!=INTENSITY_HCB2) ) { /* Don't merge with IS bands */
+							book_vector[n] = bit_stats[j][1];
+						}
+					}
+				} else {  /* it was cheaper to transmit the smaller huffman table sections */
+					bit_stats[j][0] = bit_stats[2*j][0] + bit_stats[2*j+1][0];
+				}
+			} else {  /* during the first stage of the iteration, all sfb's are individual sections */
+				if ( (book_vector[k]!=INTENSITY_HCB)&&(book_vector[k]!=INTENSITY_HCB2) ) {
+					book_vector[k] = bit_stats[j][1];  /* initially, set all sfb's to their own optimal section table values */
+				}
+			}
+			total_bit_count = total_bit_count +  bit_stats[j][0];
+			k=k+hop;
+			m++;
+		}
+#ifdef SLOW
+	}
+#endif
+	/*   book_vector[k] = book_vector[k-1]; */
+	return(total_bit_count);
+}
+
+
+int noiseless_bit_count(int quant[NUM_COEFF],
+			/*int huff[13][MAXINDEX][NUMINTAB],*/
+			int hop,  // hop is now always 1
+			int min_book_choice[112][3],
+			AACQuantInfo* quantInfo)         /* Quantization information */
+{
+  int i,j,k;
+
+  /* 
+     This function inputs:
+     - the quantized spectral data, 'quant[][]';
+     - all of the huffman codebooks, 'huff[][]';
+     - the size of the sections, in scalefactor bands (SFB's), 'hop';
+     - an empty matrix, min_book_choice[][] passed to it; 
+
+     This function outputs:
+     - the matrix, min_book_choice.  It is a two dimensional matrix, with its
+     rows corresponding to spectral sections.  The 0th column corresponds to 
+     the bits needed to code a section with 'hop' scalefactors bands wide, all using 
+     the same huffman codebook.  The 1st column contains the huffman codebook number 
+     that allows the minimum number of bits to be used.   
+
+     Other notes:
+     - Initally, the dynamic range is calculated for each spectral section.  The section
+     can only be entropy coded with books that have an equal or greater dynamic range
+     than the section's spectral data.  The exception to this is for the 11th ESC codebook.
+     If the dynamic range is larger than 16, then an escape code is appended after the
+     table 11 codeword which encodes the larger value explicity in a pseudo-non-uniform
+     quantization method.
+     
+     */
+
+	int max_sb_coeff;
+	int book_choice[12][2];
+	int total_bits_cost = 0;
+	int offset, length, end;
+	int q;
+	int write_flag = 0;
+
+	/* set local pointer to sfb_offset */
+	int* sfb_offset = quantInfo->sfb_offset;
+	int nr_of_sfb = quantInfo->nr_of_sfb;
+
+	/* each section is 'hop' scalefactor bands wide */
+	for (i=0; i < nr_of_sfb; i=i+hop){ 
+		if ((i+hop) > nr_of_sfb)
+			q = nr_of_sfb;
+		else
+			q = i+hop;
+
+		{
+			
+			/* find the maximum absolute value in the current spectral section, to see what tables are available to use */
+			max_sb_coeff = 0;
+			for (j=sfb_offset[i]; j<sfb_offset[q]; j++){  /* snl */
+				if (ABS(quant[j]) > max_sb_coeff)
+					max_sb_coeff = ABS(quant[j]);
+			}
+			
+			j = 0;
+			offset = sfb_offset[i];
+			if ((i+hop) > nr_of_sfb){
+				end = sfb_offset[nr_of_sfb];
+			}
+			else
+				end = sfb_offset[q];
+			length = end - offset;
+
+			/* all spectral coefficients in this section are zero */
+			if (max_sb_coeff == 0) { 
+				book_choice[j][0] = output_bits(quantInfo,0,quant,offset,length,write_flag);
+				book_choice[j++][1] = 0; 
+
+			}
+			else {  /* if the section does have non-zero coefficients */
+				/* Changed all the else's to else if's, big speed up. Hardly any loss in coding. */
+				if(max_sb_coeff < 2){
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,1,quant,offset,length,write_flag);
+					book_choice[j++][1] = 1;
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,2,quant,offset,length,write_flag);
+					book_choice[j++][1] = 2;
+				}
+				/*else*/ if (max_sb_coeff < 3){
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,3,quant,offset,length,write_flag);
+					book_choice[j++][1] = 3;
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,4,quant,offset,length,write_flag);
+					book_choice[j++][1] = 4;
+				}
+				/*else*/ if (max_sb_coeff < 5){
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,5,quant,offset,length,write_flag);
+					book_choice[j++][1] = 5;
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,6,quant,offset,length,write_flag);
+					book_choice[j++][1] = 6;
+				}
+				/*else*/ if (max_sb_coeff < 8){
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,7,quant,offset,length,write_flag);
+					book_choice[j++][1] = 7;
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,8,quant,offset,length,write_flag);
+					book_choice[j++][1] = 8;
+				}
+				/*else*/ if (max_sb_coeff < 13){
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,9,quant,offset,length,write_flag);
+					book_choice[j++][1] = 9;
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,10,quant,offset,length,write_flag);
+					book_choice[j++][1] = 10;
+				}
+				/* (max_sb_coeff >= 13), choose table 11 */
+				else {
+					quantInfo->spectralCount = 0; /* just for debugging : using data and len vectors */
+					book_choice[j][0] = output_bits(quantInfo,11,quant,offset,length,write_flag);
+					book_choice[j++][1] = 11;
+				}
+			}
+
+			/* find the minimum bit cost and table number for huffman coding this scalefactor section */
+			min_book_choice[i][0] = 100000;  
+			for(k=0;k<j;k++){
+				if (book_choice[k][0] < min_book_choice[i][0]){
+					min_book_choice[i][1] = book_choice[k][1];
+					min_book_choice[i][0] = book_choice[k][0];
+				}
+			}
+			total_bits_cost += min_book_choice[i][0];
+		}
+	}
+	return(total_bits_cost);
+}
+
+
+
+int calculate_esc_sequence(int input,
+						   int *len_esc_sequence
+						   )
+/* 
+   This function takes an element that is larger than 16 and generates the base10 value of the 
+   equivalent escape sequence.  It returns the escape sequence in the variable, 'output'.  It
+   also passed the length of the escape sequence through the parameter, 'len_esc_sequence'.
+*/
+
+{
+	float x,y;
+	int output;
+	int N;
+
+	N = -1;
+	y = (float)ABS(input);
+	x = y / 16;
+
+	while (x >= 1) {
+		N++;
+		x = x/2;
+	}
+
+	*len_esc_sequence = 2*N + 5;  /* the length of the escape sequence in bits */
+
+	output = (int)((pow(2,N) - 1)*pow(2,N+5) + y - pow(2,N+4));
+	return(output);
+}
+
+
+
+int output_bits(AACQuantInfo* quantInfo,
+				/*int huff[13][MAXINDEX][NUMINTAB],*/
+                int book,
+				int quant[NUM_COEFF],
+                int offset,
+				int length,
+				int write_flag)
+{
+  /* 
+     This function inputs 
+     - all the huffman codebooks, 'huff[]' 
+     - a specific codebook number, 'book'
+     - the quantized spectral data, 'quant[][]'
+     - the offset into the spectral data to begin scanning, 'offset'
+     - the 'length' of the segment to huffman code
+     -> therefore, the segment quant[CHANNEL][offset] to quant[CHANNEL][offset+length-1]
+     is huffman coded.
+     - a flag, 'write_flag' to determine whether the codebooks and lengths need to be written
+     to file.  If write_flag=0, then this function is being used only in the quantization
+     rate loop, and does not need to spend time writing the codebooks and lengths to file.
+     If write_flag=1, then it is being called by the function output_bits(), which is 
+     sending the bitsteam out of the encoder.  
+
+     This function outputs 
+     - the number of bits required, 'bits'  using the prescribed codebook, book applied to 
+     the given segment of spectral data.
+
+     There are three parameters that are passed back and forth into this function.  data[]
+     and len[] are one-dimensional arrays that store the codebook values and their respective
+     bit lengths.  These are used when packing the data for the bitstream in output_bits().  The
+     index into these arrays is 'quantInfo->spectralCount''.  It gets incremented internally in this
+     function as counter, then passed to the outside through outside_counter.  The next time
+     output_bits() is called, counter starts at the value it left off from the previous call.
+
+   */
+ 
+	int esc_sequence;
+	int len_esc;
+	int index;
+	int bits=0;
+	int tmp = 0;
+	int codebook,i,j;
+	int counter;
+
+	/* Set up local pointers to quantInfo elements data and len */
+	int* data= quantInfo -> data;
+	int* len=  quantInfo -> len;
+
+	counter = quantInfo->spectralCount;
+
+	/* This case also applies to intensity stereo encoding */
+	/*if (book == 0) { */ /* if using the zero codebook, data of zero length is sent */
+	if ((book == 0)||(book==INTENSITY_HCB2)||(book==INTENSITY_HCB)) {  /* if using the zero codebook, 
+		data of zero length is sent */
+		
+		if (write_flag) {
+			quantInfo->data[counter] = 0;
+			quantInfo->len[counter++] = 0;
+		}
+	}
+
+	if ((book == 1) || (book == 2)) {
+		for(i=offset;i<offset+length;i=i+4){
+			index = 27*quant[i] + 9*quant[i+1] + 3*quant[i+2] + quant[i+3] + 40;
+			if (book == 1) {
+				codebook = huff1[index][LASTINTAB];
+				tmp = huff1[index][FIRSTINTAB];
+			} else {
+				codebook = huff2[index][LASTINTAB];
+				tmp = huff2[index][FIRSTINTAB];
+			}
+			bits += tmp;
+			if (write_flag) {
+				data[counter] = codebook;
+				len[counter++] = tmp;
+			}
+		}
+	}
+
+	if ((book == 3) || (book == 4)) {
+		for(i=offset;i<offset+length;i=i+4){
+			index = 27*ABS(quant[i]) + 9*ABS(quant[i+1]) + 3*ABS(quant[i+2]) + ABS(quant[i+3]);
+			if (book == 3) {
+				codebook = huff3[index][LASTINTAB];
+				tmp = huff3[index][FIRSTINTAB];
+			} else {
+				codebook = huff4[index][LASTINTAB];
+				tmp = huff4[index][FIRSTINTAB];
+			}
+			bits = bits + tmp;
+			for(j=0;j<4;j++){
+				if(ABS(quant[i+j]) > 0) bits += 1; /* only for non-zero spectral coefficients */
+			}
+			if (write_flag) {
+				data[counter] = codebook;
+				len[counter++] = tmp;
+				for(j=0;j<4;j++){
+					if(quant[i+j] > 0) {  /* send out '0' if a positive value */
+						data[counter] = 0;
+						len[counter++] = 1;
+					}
+					if(quant[i+j] < 0) {  /* send out '1' if a negative value */
+						data[counter] = 1;
+						len[counter++] = 1;
+					}
+				}
+			}
+		}
+	}
+
+	if ((book == 5) || (book == 6)) {
+		for(i=offset;i<offset+length;i=i+2){
+			index = 9*(quant[i]) + (quant[i+1]) + 40;
+			if (book == 5) {
+				codebook = huff5[index][LASTINTAB];
+				tmp = huff5[index][FIRSTINTAB];
+			} else {
+				codebook = huff6[index][LASTINTAB];
+				tmp = huff6[index][FIRSTINTAB];
+			}
+			bits = bits + tmp;
+			if (write_flag) {
+				data[counter] = codebook;
+				len[counter++] = tmp;
+			}
+		}
+	}
+
+	if ((book == 7) || (book == 8)) {
+		for(i=offset;i<offset+length;i=i+2){
+			index = 8*ABS(quant[i]) + ABS(quant[i+1]);
+			if (book == 7) {
+				codebook = huff7[index][LASTINTAB];
+				tmp = huff7[index][FIRSTINTAB];
+			} else {
+				codebook = huff8[index][LASTINTAB];
+				tmp = huff8[index][FIRSTINTAB];
+			}
+			bits = bits + tmp;
+			for(j=0;j<2;j++){
+				if(ABS(quant[i+j]) > 0) bits += 1; /* only for non-zero spectral coefficients */
+			}
+			if (write_flag) {
+				data[counter] = codebook;
+				len[counter++] = tmp;
+				for(j=0;j<2;j++){
+					if(quant[i+j] > 0) {  /* send out '0' if a positive value */
+						data[counter] = 0;
+						len[counter++] = 1;
+					}
+					if(quant[i+j] < 0) {  /* send out '1' if a negative value */
+						data[counter] = 1;
+						len[counter++] = 1;
+					}
+				}
+			}
+		}
+	}
+
+	if ((book == 9) || (book == 10)) {
+		for(i=offset;i<offset+length;i=i+2){
+			index = 13*ABS(quant[i]) + ABS(quant[i+1]);
+			if (book == 9) {
+				codebook = huff9[index][LASTINTAB];
+				tmp = huff9[index][FIRSTINTAB];
+			} else {
+				codebook = huff10[index][LASTINTAB];
+				tmp = huff10[index][FIRSTINTAB];
+			}
+			bits = bits + tmp;
+			for(j=0;j<2;j++){
+				if(ABS(quant[i+j]) > 0) bits += 1; /* only for non-zero spectral coefficients */
+			}
+			if (write_flag) {
+				
+				data[counter] = codebook;
+				len[counter++] = tmp;
+
+				for(j=0;j<2;j++){
+					if(quant[i+j] > 0) {  /* send out '0' if a positive value */
+						data[counter] = 0;
+						len[counter++] = 1;
+					}
+					if(quant[i+j] < 0) {  /* send out '1' if a negative value */
+						data[counter] = 1;
+						len[counter++] = 1;
+					}
+				}
+			}
+		}
+	}
+
+	if ((book == 11)){
+		/* First, calculate the indecies into the huffman tables */
+
+		for(i=offset;i<offset+length;i=i+2){
+			if ((ABS(quant[i]) >= 16) && (ABS(quant[i+1]) >= 16)) {  /* both codewords were above 16 */
+				/* first, code the orignal pair, with the larger value saturated to +/- 16 */
+				index = 17*16 + 16;
+			}
+			else if (ABS(quant[i]) >= 16) {  /* the first codeword was above 16, not the second one */
+				/* first, code the orignal pair, with the larger value saturated to +/- 16 */
+				index = 17*16 + ABS(quant[i+1]);
+			}
+			else if (ABS(quant[i+1]) >= 16) { /* the second codeword was above 16, not the first one */
+				index = 17*ABS(quant[i]) + 16;
+			}
+			else {  /* there were no values above 16, so no escape sequences */
+				index = 17*ABS(quant[i]) + ABS(quant[i+1]);
+			}
+
+			/* write out the codewords */
+
+			tmp = huff11[index][FIRSTINTAB];
+			codebook = huff11[index][LASTINTAB];
+			bits += tmp;
+			if (write_flag) {
+				/*	printf("[book %d] {%d %d} \n",book,quant[i],quant[i+1]);*/
+				data[counter] = codebook;
+				len[counter++] = tmp;
+			}
+			
+			/* Take care of the sign bits */
+
+			for(j=0;j<2;j++){
+				if(ABS(quant[i+j]) > 0) bits += 1; /* only for non-zero spectral coefficients */
+			}
+			if (write_flag) {
+				for(j=0;j<2;j++){
+					if(quant[i+j] > 0) {  /* send out '0' if a positive value */
+						data[counter] = 0;
+						len[counter++] = 1;
+					}
+					if(quant[i+j] < 0) {  /* send out '1' if a negative value */
+						data[counter] = 1;
+						len[counter++] = 1;
+					}
+				}
+			}
+
+			/* write out the escape sequences */
+
+			if ((ABS(quant[i]) >= 16) && (ABS(quant[i+1]) >= 16)) {  /* both codewords were above 16 */
+				/* code and transmit the first escape_sequence */
+				esc_sequence = calculate_esc_sequence(quant[i],&len_esc); 
+				bits += len_esc;
+				if (write_flag) {
+					data[counter] = esc_sequence;
+					len[counter++] = len_esc;
+				}
+
+				/* then code and transmit the second escape_sequence */
+				esc_sequence = calculate_esc_sequence(quant[i+1],&len_esc); 
+				bits += len_esc;
+				if (write_flag) {
+					data[counter] = esc_sequence;
+					len[counter++] = len_esc;
+				}
+			}
+
+			else if (ABS(quant[i]) >= 16) {  /* the first codeword was above 16, not the second one */
+				/* code and transmit the escape_sequence */
+				esc_sequence = calculate_esc_sequence(quant[i],&len_esc); 
+				bits += len_esc;
+				if (write_flag) {
+					data[counter] = esc_sequence;
+					len[counter++] = len_esc;
+				}
+			}
+
+			else if (ABS(quant[i+1]) >= 16) { /* the second codeword was above 16, not the first one */
+				/* code and transmit the escape_sequence */
+				esc_sequence = calculate_esc_sequence(quant[i+1],&len_esc); 
+				bits += len_esc;
+				if (write_flag) {
+					data[counter] = esc_sequence;
+					len[counter++] = len_esc;
+				}
+			} 
+		}
+	}
+
+	quantInfo -> spectralCount = counter;  /* send the current count back to the outside world */
+
+	return(bits);
+}
+
+
+int find_grouping_bits(int window_group_length[],
+					   int num_window_groups
+					   )
+{
+
+  /* This function inputs the grouping information and outputs the seven bit 
+	'grouping_bits' field that the NBC decoder expects.  */
+
+
+	int grouping_bits = 0;
+	int tmp[8];
+	int i,j;
+	int index=0;
+
+	for(i=0; i<num_window_groups; i++){
+		for (j=0; j<window_group_length[i];j++){
+			tmp[index++] = i;
+		}
+	}
+
+	for(i=1; i<8; i++){
+		grouping_bits = grouping_bits << 1;
+		if(tmp[i] == tmp[i-1]) {
+			grouping_bits++;
+		}
+	}
+	
+	return(grouping_bits);
+}
+
+
+
+int write_scalefactor_bitstream(BsBitStream* fixed_stream,             /* Bitstream */  
+				int write_flag,                        /* Write flag */
+				AACQuantInfo* quantInfo)               /* Quantization information */
+{
+	/* this function takes care of counting the number of bits necessary */
+	/* to encode the scalefactors.  In addition, if the write_flag == 1, */
+	/* then the scalefactors are written out the fixed_stream output bit */
+	/* stream.  it returns k, the number of bits written to the bitstream*/
+
+	int i,j,k=0;
+	int diff,length,codeword;
+	int previous_scale_factor;
+	int previous_is_factor;       /* Intensity stereo */
+	int index = 0;
+	int count = 0;
+	int group_offset = 0;
+	int nr_of_sfb_per_group=0;
+
+	/* set local pointer to quantInfo elements */
+	int* scale_factors = quantInfo->scale_factor;
+	
+	if (quantInfo->block_type == ONLY_SHORT_WINDOW) { /* short windows */
+		nr_of_sfb_per_group = quantInfo->nr_of_sfb/quantInfo->num_window_groups;
+	}
+	else {
+		nr_of_sfb_per_group = quantInfo->nr_of_sfb;
+		quantInfo->num_window_groups = 1;
+		quantInfo->window_group_length[0] = 1;
+	}
+
+	previous_scale_factor = quantInfo->common_scalefac;
+	previous_is_factor = 0;
+    
+	for(j=0; j<quantInfo->num_window_groups; j++){
+		for(i=0;i<nr_of_sfb_per_group;i++) {  
+			/* test to see if any codebooks in a group are zero */
+			if ( (quantInfo->book_vector[index]==INTENSITY_HCB) ||
+				(quantInfo->book_vector[index]==INTENSITY_HCB2) ) {
+				/* only send scalefactors if using non-zero codebooks */
+				diff = scale_factors[index] - previous_is_factor;
+				length = huff12[diff+60][FIRSTINTAB];
+				k+=length;
+				previous_is_factor = scale_factors[index];
+				if (write_flag == 1 ) {   
+					codeword = huff12[diff+60][LASTINTAB];
+					BsPutBit(fixed_stream,codeword,length); 
+				}
+			} else if (quantInfo->book_vector[index]) {
+				/* only send scalefactors if using non-zero codebooks */
+				diff = scale_factors[index] - previous_scale_factor;
+				length = huff12[diff+60][FIRSTINTAB];
+				k+=length;
+				previous_scale_factor = scale_factors[index];
+				if (write_flag == 1 ) {   
+					codeword = huff12[diff+60][LASTINTAB];
+					BsPutBit(fixed_stream,codeword,length); 
+				}
+			}
+			index++;
+		}
+	}
+	return(k);
+}
+
--- /dev/null
+++ b/aac_qc.h
@@ -1,0 +1,193 @@
+
+#ifndef AAC_QC_H
+#define AAC_QC_H
+
+#include "pulse.h"
+#include "interface.h"
+#include "tf_main.h"
+#include "tns.h"
+#include "all.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+/* assumptions for the first run of this quantizer */
+#define CHANNEL  1
+#define NUM_COEFF  BLOCK_LEN_LONG       /* now using BLOCK_LEN_LONG of block.h */
+#define MAGIC_NUMBER  0.4054
+#define MAX_QUANT 8192
+#define SF_OFFSET 100
+#define ABS(A) ((A) < 0 ? (-A) : (A))
+#define sgn(A) ((A) > 0 ? (1) : (-1))
+#define SFB_NUM_MAX MAX_SCFAC_BANDS     /* now using MAX_SCFAC_BANDS of tf_main.h */
+
+
+// Huffman tables
+#define MAXINDEX 289
+#define NUMINTAB 2
+#define FIRSTINTAB 0
+#define LASTINTAB 1
+
+/*********************************************************/
+/* AACQuantInfo, info for AAC quantization and coding.   */
+/*********************************************************/
+typedef struct {
+  int max_sfb;                          /* max_sfb, should = nr_of_sfb/num_window_groups */
+  int nr_of_sfb;                        /* Number of scalefactor bands, interleaved */
+  int spectralCount;                    /* Number of spectral data coefficients */
+  enum WINDOW_TYPE block_type;	        /* Block type */      
+  int scale_factor[SFB_NUM_MAX];        /* Scalefactor data array , interleaved */			
+  int sfb_offset[250];                  /* Scalefactor spectral offset, interleaved */
+  int book_vector[SFB_NUM_MAX];         /* Huffman codebook selected for each sf band */
+  int data[5*NUM_COEFF];                /* Data of spectral bitstream elements, for each spectral pair, 
+                                           5 elements are required: 1*(esc)+2*(sign)+2*(esc value)=5 */
+  int len[5*NUM_COEFF];                 /* Lengths of spectral bitstream elements */
+  int num_window_groups;                /* Number of window groups */
+  int window_group_length
+    [MAX_SHORT_IN_LONG_BLOCK];          /* Length (in windows) of each window group */
+  int common_scalefac;                  /* Global gain */
+  Window_shape window_shape;            /* Window shape parameter */
+  short pred_global_flag;               /* Global prediction enable flag */
+  int pred_sfb_flag[SFB_NUM_MAX];       /* Prediction enable flag for each scalefactor band */
+  int reset_group_number;               /* Prediction reset group number */
+  TNS_INFO* tnsInfo;                    /* Ptr to tns data */
+  AACPulseInfo pulseInfo;
+} AACQuantInfo;
+
+
+void PulseCoder(AACQuantInfo *quantInfo, int *quant);
+void PulseDecoder(AACQuantInfo *quantInfo, int *quant);
+int quantize(AACQuantInfo *quantInfo,
+			 double *p_spectrum,
+			 double *pow_spectrum,
+			 int quant[NUM_COEFF]
+			 );
+void dequantize(AACQuantInfo *quantInfo,
+				double *p_spectrum,
+				int quant[NUM_COEFF],
+				double requant[NUM_COEFF],
+				double error_energy[SFB_NUM_MAX]
+				);
+int count_bits(AACQuantInfo* quantInfo,
+			   int quant[NUM_COEFF],
+			   int output_book_vector[SFB_NUM_MAX*2]);
+
+
+/*********************************************************/
+/* tf_init_encode_spectrum_aac                           */
+/*********************************************************/
+void tf_init_encode_spectrum_aac( int quality );
+
+
+/*********************************************************/
+/* tf_encode_spectrum_aac                                */
+/*********************************************************/
+int tf_encode_spectrum_aac(
+			   double      *p_spectrum[MAX_TIME_CHANNELS],
+			   double      *SigMaksRatio[MAX_TIME_CHANNELS],
+			   double      allowed_dist[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   double      energy[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS],
+			   int         sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
+			   int         nr_of_sfb[MAX_TIME_CHANNELS],
+			   int         average_block_bits,
+			   int         available_bitreservoir_bits,
+			   int         padding_limit,
+			   BsBitStream *fixed_stream,
+			   BsBitStream *var_stream,
+			   int         nr_of_chan,
+			   double      *p_reconstructed_spectrum[MAX_TIME_CHANNELS],
+			   int         useShortWindows,
+			   int         aacAllowScalefacs,
+			   AACQuantInfo* quantInfo,      /* AAC quantization information */ 
+			   Ch_Info *ch_info,
+			   int varBitRate,
+			   int bitRate);
+
+
+/*********************************************************/
+/* sort_book_numbers                                     */
+/*********************************************************/
+int sort_book_numbers(AACQuantInfo* quantInfo,     /* Quantization information */
+		  int output_book_vector[],    /* Output codebook vector, formatted for bitstream */
+		  BsBitStream* fixed_stream,   /* Bitstream */
+		  int write_flag);             /* Write flag: 0 count, 1 write */
+
+
+/*********************************************************/
+/* sort_book_numbers                                     */
+/*********************************************************/
+int sort_for_grouping(AACQuantInfo* quantInfo,        /* ptr to quantization information */
+		      int sfb_width_table[],          /* Widths of single window */
+		      double *p_spectrum[],           /* Spectral values, noninterleaved */
+		      double *SigMaskRatio,
+		      double *PsySigMaskRatio);
+
+/*********************************************************/
+/* bit_search                                            */
+/*********************************************************/
+int bit_search(int quant[NUM_COEFF],  /* Quantized spectral values */
+               AACQuantInfo* quantInfo);       /* Quantization information */
+
+/*********************************************************/
+/* noiseless_bit_count                                   */
+/*********************************************************/
+int noiseless_bit_count(int quant[NUM_COEFF],
+			int hop,
+			int min_book_choice[112][3],
+			AACQuantInfo* quantInfo);         /* Quantization information */
+
+/*********************************************************/
+/* output_bits                                           */
+/*********************************************************/
+int output_bits(AACQuantInfo* quantInfo,
+		/*int huff[13][MAXINDEX][NUMINTAB],*/
+                int book,                /* codebook */
+		int quant[NUM_COEFF],		
+		int offset,
+		int length,
+		int write_flag);
+
+
+/*********************************************************/
+/* tf_init_decode_spectrum_aac                           */
+/*********************************************************/
+void tf_init_decode_spectrum_aac( long sampling_rate );
+
+/*********************************************************/
+/* tf_decode_spectrum_aac                                */
+/*********************************************************/
+int tf_decode_spectrum_aac(
+   double      *p_spectrum[MAX_TIME_CHANNELS],
+   int         block_type,
+   BsBitStream *fixed_stream,
+   BsBitStream *var_stream,
+   int         nr_of_chan,
+   int         bits_avail
+);
+
+
+/*********************************************************/
+/* find_grouping_bits                                    */
+/*********************************************************/
+int find_grouping_bits(int window_group_length[],
+		       int num_window_groups
+		       );
+
+/*********************************************************/
+/* write_scalefactor_bitstream                           */
+/*********************************************************/
+int write_scalefactor_bitstream(BsBitStream* fixed_stream,             /* Bitstream */  
+				int write_flag,                        /* Write flag */
+				AACQuantInfo* quantInfo);              /* Quantization information */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+++ b/aac_se_enc.c
@@ -1,0 +1,507 @@
+/*********************************************************************
+ *
+ * Module for writing/counting AAC syntactic elements
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * ADD   Alberto Duenas, TI <alberto@ndsuk.com>
+ * RG    Ralf Geiger,  FhG/IIS
+ * Changes:
+ * 07-jun-97   CL   Initial revision.
+ * 14-sep-97   CL   Modified WritePredictorData to actually write
+ *                  predictor data.  Still need to add resets.
+ * 20-oct-97   CL   Updated WriteTNSData to support TNS.
+ * 03-Dec-97   ADD  Addding the prediction reset
+ * 22-Jan-98   CL   Added support for CPE's and common windows.
+ * 07-Apr-98   RG   Added WriteLFE to write LFE channel element.
+ *
+**********************************************************************/
+
+#include <stdlib.h>
+#include "aac_se_enc.h"
+#include "aac_qc.h"
+
+int max_pred_sfb;
+
+/*****************************************************************************/
+/* WriteAACFillBits(...)                                                     */
+/* Write fill_elements to the bitstream.	                             */
+/* Number of bits written is LEN_SE_ID + FIL_COUNT_LEN + a multiple of 8.    */
+/* Return number of bits left over (less than 7 ).                           */
+/*****************************************************************************/
+int WriteAACFillBits(BsBitStream* ptrBs,  /* Pointer to bitstream */
+		     int numBits)         /* Number of bits needed to fill */
+{
+  int numberOfBitsLeft=numBits;
+
+  /* Need at least (LEN_SE_ID + LEN_F_CNT) bits for a fill_element */
+  int minNumberOfBits = LEN_SE_ID + LEN_F_CNT;
+  while (numberOfBitsLeft>=minNumberOfBits) {
+    int numberOfBytes;
+    int maxCount;
+
+    BsPutBit(ptrBs,ID_FIL,LEN_SE_ID);	/* Write fill_element ID */
+    numberOfBitsLeft-=minNumberOfBits;	/* Subtract for ID,count */
+
+    numberOfBytes=(int)(numberOfBitsLeft/LEN_BYTE);
+    maxCount = (1<<LEN_F_CNT) - 1;  /* Max count without escaping */
+
+    /* if we have less than maxCount bytes, write them now */
+    if (numberOfBytes<maxCount) {
+      int i;
+      BsPutBit(ptrBs,numberOfBytes,LEN_F_CNT);
+      for (i=0;i<numberOfBytes;i++) {
+	BsPutBit(ptrBs,0,LEN_BYTE);
+      }
+    /* otherwise, we need to write an escape count */
+    } else {
+      int maxEscapeCount,maxNumberOfBytes,escCount;
+      int i;
+      BsPutBit(ptrBs,maxCount,LEN_F_CNT);
+      maxEscapeCount = (1<<LEN_BYTE) - 1;  /* Max escape count */
+      maxNumberOfBytes = maxCount + maxEscapeCount;
+      numberOfBytes = (numberOfBytes > maxNumberOfBytes ) ?
+	(maxNumberOfBytes) : (numberOfBytes);
+      escCount = numberOfBytes - maxCount;
+      BsPutBit(ptrBs,escCount,LEN_BYTE);
+      for (i=0;i<numberOfBytes-1;i++) {
+	BsPutBit(ptrBs,0,LEN_BYTE);
+      }
+    }
+    numberOfBitsLeft -= LEN_BYTE*numberOfBytes;
+  }
+  return numberOfBitsLeft;
+}
+
+/*****************************************************************************/
+/* WriteSCE(...), write a single-channel element to the bitstream.           */
+/*****************************************************************************/
+int WriteSCE(AACQuantInfo* quantInfo,   /* AACQuantInfo structure */
+	     int tag,
+	     BsBitStream* fixedStream,  /* Pointer to bitstream */
+	     int writeFlag)             /* 1 means write, 0 means count only */
+{
+  int bit_count=0;
+
+  if (writeFlag) {
+    /* write ID_SCE, single_element_channel() identifier */
+    BsPutBit(fixedStream,ID_SCE,LEN_SE_ID);  
+
+    /* write the element_identifier_tag */
+    BsPutBit(fixedStream,tag,LEN_TAG);  
+  }
+ 
+  bit_count += LEN_SE_ID;
+  bit_count += LEN_TAG;
+  
+  /* Write an individual_channel_stream element */
+  bit_count += WriteICS(quantInfo,0,fixedStream,writeFlag);
+ 
+  return bit_count;
+}
+
+/*****************************************************************************/
+/* WriteLFE(...), write a lfe-channel element to the bitstream.              */
+/*****************************************************************************/
+int WriteLFE(AACQuantInfo* quantInfo,   /* AACQuantInfo structure */
+	     int tag,
+	     BsBitStream* fixedStream,  /* Pointer to bitstream */
+	     int writeFlag)             /* 1 means write, 0 means count only */
+{
+  int bit_count=0;
+  
+  if (writeFlag) {
+    /* write ID_LFE, lfe_element_channel() identifier */
+    BsPutBit(fixedStream,ID_LFE,LEN_SE_ID);  
+
+    /* write the element_identifier_tag */
+    BsPutBit(fixedStream,tag,LEN_TAG);  
+  }
+ 
+  bit_count += LEN_SE_ID;
+  bit_count += LEN_TAG;
+  
+  /* Write an individual_channel_stream element */
+  bit_count += WriteICS(quantInfo,0,fixedStream,writeFlag);
+ 
+  return bit_count;
+}
+
+
+/*****************************************************************************/
+/* WriteCPE(...), write a channel_pair_element to the bitstream.           */
+/*****************************************************************************/
+int WriteCPE(AACQuantInfo* quantInfoL,   /* AACQuantInfo structure, left */
+             AACQuantInfo* quantInfoR,   /* AACQuantInfo structure, right */
+	     int tag,
+	     int commonWindow,          /* common_window flag */
+	     MS_Info* ms_info,          /* MS stereo information */
+	     BsBitStream* fixedStream,  /* Pointer to bitstream */
+	     int writeFlag)             /* 1 means write, 0 means count only */
+{
+  int bit_count=0;
+
+  if (writeFlag) {
+    /* write ID_CPE, single_element_channel() identifier */
+    BsPutBit(fixedStream,ID_CPE,LEN_SE_ID);  
+
+    /* write the element_identifier_tag */
+    BsPutBit(fixedStream,tag,LEN_TAG);  /* Currently, this is zero */
+
+    /* common_window? */
+    BsPutBit(fixedStream,commonWindow,LEN_COM_WIN);
+  }
+ 
+  bit_count += LEN_SE_ID;
+  bit_count += LEN_TAG;
+  bit_count += LEN_COM_WIN;
+
+  /* if common_window, write ics_info */
+  if (commonWindow) {
+    int numWindows,maxSfb;
+    bit_count = WriteICSInfo(quantInfoL,fixedStream,writeFlag);
+    numWindows=quantInfoL->num_window_groups;
+    maxSfb = quantInfoL->max_sfb;
+    if (writeFlag) {
+      BsPutBit(fixedStream,ms_info->is_present,LEN_MASK_PRES);
+      if (ms_info->is_present==1) {
+	int g;
+	int b;
+	for (g=0;g<numWindows;g++) {
+	  for (b=0;b<maxSfb;b++) {
+	    BsPutBit(fixedStream,ms_info->ms_used[g*maxSfb+b],LEN_MASK);
+	  }
+	}
+      }
+    }
+    bit_count += LEN_MASK_PRES;
+    bit_count += (ms_info->is_present==1)*numWindows*maxSfb*LEN_MASK;
+  }
+  
+  /* Write individual_channel_stream elements */
+  bit_count += WriteICS(quantInfoL,commonWindow,fixedStream,writeFlag);
+  bit_count += WriteICS(quantInfoR,commonWindow,fixedStream,writeFlag);
+ 
+  return bit_count;
+}
+
+
+/*****************************************************************************/
+/* WriteICS(...), write an individual_channel_stream element to the bitstream.*/
+/*****************************************************************************/
+int WriteICS(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+	     int commonWindow,           /* Common window flag */
+	     BsBitStream* fixed_stream,  /* Pointer to bitstream */
+	     int writeFlag)              /* 1 means write, 0 means count only */
+{
+  /* this function writes out an individual_channel_stream to the bitstream and */
+  /* returns the number of bits written to the bitstream */
+  int bit_count = 0;
+  int output_book_vector[SFB_NUM_MAX*2];
+  writeFlag = ( writeFlag != 0 );
+
+  /* Write the 8-bit global_gain */
+  BsPutBit(fixed_stream,quantInfo->common_scalefac,writeFlag*LEN_GLOB_GAIN);  
+  bit_count += LEN_GLOB_GAIN;
+
+  /* Write ics information */
+  if (!commonWindow) {
+    bit_count += WriteICSInfo(quantInfo,fixed_stream,writeFlag);
+  }
+
+  /* Write section_data() information to the bitstream */
+  bit_count += sort_book_numbers(quantInfo,output_book_vector,fixed_stream,writeFlag);
+
+  /* Write scale_factor_data() information */
+  bit_count += write_scalefactor_bitstream(fixed_stream,writeFlag,quantInfo);
+
+  /* Write pulse_data() */
+  bit_count += WritePulseData(quantInfo,fixed_stream,writeFlag);
+
+  /* Write TNS data */
+  bit_count += WriteTNSData(quantInfo,fixed_stream,writeFlag);
+	
+  /* Write gain control data */
+  bit_count += WriteGainControlData(quantInfo,fixed_stream,writeFlag);
+
+  /* Write out spectral_data() */
+  bit_count += WriteSpectralData(quantInfo,fixed_stream,writeFlag);
+
+  /* Return number of bits */
+  return(bit_count);
+}
+
+
+/*****************************************************************************/
+/* WriteICSInfo(...), write individual_channel_stream information            */
+/*  to the bitstream.                                                        */
+/*****************************************************************************/
+int WriteICSInfo(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+		 BsBitStream* fixed_stream,  /* Pointer to bitstream */
+		 int writeFlag)              /* 1 means write, 0 means count only */
+{
+  int grouping_bits;
+  int max_sfb;
+  int bit_count = 0;
+
+  /* Compute number of scalefactor bands */
+//  if (quantInfo->max_sfb*quantInfo->num_window_groups != quantInfo->nr_of_sfb)
+    //CommonExit(-1,"Wrong number of scalefactorbands");
+  max_sfb =   quantInfo->max_sfb;
+
+  if (writeFlag) {
+    /* write out ics_info() information */
+    BsPutBit(fixed_stream,0,LEN_ICS_RESERV);  /* reserved Bit*/
+  
+    /* Write out window sequence */
+    BsPutBit(fixed_stream,quantInfo->block_type,LEN_WIN_SEQ);  /* short window */
+
+    /* Write out window shape */ 
+    BsPutBit(fixed_stream,quantInfo->window_shape,LEN_WIN_SH);  /* window shape */
+  }
+    
+  bit_count += LEN_ICS_RESERV;
+  bit_count += LEN_WIN_SEQ;
+  bit_count += LEN_WIN_SH;
+
+  /* For short windows, write out max_sfb and scale_factor_grouping */
+  if (quantInfo -> block_type == ONLY_SHORT_WINDOW){
+    if (writeFlag) {
+      BsPutBit(fixed_stream,max_sfb,LEN_MAX_SFBS); 
+      grouping_bits = find_grouping_bits(quantInfo->window_group_length,quantInfo->num_window_groups);
+      BsPutBit(fixed_stream,grouping_bits,MAX_SHORT_IN_LONG_BLOCK - 1);  /* the grouping bits */
+    }
+    bit_count += LEN_MAX_SFBS;
+    bit_count += MAX_SHORT_IN_LONG_BLOCK - 1;
+  }
+
+  /* Otherwise, write out max_sfb and predictor data */
+  else { /* block type is either start, stop, or long */
+    if (writeFlag) {
+      BsPutBit(fixed_stream,max_sfb,LEN_MAX_SFBL);
+    }
+    bit_count += LEN_MAX_SFBL;
+    bit_count += WritePredictorData(quantInfo,fixed_stream,writeFlag);
+  }
+
+  return bit_count;
+}
+
+
+/*****************************************************************************/
+/* WritePredictorData(...), write predictor data.                            */
+/*****************************************************************************/
+int WritePredictorData(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+		       BsBitStream* fixed_stream,  /* Pointer to bitstream */
+		       int writeFlag)              /* 1 means write, 0 means count only */  
+{
+	int bit_count = 0;
+
+	/* Write global predictor data present */
+	short predictorDataPresent = quantInfo->pred_global_flag;
+	int numBands = min(max_pred_sfb,quantInfo->nr_of_sfb);
+
+	if (writeFlag) {
+		BsPutBit(fixed_stream,predictorDataPresent,LEN_PRED_PRES);  /* predictor_data_present */
+		if (predictorDataPresent) {
+			int b;
+
+			/* Code segment added by JB */
+			if (quantInfo->reset_group_number == -1)
+				BsPutBit(fixed_stream,0,LEN_PRED_RST); /* No prediction reset */
+			else
+			{
+				BsPutBit(fixed_stream,1,LEN_PRED_RST);
+				BsPutBit(fixed_stream,(unsigned long)quantInfo->reset_group_number,
+					LEN_PRED_RSTGRP);
+			}
+			/* End of code segment */
+
+			for (b=0;b<numBands;b++) {
+				BsPutBit(fixed_stream,quantInfo->pred_sfb_flag[b],LEN_PRED_ENAB);
+			}
+		}
+	}
+	bit_count = LEN_PRED_PRES;
+	bit_count += (predictorDataPresent) ?
+		(LEN_PRED_RST + 
+		((quantInfo->reset_group_number)!=-1)*LEN_PRED_RSTGRP + 
+		numBands*LEN_PRED_ENAB) : 0;
+
+	return bit_count;
+}
+
+/*****************************************************************************/
+/* WritePulseData(...), write pulse data.                            */
+/*****************************************************************************/
+int WritePulseData(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+		   BsBitStream* fixed_stream,  /* Pointer to bitstream */
+		   int writeFlag)              /* 1 means write, 0 means count only */
+{
+	int i, bit_count = 0;
+
+	/* Currently write no pulse data present */
+	if (quantInfo->pulseInfo.pulse_data_present) {
+		if (writeFlag) {
+			BsPutBit(fixed_stream,1,LEN_PULSE_PRES);  /* no pulse_data_present */
+			BsPutBit(fixed_stream,quantInfo->pulseInfo.number_pulse,LEN_NEC_NPULSE);  /* no pulse_data_present */
+			BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_start_sfb,LEN_NEC_ST_SFB);  /* no pulse_data_present */
+		}
+		bit_count += LEN_NEC_NPULSE + LEN_NEC_ST_SFB;
+
+		for (i = 0; i < quantInfo->pulseInfo.number_pulse+1; i++) {
+			if (writeFlag) {
+				BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_offset[i],LEN_NEC_POFF);
+				BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_amp[i],LEN_NEC_PAMP);
+			}
+			bit_count += LEN_NEC_POFF + LEN_NEC_PAMP;
+		}
+	} else {
+		if (writeFlag) {
+			BsPutBit(fixed_stream,0,LEN_PULSE_PRES);  /* no pulse_data_present */
+		}
+	}
+	bit_count += LEN_PULSE_PRES;
+	return bit_count;
+}
+
+/*****************************************************************************/
+/* WriteTNSData(...), write TNS data.                            */
+/*****************************************************************************/
+int WriteTNSData(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+		 BsBitStream* fixed_stream,  /* Pointer to bitstream */
+		 int writeFlag)              /* 1 means write, 0 means count only */ 
+{
+  int bit_count = 0;
+  int numWindows = 1;
+  int len_tns_nfilt;
+  int len_tns_length;
+  int len_tns_order;
+  int filtNumber;
+  int resInBits;
+  int bitsToTransmit;
+  unsigned long unsignedIndex;
+  int w;
+
+  TNS_INFO* tnsInfoPtr = quantInfo->tnsInfo;
+
+  if (writeFlag) {
+    BsPutBit(fixed_stream,tnsInfoPtr->tnsDataPresent,LEN_TNS_PRES);
+  }
+  bit_count += LEN_TNS_PRES;
+
+  /* If TNS is not present, bail */
+  if (!tnsInfoPtr->tnsDataPresent) {
+    return bit_count;
+  }
+
+  /* Set window-dependent TNS parameters */
+  if (quantInfo->block_type == ONLY_SHORT_WINDOW) {
+    numWindows = MAX_SHORT_IN_LONG_BLOCK;
+    len_tns_nfilt = LEN_TNS_NFILTS;
+    len_tns_length = LEN_TNS_LENGTHS;
+    len_tns_order = LEN_TNS_ORDERS;
+  } else {
+    numWindows = 1;
+    len_tns_nfilt = LEN_TNS_NFILTL;
+    len_tns_length = LEN_TNS_LENGTHL;
+    len_tns_order = LEN_TNS_ORDERL;
+  }
+
+  /* Write TNS data */
+  bit_count += numWindows * len_tns_nfilt;
+  for (w=0;w<numWindows;w++) {
+    TNS_WINDOW_DATA* windowDataPtr = &tnsInfoPtr->windowData[w];
+    int numFilters = windowDataPtr->numFilters;
+    if (writeFlag) {
+      BsPutBit(fixed_stream,numFilters,len_tns_nfilt); /* n_filt[] = 0 */
+    }
+    if (numFilters) {
+      bit_count += LEN_TNS_COEFF_RES;
+      resInBits = windowDataPtr->coefResolution;
+      resInBits = windowDataPtr->coefResolution;
+      if (writeFlag) {
+	BsPutBit(fixed_stream,resInBits-DEF_TNS_RES_OFFSET,LEN_TNS_COEFF_RES);
+      }
+      bit_count += numFilters * (len_tns_length+len_tns_order);
+      for (filtNumber=0;filtNumber<numFilters;filtNumber++) {
+	TNS_FILTER_DATA* tnsFilterPtr=&windowDataPtr->tnsFilter[filtNumber];
+	int order = tnsFilterPtr->order;
+	if (writeFlag) {
+	  BsPutBit(fixed_stream,tnsFilterPtr->length,len_tns_length);
+	  BsPutBit(fixed_stream,order,len_tns_order);
+	}
+	if (order) {
+	  bit_count += (LEN_TNS_DIRECTION + LEN_TNS_COMPRESS);
+	  if (writeFlag) {
+	    BsPutBit(fixed_stream,tnsFilterPtr->direction,LEN_TNS_DIRECTION);
+	    BsPutBit(fixed_stream,tnsFilterPtr->coefCompress,LEN_TNS_COMPRESS);
+	  }
+          bitsToTransmit = resInBits - tnsFilterPtr->coefCompress;
+	  bit_count += order * bitsToTransmit;
+	  if (writeFlag) {
+	    int i;
+	    for (i=1;i<=order;i++) {
+	      unsignedIndex = (unsigned long) (tnsFilterPtr->index[i])&(~(~0<<bitsToTransmit));
+	      BsPutBit(fixed_stream,unsignedIndex,bitsToTransmit);
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return bit_count;
+}
+
+
+/*****************************************************************************/
+/* WriteGainControlData(...), write gain control data.                       */
+/*****************************************************************************/
+int WriteGainControlData(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+			 BsBitStream* fixed_stream,  /* Pointer to bitstream */
+			 int writeFlag)              /* 1 means write, 0 means count only */  
+{
+	int bit_count = 0;
+	bit_count += LEN_GAIN_PRES;
+
+	if (writeFlag) {
+		BsPutBit(fixed_stream,0,LEN_GAIN_PRES);
+	}
+	return bit_count;
+}
+
+
+/*****************************************************************************/
+/* WriteSpectralData(...), write spectral data.                              */
+/*****************************************************************************/
+int WriteSpectralData(AACQuantInfo* quantInfo,    /* AACQuantInfo structure */
+		      BsBitStream* fixed_stream,  /* Pointer to bitstream */
+		      int writeFlag)              /* 1 means write, 0 means count only */
+{
+	int bit_count = 0;
+	int numSpectral = quantInfo->spectralCount;
+
+	/* set up local pointers to data and len */
+	/* data array contains data to be written */
+	/* len array contains lengths of data words */
+	int* data = quantInfo -> data;
+	int* len = quantInfo -> len;
+
+	if (writeFlag) {
+		int i;
+		for(i=0;i<numSpectral;i++) {
+			if (len[i] > 0) {  /* only send out non-zero codebook data */
+				BsPutBit(fixed_stream,data[i],len[i]); /* write data */
+				bit_count += len[i];                   /* update bit_count */
+			}
+		}
+	} else {
+		int i;
+		for(i=0;i<numSpectral;i++) {
+			bit_count += len[i];              /* update bit_count */
+		}
+	}
+
+	return bit_count;
+}
+
--- /dev/null
+++ b/aac_se_enc.h
@@ -1,0 +1,138 @@
+/***********
+
+This software module was originally developed by Texas 
+Instruments in the course of development of the MPEG-2 NBC/MPEG-4 
+Audio standard ISO/IEC13818-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-2NBC/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, 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 the developer's 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 1996.  
+
+***********/
+/*********************************************************************
+ *
+ * Function prototypes for writing/counting AAC syntactic elements
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * RG    Ralf Geiger, FhG/IIS
+ *
+ * Changes:
+ * 07-jun-97   CL   Initial revision.
+ * 14-sep-97   CL   Updated WritePredictorData to support prediction.
+ * 20-oct-97   CL   Updated WriteTNSData to support TNS.
+ * 22-Jan-98   CL   Added support for CPE's and common windows.
+ * 07-Apr-98   RG   Added WriteLFE to write LFE channel element.
+ *
+**********************************************************************/
+
+
+#ifndef AAC_SE_ENC
+#define AAC_SE_ENC
+
+#include "interface.h"
+#include "bitstream.h"
+#include "all.h"
+#include "aac_qc.h"
+
+extern int max_pred_sfb;
+
+/*****************************************************************************/
+/* Write AAC fill bits to the bitStream                                      */
+/*****************************************************************************/
+int WriteAACFillBits(BsBitStream* ptrBs,  /* Pointer to bit stream */
+		     int numBits);        /* Number of bits neede to fill */
+
+/*****************************************************************************/
+/* WriteSCE(...), write a single-channel element to the bitstream.           */
+/*****************************************************************************/
+int WriteSCE(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+	     int tag,
+	     BsBitStream* fixedStream, /* Pointer to bitstream */
+	     int writeFlag);           /* 1 means write, 0 means count only */
+
+/*****************************************************************************/
+/* WriteLFE(...), write a lfe-channel element to the bitstream.              */
+/*****************************************************************************/
+int WriteLFE(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+	     int tag,
+	     BsBitStream* fixedStream, /* Pointer to bitstream */
+	     int writeFlag);           /* 1 means write, 0 means count only */
+
+/*****************************************************************************/
+/* WriteCPE(...), write a channel_pair_element to the bitstream.           */
+/*****************************************************************************/
+int WriteCPE(AACQuantInfo* quantInfoL,   /* AACQuantInfo structure, left */
+             AACQuantInfo* quantInfoR,   /* AACQuantInfo structure, right */
+	     int tag,
+	     int commonWindow,
+	     MS_Info* ms_info,
+	     BsBitStream* fixedStream,  /* Pointer to bitstream */
+	     int writeFlag);            /* 1 means write, 0 means count only */
+
+/*****************************************************************************/
+/* WriteICS(...), write an individual_channel_stream element to the bitstream.*/
+/*****************************************************************************/
+int WriteICS(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+	     int commonWindow,
+	     BsBitStream* fixedStream, /* Pointer to bitstream */
+	     int writeFlag);           /* 1 means write, 0 means count only */ 
+
+/*****************************************************************************/
+/* WriteICSInfo(...), write a individual_channel_stream information          */
+/*  to the bitstream.                                                        */
+/*****************************************************************************/
+int WriteICSInfo(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+		 BsBitStream* fixedStream, /* Pointer to bitstream */
+		 int writeFlag);           /* 1 means write, 0 means count only */
+
+
+/*****************************************************************************/
+/* WritePredictorData(...), write predictor data.                            */
+/*****************************************************************************/
+int WritePredictorData(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+		       BsBitStream* fixedStream, /* Pointer to bitstream */
+		       int writeFlag);           /* 1 means write, 0 means count only */   
+
+/*****************************************************************************/
+/* WritePulseData(...), write pulse data.                            */
+/*****************************************************************************/
+int WritePulseData(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+		   BsBitStream* fixedStream, /* Pointer to bitstream */
+		   int writeFlag);           /* 1 means write, 0 means count only */ 
+
+/*****************************************************************************/
+/* WriteTNSData(...), write TNS data.                            */
+/*****************************************************************************/
+int WriteTNSData(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+		 BsBitStream* fixedStream, /* Pointer to bitstream */
+		 int writeFlag);           /* 1 means write, 0 means count only */
+
+/*****************************************************************************/
+/* WriteGainControlData(...), write gain control data.                       */
+/*****************************************************************************/
+int WriteGainControlData(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+			 BsBitStream* fixedStream, /* Pointer to bitstream */
+			 int writeFlag);           /* 1 means write, 0 means count only */
+
+/*****************************************************************************/
+/* WriteSpectralData(...), write spectral data.                              */
+/*****************************************************************************/
+int WriteSpectralData(AACQuantInfo* quantInfo,  /* Pointer to AACQuantInfo structure */
+		      BsBitStream* fixedStream, /* Pointer to bitstream */
+		      int writeFlag);           /* 1 means write, 0 means count only */
+
+#endif
+
--- /dev/null
+++ b/aacenc.h
@@ -1,0 +1,143 @@
+
+
+#define MAIN_PROFILE 0
+#define LOW_PROFILE 1
+
+#define FNO_ERROR 0
+#define FERROR 1
+
+typedef struct {
+	int channels;      // Number of channels: Currently has to be 2
+	int sampling_rate; // Sampling rate
+	int bit_rate;      // Bitrate: can be: 64000, 80000, 96000, 112000, 128000, 160000
+	                   //    192000, 224000 or 256000
+	int profile;       // AAC Profile: can be MAIN_PROFILE or LOW_PROFILE
+	int write_header;  // If this is 1, a ADIF header will be written, if it is 0, no
+	                   //    header will be written. (better turn this on, because
+                       //    there is some bug when not using ADIF header)
+	int use_MS;        // If 1, MS stereo is on, if 0, it is off
+	int use_IS;        // If 1, IS stereo is on, if 0, it is off
+} faacAACConfig;
+
+// This structure is for internal use of the encoder only.
+typedef struct {
+	long total_bits;
+	long frames;
+	long cur_frame;
+	int is_first_frame;
+	int channels;
+	int sampling_rate;
+	int frame_bits;
+	int available_bits;
+	int write_header;
+	int use_MS;
+	int use_IS;
+	int profile;
+	float **inputBuffer;
+} faacAACStream;
+
+typedef struct {
+	int DLLMajorVersion; // These 2 values should always be checked, because the DLL
+	int DLLMinorVersion; // interface can change from version to version.
+	int MajorVersion;
+	int MinorVersion;
+	char HomePage[255];
+} faacVersion;
+
+#ifndef FAAC_DLL
+
+
+//
+// The main() function in encoder.c gives an example of how to use these functions
+//
+
+// faacAACStream* faacEncodeInit(faacAACConfig *ac, int *samplesToRead, int *bitBufferSize,
+//  int *headerSize);
+//
+// Purpose:
+//  Initializes the DLL.
+// Parameters:
+//  Input:
+//   ac: Completely filled faacAACConfig structure
+//  Output:
+//   samplesToRead: Number of samples that should be read before every call to faacEncodeFrame()
+//   bitBufferSize: Size of the buffer in bytes that should be initialized for writing
+//   headerSize: Size of the buffer in bytes that should be initialized for writing the header
+//               This number of bytes should be skipped in the file before writing any frames.
+//               Later, after calling faacAACFree() the headerBuf should be written to this space in the AAC file.
+// Return value:
+//  faacAACStream structure that should be used in calls to other functions
+typedef faacAACStream* (*FAACENCODEINIT) (faacAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize);
+
+
+// int faacEncodeFrame(faacAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer,
+//  int *bitBufSize);
+//
+// Purpose:
+//  Encodes a chunk of samples.
+// Parameters:
+//  Input:
+//   as: faacAACStream returned by faacEncodeInit()
+//   Buffer: Sample data from audio file
+//   Samples: Number of samples in buffer
+//  Output:
+//   bitBuffer: Output data that should be written to the AAC file.
+//   bitBufSize: Size of bitBuffer in bytes
+// Return value:
+//  FERROR or FNO_ERROR
+typedef int (*FAACENCODEFRAME) (faacAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize);
+
+
+// int faacEncodeFinish(faacAACStream *as, unsigned char *bitBuffer, int *bitBufSize);
+//
+// Purpose:
+//  Flushes the last pieces of data.
+// Parameters:
+//  Input:
+//   as: faacAACStream returned by faacEncodeInit()
+//  Output:
+//   bitBuffer: Output data that should be written to the AAC file.
+//   bitBufSize: Size of bitBuffer in bytes
+// Return value:
+//  FERROR or FNO_ERROR
+typedef int (*FAACENCODEFINISH) (faacAACStream *as, unsigned char *bitBuffer, int *bitBufSize);
+
+// int faacEncodeFree(faacAACStream *as, unsigned char *headerBuf);
+//
+// Purpose:
+//  Frees encoder memory and fills in headerBuf.
+// Parameters:
+//  Input:
+//   as: faacAACStream returned by faacEncodeInit()
+//  Output:
+//   headerBuf: Header data that should be written to the AAC file, size of 
+//         the data is headerSize returned by faacEncodeInit().
+// Return value:
+//  FERROR or FNO_ERROR
+typedef int (*FAACENCODEFREE) (faacAACStream *as, unsigned char *headerBuf);
+
+
+// int faacEncodeVersion(void);
+//
+// Purpose:
+//  Gives version information from the DLL.
+// Return value:
+//  Filled in faacVersion structure
+typedef faacVersion* (*FAACENCODEVERSION) (void);
+
+#define TEXT_FAACENCODEINIT    "faacEncodeInit"
+#define TEXT_FAACENCODEFRAME   "faacEncodeFrame"
+#define TEXT_FAACENCODEFINISH  "faacEncodeFinish"
+#define TEXT_FAACENCODEFREE    "faacEncodeFree"
+#define TEXT_FAACENCODEVERSION "faacEncodeVersion"
+
+#else
+
+__declspec(dllexport) faacAACStream *faacEncodeInit(faacAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize);
+__declspec(dllexport) int faacEncodeFrame(faacAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize);
+__declspec(dllexport) int faacEncodeFree(faacAACStream *as, unsigned char *headerBuf);
+__declspec(dllexport) int faacEncodeFinish(faacAACStream *as, unsigned char *bitBuffer, int *bitBufSize);
+__declspec(dllexport) faacVersion *faacEncodeVersion(void);
+
+#endif
+
--- /dev/null
+++ b/all.h
@@ -1,0 +1,64 @@
+/************************* 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.
+ *                                                                           *
+ ****************************************************************************/
+
+#ifndef	_all_h_
+#define _all_h_
+
+#include "interface.h"
+#include "tns.h"
+#include "bitstream.h"
+
+
+typedef struct
+{
+    int is_present;	/* right channel uses intensiy stereo */
+    int is_used[MAXBANDS];
+    int sign[2*(MAXBANDS+1)];
+    int fac[2*(MAXBANDS+1)];
+    int bot[2*(MAXBANDS+1)];
+    int top[2*(MAXBANDS+1)];
+} IS_Info;
+
+typedef struct
+{
+    int is_present;  
+    int ms_used[MAXBANDS];
+} MS_Info;
+
+typedef struct
+{
+    int present;	/* channel present */
+    int tag;		/* element tag */
+    int cpe;		/* 0 if single channel or lfe, 1 if channel pair */ 
+    int lfe;            /* 1 if lfe channel */             
+    int	common_window;	/* 1 if common window for cpe */
+    int	ch_is_left;	/* 1 if left channel of cpe */
+    int	paired_ch;	/* index of paired channel in cpe */
+    int widx;		/* window element index for this channel */
+    IS_Info is_info;	/* IS information */
+    MS_Info ms_info;    /* MS information */
+} Ch_Info;
+
+#endif	/* _all_h_ */
+
--- /dev/null
+++ b/bitstream.c
@@ -1,0 +1,99 @@
+
+/* Heavily modified since it is now only used to write bits to a buffer. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bitstream.h"		/* bit stream module */
+
+
+#define BYTE_NUMBIT 8		/* bits in byte (char) */
+#define LONG_NUMBIT 32		/* bits in unsigned long */
+#define bit2byte(a) (((a)+BYTE_NUMBIT-1)/BYTE_NUMBIT)
+#define byte2bit(a) ((a)*BYTE_NUMBIT)
+
+
+BsBitStream *BsOpenWrite(int size)
+{
+	BsBitStream *bs;
+
+	bs = malloc(sizeof(BsBitStream));
+	bs->size = size;
+	bs->numBit = 0;
+	bs->currentBit = 0;
+	bs->data = malloc(bit2byte(size));
+
+	return bs;
+}
+
+void BsClose(BsBitStream *bs)
+{
+	free(bs->data);
+	free(bs);
+}
+
+long BsBufferNumBit (BsBitStream *bs)
+{
+	return bs->numBit;
+}
+
+int BsWriteByte (BsBitStream *stream,
+				 unsigned long data,
+				 int numBit)
+{
+	long numUsed,idx;
+
+	idx = (stream->currentBit / BYTE_NUMBIT) % bit2byte(stream->size);
+	numUsed = stream->currentBit % BYTE_NUMBIT;
+	if (numUsed == 0)
+		stream->data[idx] = 0;
+	stream->data[idx] |= (data & ((1<<numBit)-1)) <<
+		(BYTE_NUMBIT-numUsed-numBit);
+	stream->currentBit += numBit;
+	stream->numBit = stream->currentBit;
+
+	return 0;
+}
+
+int BsPutBit (BsBitStream *stream,
+			  unsigned long data,
+			  int numBit)
+{
+	int num,maxNum,curNum;
+	unsigned long bits;
+
+	if (numBit == 0)
+		return 0;
+
+	/* write bits in packets according to buffer byte boundaries */
+	num = 0;
+	maxNum = BYTE_NUMBIT - stream->currentBit % BYTE_NUMBIT;
+	while (num < numBit) {
+		curNum = min(numBit-num,maxNum);
+		bits = data>>(numBit-num-curNum);
+		if (BsWriteByte(stream,bits,curNum)) {
+			return 1;
+		}
+		num += curNum;
+		maxNum = BYTE_NUMBIT;
+	}
+
+	return 0;
+}
+
+int ByteAlign(BsBitStream* ptrBs)
+{
+	int len, i,j;
+	len = BsBufferNumBit( ptrBs );
+	   
+	j = (8 - (len%8))%8;
+
+	if ((len % 8) == 0) j = 0;
+	for( i=0; i<j; i++ ) {
+		BsPutBit( ptrBs, 0, 1 ); 
+	}
+	return j;
+}
+
+
--- /dev/null
+++ b/bitstream.h
@@ -1,0 +1,40 @@
+
+#ifndef _bitstream_h_
+#define _bitstream_h_
+
+#ifndef min
+#define min(a,b) ( (a) < (b) ? (a) : (b) )
+#endif
+#ifndef max
+#define max(a,b) ( (a) > (b) ? (a) : (b) )
+#endif
+
+typedef struct _bitstream
+{
+  unsigned char *data;		/* data bits */
+  long numBit;			/* number of bits in buffer */
+  long size;			/* buffer size in bits */
+  long currentBit;		/* current bit position in bit stream */
+  long numByte;			/* number of bytes read/written (only file) */
+} BsBitStream;
+
+
+BsBitStream *BsOpenWrite(int size);
+
+void BsClose(BsBitStream *bs);
+
+long BsBufferNumBit (BsBitStream *bs);
+
+int BsWriteByte (BsBitStream *stream,
+				 unsigned long data,
+				 int numBit);
+
+int BsPutBit (BsBitStream *stream,
+			  unsigned long data,
+			  int numBit);
+
+/* ByteAlign(...), used to byte align bitstream */
+int ByteAlign(BsBitStream* ptrBs);
+
+#endif
+
--- /dev/null
+++ b/block.h
@@ -1,0 +1,107 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+"This software module was originally developed by 
+AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS 
+and edited by Takashi Koike (Sony Corporation),
+Yasuhiro Toguri(Sony Corporation) 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.
+ *                                                                           *
+ ****************************************************************************/
+#ifndef BLOCK_H
+#define BLOCK_H 1
+
+#include "transfo.h"
+#include "dolby_def.h"
+
+
+#define IN_DATATYPE  double
+#define OUT_DATATYPE double
+
+#define BLOCK_LEN_LONG	   1024
+#define BLOCK_LEN_MEDIUM   512
+#define BLOCK_LEN_SHORT    128
+#define BLOCK_LEN_LONG_S   960
+#define BLOCK_LEN_MEDIUM_S 480
+#define BLOCK_LEN_SHORT_S  120
+#define BLOCK_LEN_LONG_SSR	  256 /* 980129 added for SSR */
+#define BLOCK_LEN_SHORT_SSR   32  /* 980129 added for SSR */
+
+#define NWINLONG	(BLOCK_LEN_LONG)
+#define ALFALONG	4.0
+#define NWINSHORT	(BLOCK_LEN_SHORT)
+#define ALFASHORT	7.0
+
+#define	NWINFLAT	(NWINLONG)					/* flat params */
+#define	NWINADV		(NWINLONG-NWINSHORT)		/* Advanced flat params */
+#define NFLAT		((NWINFLAT-NWINSHORT)/2)
+#define NADV0		((NWINADV-NWINSHORT)/2)
+
+
+typedef enum {
+    WS_FHG, WS_DOLBY, N_WINDOW_SHAPES
+} 
+Window_shape;
+
+/* YT 970615 for Son_PP  */
+typedef enum {
+	MOVERLAPPED,
+	MNON_OVERLAPPED
+}
+Mdct_in,Imdct_out;
+
+typedef enum {
+    WT_LONG, 
+    WT_SHORT, 
+    WT_FLAT, 
+    WT_ADV,			/* Advanced flat window */
+    N_WINDOW_TYPES
+} 
+WINDOW_TYPE_AAC; 
+
+typedef enum {                  /* ADVanced transform types */
+    LONG_BLOCK,
+    START_BLOCK,
+    SHORT_BLOCK,
+    STOP_BLOCK,
+    START_ADV_BLOCK,
+    STOP_ADV_BLOCK,
+    START_FLAT_BLOCK,
+    STOP_FLAT_BLOCK,
+    N_BLOCK_TYPES
+} 
+BLOCK_TYPE;
+
+typedef enum {  		/* Advanced window sequence (frame) types */
+    ONLY_LONG,
+    LONG_START, 
+    LONG_STOP,
+    SHORT_START, 
+    SHORT_STOP,
+    EIGHT_SHORT, 
+    SHORT_EXT_STOP,
+    NINE_SHORT,
+    OLD_START,
+    OLD_STOP,
+    N_WINDOW_SEQUENCES
+} 
+WINDOW_SEQUENCE;
+
+
+#endif	/*	BLOCK_H	*/
+
--- /dev/null
+++ b/dolby_def.h
@@ -1,0 +1,42 @@
+/************************* 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.
+ *                                                                           *
+ ****************************************************************************/
+
+#include "block.h"
+#define MAX_NCHANNELS 7
+
+#ifdef DOUBLE_WIN_XXX
+
+extern Window_shape window_shape [MAX_NCHANNELS];
+void selectWindowShape (double *sws_buf, int winlen, int sws_chan, int sws_block_type);
+
+#else
+
+#endif	/* DOUBLE_WIN	*/
+
+
+#ifdef MFDBG
+void plot_ary (double *, int, int, double, double, char *);
+void plot_fary (float *, int, int, double, double, char *);
+#endif
+
--- /dev/null
+++ b/dolby_win.h
@@ -1,0 +1,1191 @@
+/*******************************************************************************
+*                                                                              *
+* Interface between the MPEG-4 Audio VM and the ITU-T G.729 8 kbit/s decoder   *
+*                                                                              *
+********************************************************************************
+
+This software module was originally developed by
+Bernhard Grill (University of Erlangen) 
+in the course of development of the MPEG-4 Audio (ISO/IEC 14496-3).
+This software module is an implementation of a part of one or more MPEG-4 Audio
+(ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio (ISO/IEC 14496-3).
+ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC 14496-3) free license to this
+software module or modifications thereof for use in hardware or software
+products claiming conformance to the MPEG-4 Audio (ISO/IEC 14496-3).
+Those intending to use this software module in hardware or software products are
+advised that its 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-4 Audio (ISO/IEC 14496-3) conforming
+products.
+The original developers retain full right to use the code for his/her own
+purpose, assign or donate the code to a third party and to inhibit third parties
+from using the code for non MPEG-4 Audio (ISO/IEC 14496-3) conforming products.
+This copyright notice must be included in all copies or derivative works.
+Copyright (C) 1997.
+*/
+#ifndef _DOLBY_WIN_H_
+#define _DOLBY_WIN_H_
+
+double dolby_win_1024[1024] = {  /* IBLEN = 1024 */
+  0.00029256153896361,
+  0.00042998567353047,
+  0.00054674074589540,
+  0.00065482304299792,
+  0.00075870195068747,
+  0.00086059331713336,
+  0.00096177541439010,
+  0.0010630609410878,
+  0.0011650036308132,
+  0.0012680012194148,
+  0.0013723517232956,
+  0.0014782864109136,
+  0.0015859901976719,
+  0.0016956148252373,
+  0.0018072876903517,
+  0.0019211179405514,
+  0.0020372007924215,
+  0.0021556206591754,
+  0.0022764534599614,
+  0.0023997683540995,
+  0.0025256290631156,
+  0.0026540948920831,
+  0.0027852215281403,
+  0.0029190616715331,
+  0.0030556655443223,
+  0.0031950812943391,
+  0.0033373553240392,
+  0.0034825325586930,
+  0.0036306566699199,
+  0.0037817702604646,
+  0.0039359150179719,
+  0.0040931318437260,
+  0.0042534609610026,
+  0.0044169420066964,
+  0.0045836141091341,
+  0.0047535159544086,
+  0.0049266858431214,
+  0.0051031617390698,
+  0.0052829813111335,
+  0.0054661819693975,
+  0.0056528008963682,
+  0.0058428750739943,
+  0.0060364413070882,
+  0.0062335362436492,
+  0.0064341963925079,
+  0.0066384581386503,
+  0.0068463577565218,
+  0.0070579314215715,
+  0.0072732152202559,
+  0.0074922451586909,
+  0.0077150571701162,
+  0.0079416871213115,
+  0.0081721708180857,
+  0.0084065440099458,
+  0.0086448423940363,
+  0.0088871016184291,
+  0.0091333572848345,
+  0.0093836449507939,
+  0.0096380001314086,
+  0.0098964583006517,
+  0.010159054892306,
+  0.010425825300561,
+  0.010696804880310,
+  0.010972028947167,
+  0.011251532777236,
+  0.011535351606646,
+  0.011823520630897,
+  0.012116075003993,
+  0.012413049837429,
+  0.012714480198999,
+  0.013020401111478,
+  0.013330847551161,
+  0.013645854446288,
+  0.013965456675352,
+  0.014289689065314,
+  0.014618586389712,
+  0.014952183366697,
+  0.015290514656976,
+  0.015633614861688,
+  0.015981518520214,
+  0.016334260107915,
+  0.016691874033817,
+  0.017054394638241,
+  0.017421856190380,
+  0.017794292885832,
+  0.018171738844085,
+  0.018554228105962,
+  0.018941794631032,
+  0.019334472294980,
+  0.019732294886947,
+  0.020135296106839,
+  0.020543509562604,
+  0.020956968767488,
+  0.021375707137257,
+  0.021799757987407,
+  0.022229154530343,
+  0.022663929872540,
+  0.023104117011689,
+  0.023549748833816,
+  0.024000858110398,
+  0.024457477495451,
+  0.024919639522613,
+  0.025387376602207,
+  0.025860721018295,
+  0.026339704925726,
+  0.026824360347160,
+  0.027314719170100,
+  0.027810813143900,
+  0.028312673876775,
+  0.028820332832801,
+  0.029333821328905,
+  0.029853170531859,
+  0.030378411455255,
+  0.030909574956490,
+  0.031446691733739,
+  0.031989792322926,
+  0.032538907094693,
+  0.033094066251369,
+  0.033655299823935,
+  0.034222637668991,
+  0.034796109465717,
+  0.035375744712844,
+  0.035961572725616,
+  0.036553622632758,
+  0.037151923373446,
+  0.037756503694277,
+  0.038367392146243,
+  0.038984617081711,
+  0.039608206651398,
+  0.040238188801359,
+  0.040874591269976,
+  0.041517441584950,
+  0.042166767060301,
+  0.042822594793376,
+  0.043484951661852,
+  0.044153864320760,
+  0.044829359199509,
+  0.045511462498913,
+  0.046200200188234,
+  0.046895598002228,
+  0.047597681438201,
+  0.048306475753074,
+  0.049022005960455,
+  0.049744296827725,
+  0.050473372873129,
+  0.051209258362879,
+  0.051951977308273,
+  0.052701553462813,
+  0.053458010319350,
+  0.054221371107223,
+  0.054991658789428,
+  0.055768896059787,
+  0.056553105340134,
+  0.057344308777513,
+  0.058142528241393,
+  0.058947785320893,
+  0.059760101322019,
+  0.060579497264926,
+  0.061405993881180,
+  0.062239611611049,
+  0.063080370600799,
+  0.063928290700012,
+  0.064783391458919,
+  0.065645692125747,
+  0.066515211644086,
+  0.067391968650269,
+  0.068275981470777,
+  0.069167268119652,
+  0.070065846295935,
+  0.070971733381121,
+  0.071884946436630,
+  0.072805502201299,
+  0.073733417088896,
+  0.074668707185649,
+  0.075611388247794,
+  0.076561475699152,
+  0.077518984628715,
+  0.078483929788261,
+  0.079456325589986,
+  0.080436186104162,
+  0.081423525056808,
+  0.082418355827392,
+  0.083420691446553,
+  0.084430544593841,
+  0.085447927595483,
+  0.086472852422178,
+  0.087505330686900,
+  0.088545373642744,
+  0.089592992180780,
+  0.090648196827937,
+  0.091710997744919,
+  0.092781404724131,
+  0.093859427187640,
+  0.094945074185163,
+  0.096038354392069,
+  0.097139276107423,
+  0.098247847252041,
+  0.099364075366580,
+  0.10048796760965,
+  0.10161953075597,
+  0.10275877119451,
+  0.10390569492671,
+  0.10506030756469,
+  0.10622261432949,
+  0.10739262004941,
+  0.10857032915821,
+  0.10975574569357,
+  0.11094887329534,
+  0.11214971520402,
+  0.11335827425914,
+  0.11457455289772,
+  0.11579855315274,
+  0.11703027665170,
+  0.11826972461510,
+  0.11951689785504,
+  0.12077179677383,
+  0.12203442136263,
+  0.12330477120008,
+  0.12458284545102,
+  0.12586864286523,
+  0.12716216177615,
+  0.12846340009971,
+  0.12977235533312,
+  0.13108902455375,
+  0.13241340441801,
+  0.13374549116025,
+  0.13508528059173,
+  0.13643276809961,
+  0.13778794864595,
+  0.13915081676677,
+  0.14052136657114,
+  0.14189959174027,
+  0.14328548552671,
+  0.14467904075349,
+  0.14608024981336,
+  0.14748910466804,
+  0.14890559684750,
+  0.15032971744929,
+  0.15176145713790,
+  0.15320080614414,
+  0.15464775426459,
+  0.15610229086100,
+  0.15756440485987,
+  0.15903408475193,
+  0.16051131859170,
+  0.16199609399712,
+  0.16348839814917,
+  0.16498821779156,
+  0.16649553923042,
+  0.16801034833404,
+  0.16953263053270,
+  0.17106237081842,
+  0.17259955374484,
+  0.17414416342714,
+  0.17569618354193,
+  0.17725559732720,
+  0.17882238758238,
+  0.18039653666830,
+  0.18197802650733,
+  0.18356683858343,
+  0.18516295394233,
+  0.18676635319174,
+  0.18837701650148,
+  0.18999492360384,
+  0.19162005379380,
+  0.19325238592940,
+  0.19489189843209,
+  0.19653856928714,
+  0.19819237604409,
+  0.19985329581721,
+  0.20152130528605,
+  0.20319638069594,
+  0.20487849785865,
+  0.20656763215298,
+  0.20826375852540,
+  0.20996685149083,
+  0.21167688513330,
+  0.21339383310678,
+  0.21511766863598,
+  0.21684836451719,
+  0.21858589311922,
+  0.22033022638425,
+  0.22208133582887,
+  0.22383919254503,
+  0.22560376720111,
+  0.22737503004300,
+  0.22915295089517,
+  0.23093749916189,
+  0.23272864382838,
+  0.23452635346201,
+  0.23633059621364,
+  0.23814133981883,
+  0.23995855159925,
+  0.24178219846403,
+  0.24361224691114,
+  0.24544866302890,
+  0.24729141249740,
+  0.24914046059007,
+  0.25099577217522,
+  0.25285731171763,
+  0.25472504328019,
+  0.25659893052556,
+  0.25847893671788,
+  0.26036502472451,
+  0.26225715701781,
+  0.26415529567692,
+  0.26605940238966,
+  0.26796943845439,
+  0.26988536478190,
+  0.27180714189742,
+  0.27373472994256,
+  0.27566808867736,
+  0.27760717748238,
+  0.27955195536071,
+  0.28150238094021,
+  0.28345841247557,
+  0.28542000785059,
+  0.28738712458038,
+  0.28935971981364,
+  0.29133775033492,
+  0.29332117256704,
+  0.29530994257338,
+  0.29730401606034,
+  0.29930334837974,
+  0.30130789453132,
+  0.30331760916521,
+  0.30533244658452,
+  0.30735236074785,
+  0.30937730527195,
+  0.31140723343430,
+  0.31344209817583,
+  0.31548185210356,
+  0.31752644749341,
+  0.31957583629288,
+  0.32162997012390,
+  0.32368880028565,
+  0.32575227775738,
+  0.32782035320134,
+  0.32989297696566,
+  0.33197009908736,
+  0.33405166929523,
+  0.33613763701295,
+  0.33822795136203,
+  0.34032256116495,
+  0.34242141494820,
+  0.34452446094547,
+  0.34663164710072,
+  0.34874292107143,
+  0.35085823023181,
+  0.35297752167598,
+  0.35510074222129,
+  0.35722783841160,
+  0.35935875652060,
+  0.36149344255514,
+  0.36363184225864,
+  0.36577390111444,
+  0.36791956434930,
+  0.37006877693676,
+  0.37222148360070,
+  0.37437762881878,
+  0.37653715682603,
+  0.37870001161834,
+  0.38086613695607,
+  0.38303547636766,
+  0.38520797315322,
+  0.38738357038821,
+  0.38956221092708,
+  0.39174383740701,
+  0.39392839225157,
+  0.39611581767449,
+  0.39830605568342,
+  0.40049904808370,
+  0.40269473648218,
+  0.40489306229101,
+  0.40709396673153,
+  0.40929739083810,
+  0.41150327546197,
+  0.41371156127524,
+  0.41592218877472,
+  0.41813509828594,
+  0.42035022996702,
+  0.42256752381274,
+  0.42478691965848,
+  0.42700835718423,
+  0.42923177591866,
+  0.43145711524314,
+  0.43368431439580,
+  0.43591331247564,
+  0.43814404844658,
+  0.44037646114161,
+  0.44261048926688,
+  0.44484607140589,
+  0.44708314602359,
+  0.44932165147057,
+  0.45156152598727,
+  0.45380270770813,
+  0.45604513466581,
+  0.45828874479543,
+  0.46053347593880,
+  0.46277926584861,
+  0.46502605219277,
+  0.46727377255861,
+  0.46952236445718,
+  0.47177176532752,
+  0.47402191254100,
+  0.47627274340557,
+  0.47852419517009,
+  0.48077620502869,
+  0.48302871012505,
+  0.48528164755674,
+  0.48753495437962,
+  0.48978856761212,
+  0.49204242423966,
+  0.49429646121898,
+  0.49655061548250,
+  0.49880482394273,
+  0.50105902349665,
+  0.50331315103004,
+  0.50556714342194,
+  0.50782093754901,
+  0.51007447028990,
+  0.51232767852971,
+  0.51458049916433,
+  0.51683286910489,
+  0.51908472528213,
+  0.52133600465083,
+  0.52358664419420,
+  0.52583658092832,
+  0.52808575190648,
+  0.53033409422367,
+  0.53258154502092,
+  0.53482804148974,
+  0.53707352087652,
+  0.53931792048690,
+  0.54156117769021,
+  0.54380322992385,
+  0.54604401469766,
+  0.54828346959835,
+  0.55052153229384,
+  0.55275814053768,
+  0.55499323217338,
+  0.55722674513883,
+  0.55945861747062,
+  0.56168878730842,
+  0.56391719289930,
+  0.56614377260214,
+  0.56836846489188,
+  0.57059120836390,
+  0.57281194173835,
+  0.57503060386439,
+  0.57724713372458,
+  0.57946147043912,
+  0.58167355327012,
+  0.58388332162591,
+  0.58609071506528,
+  0.58829567330173,
+  0.59049813620770,
+  0.59269804381879,
+  0.59489533633802,
+  0.59708995413996,
+  0.59928183777495,
+  0.60147092797329,
+  0.60365716564937,
+  0.60584049190582,
+  0.60802084803764,
+  0.61019817553632,
+  0.61237241609393,
+  0.61454351160718,
+  0.61671140418155,
+  0.61887603613527,
+  0.62103735000336,
+  0.62319528854167,
+  0.62534979473088,
+  0.62750081178042,
+  0.62964828313250,
+  0.63179215246597,
+  0.63393236370030,
+  0.63606886099946,
+  0.63820158877577,
+  0.64033049169379,
+  0.64245551467413,
+  0.64457660289729,
+  0.64669370180740,
+  0.64880675711607,
+  0.65091571480603,
+  0.65302052113494,
+  0.65512112263906,
+  0.65721746613689,
+  0.65930949873289,
+  0.66139716782102,
+  0.66348042108842,
+  0.66555920651892,
+  0.66763347239664,
+  0.66970316730947,
+  0.67176824015260,
+  0.67382864013196,
+  0.67588431676768,
+  0.67793521989751,
+  0.67998129968017,
+  0.68202250659876,
+  0.68405879146403,
+  0.68609010541774,
+  0.68811639993588,
+  0.69013762683195,
+  0.69215373826012,
+  0.69416468671849,
+  0.69617042505214,
+  0.69817090645634,
+  0.70016608447958,
+  0.70215591302664,
+  0.70414034636163,
+  0.70611933911096,
+  0.70809284626630,
+  0.71006082318751,
+  0.71202322560554,
+  0.71398000962530,
+  0.71593113172842,
+  0.71787654877613,
+  0.71981621801195,
+  0.72175009706445,
+  0.72367814394990,
+  0.72560031707496,
+  0.72751657523927,
+  0.72942687763803,
+  0.73133118386457,
+  0.73322945391280,
+  0.73512164817975,
+  0.73700772746796,
+  0.73888765298787,
+  0.74076138636020,
+  0.74262888961827,
+  0.74449012521027,
+  0.74634505600152,
+  0.74819364527663,
+  0.75003585674175,
+  0.75187165452661,
+  0.75370100318668,
+  0.75552386770515,
+  0.75734021349500,
+  0.75915000640095,
+  0.76095321270137,
+  0.76274979911019,
+  0.76453973277875,
+  0.76632298129757,
+  0.76809951269819,
+  0.76986929545481,
+  0.77163229848604,
+  0.77338849115651,
+  0.77513784327849,
+  0.77688032511340,
+  0.77861590737340,
+  0.78034456122283,
+  0.78206625827961,
+  0.78378097061667,
+  0.78548867076330,
+  0.78718933170643,
+  0.78888292689189,
+  0.79056943022564,
+  0.79224881607494,
+  0.79392105926949,
+  0.79558613510249,
+  0.79724401933170,
+  0.79889468818046,
+  0.80053811833858,
+  0.80217428696334,
+  0.80380317168028,
+  0.80542475058405,
+  0.80703900223920,
+  0.80864590568089,
+  0.81024544041560,
+  0.81183758642175,
+  0.81342232415032,
+  0.81499963452540,
+  0.81656949894467,
+  0.81813189927991,
+  0.81968681787738,
+  0.82123423755821,
+  0.82277414161874,
+  0.82430651383076,
+  0.82583133844180,
+  0.82734860017528,
+  0.82885828423070,
+  0.83036037628369,
+  0.83185486248609,
+  0.83334172946597,
+  0.83482096432759,
+  0.83629255465130,
+  0.83775648849344,
+  0.83921275438615,
+  0.84066134133716,
+  0.84210223882952,
+  0.84353543682130,
+  0.84496092574524,
+  0.84637869650833,
+  0.84778874049138,
+  0.84919104954855,
+  0.85058561600677,
+  0.85197243266520,
+  0.85335149279457,
+  0.85472279013653,
+  0.85608631890295,
+  0.85744207377513,
+  0.85879004990298,
+  0.86013024290422,
+  0.86146264886346,
+  0.86278726433124,
+  0.86410408632306,
+  0.86541311231838,
+  0.86671434025950,
+  0.86800776855046,
+  0.86929339605590,
+  0.87057122209981,
+  0.87184124646433,
+  0.87310346938840,
+  0.87435789156650,
+  0.87560451414719,
+  0.87684333873173,
+  0.87807436737261,
+  0.87929760257204,
+  0.88051304728038,
+  0.88172070489456,
+  0.88292057925645,
+  0.88411267465117,
+  0.88529699580537,
+  0.88647354788545,
+  0.88764233649580,
+  0.88880336767692,
+  0.88995664790351,
+  0.89110218408260,
+  0.89223998355154,
+  0.89337005407600,
+  0.89449240384793,
+  0.89560704148345,
+  0.89671397602074,
+  0.89781321691786,
+  0.89890477405053,
+  0.89998865770993,
+  0.90106487860034,
+  0.90213344783689,
+  0.90319437694315,
+  0.90424767784873,
+  0.90529336288690,
+  0.90633144479201,
+  0.90736193669708,
+  0.90838485213119,
+  0.90940020501694,
+  0.91040800966776,
+  0.91140828078533,
+  0.91240103345685,
+  0.91338628315231,
+  0.91436404572173,
+  0.91533433739238,
+  0.91629717476594,
+  0.91725257481564,
+  0.91820055488334,
+  0.91914113267664,
+  0.92007432626589,
+  0.92100015408120,
+  0.92191863490944,
+  0.92282978789113,
+  0.92373363251740,
+  0.92463018862687,
+  0.92551947640245,
+  0.92640151636824,
+  0.92727632938624,
+  0.92814393665320,
+  0.92900435969727,
+  0.92985762037477,
+  0.93070374086684,
+  0.93154274367610,
+  0.93237465162328,
+  0.93319948784382,
+  0.93401727578443,
+  0.93482803919967,
+  0.93563180214841,
+  0.93642858899043,
+  0.93721842438279,
+  0.93800133327637,
+  0.93877734091223,
+  0.93954647281807,
+  0.94030875480458,
+  0.94106421296182,
+  0.94181287365556,
+  0.94255476352362,
+  0.94328990947213,
+  0.94401833867184,
+  0.94474007855439,
+  0.94545515680855,
+  0.94616360137644,
+  0.94686544044975,
+  0.94756070246592,
+  0.94824941610434,
+  0.94893161028248,
+  0.94960731415209,
+  0.95027655709525,
+  0.95093936872056,
+  0.95159577885924,
+  0.95224581756115,
+  0.95288951509097,
+  0.95352690192417,
+  0.95415800874314,
+  0.95478286643320,
+  0.95540150607863,
+  0.95601395895871,
+  0.95662025654373,
+  0.95722043049100,
+  0.95781451264084,
+  0.95840253501260,
+  0.95898452980058,
+  0.95956052937008,
+  0.96013056625336,
+  0.96069467314557,
+  0.96125288290073,
+  0.96180522852773,
+  0.96235174318622,
+  0.96289246018262,
+  0.96342741296604,
+  0.96395663512424,
+  0.96448016037959,
+  0.96499802258499,
+  0.96551025571985,
+  0.96601689388602,
+  0.96651797130376,
+  0.96701352230768,
+  0.96750358134269,
+  0.96798818295998,
+  0.96846736181297,
+  0.96894115265327,
+  0.96940959032667,
+  0.96987270976912,
+  0.97033054600270,
+  0.97078313413161,
+  0.97123050933818,
+  0.97167270687887,
+  0.97210976208030,
+  0.97254171033525,
+  0.97296858709871,
+  0.97339042788392,
+  0.97380726825843,
+  0.97421914384017,
+  0.97462609029350,
+  0.97502814332534,
+  0.97542533868127,
+  0.97581771214160,
+  0.97620529951759,
+  0.97658813664749,
+  0.97696625939282,
+  0.97733970363445,
+  0.97770850526884,
+  0.97807270020427,
+  0.97843232435704,
+  0.97878741364771,
+  0.97913800399743,
+  0.97948413132414,
+  0.97982583153895,
+  0.98016314054243,
+  0.98049609422096,
+  0.98082472844313,
+  0.98114907905608,
+  0.98146918188197,
+  0.98178507271438,
+  0.98209678731477,
+  0.98240436140902,
+  0.98270783068385,
+  0.98300723078342,
+  0.98330259730589,
+  0.98359396579995,
+  0.98388137176152,
+  0.98416485063031,
+  0.98444443778651,
+  0.98472016854752,
+  0.98499207816463,
+  0.98526020181980,
+  0.98552457462240,
+  0.98578523160609,
+  0.98604220772560,
+  0.98629553785362,
+  0.98654525677772,
+  0.98679139919726,
+  0.98703399972035,
+  0.98727309286089,
+  0.98750871303556,
+  0.98774089456089,
+  0.98796967165036,
+  0.98819507841154,
+  0.98841714884323,
+  0.98863591683269,
+  0.98885141615285,
+  0.98906368045957,
+  0.98927274328896,
+  0.98947863805473,
+  0.98968139804554,
+  0.98988105642241,
+  0.99007764621618,
+  0.99027120032501,
+  0.99046175151186,
+  0.99064933240208,
+  0.99083397548099,
+  0.99101571309153,
+  0.99119457743191,
+  0.99137060055337,
+  0.99154381435784,
+  0.99171425059582,
+  0.99188194086414,
+  0.99204691660388,
+  0.99220920909823,
+  0.99236884947045,
+  0.99252586868186,
+  0.99268029752989,
+  0.99283216664606,
+  0.99298150649419,
+  0.99312834736847,
+  0.99327271939167,
+  0.99341465251338,
+  0.99355417650825,
+  0.99369132097430,
+  0.99382611533130,
+  0.99395858881910,
+  0.99408877049612,
+  0.99421668923778,
+  0.99434237373503,
+  0.99446585249289,
+  0.99458715382906,
+  0.99470630587254,
+  0.99482333656229,
+  0.99493827364600,
+  0.99505114467878,
+  0.99516197702200,
+  0.99527079784214,
+  0.99537763410962,
+  0.99548251259777,
+  0.99558545988178,
+  0.99568650233767,
+  0.99578566614138,
+  0.99588297726783,
+  0.99597846149005,
+  0.99607214437834,
+  0.99616405129947,
+  0.99625420741595,
+  0.99634263768527,
+  0.99642936685928,
+  0.99651441948352,
+  0.99659781989663,
+  0.99667959222978,
+  0.99675976040620,
+  0.99683834814063,
+  0.99691537893895,
+  0.99699087609774,
+  0.99706486270391,
+  0.99713736163442,
+  0.99720839555593,
+  0.99727798692461,
+  0.99734615798589,
+  0.99741293077431,
+  0.99747832711337,
+  0.99754236861541,
+  0.99760507668158,
+  0.99766647250181,
+  0.99772657705478,
+  0.99778541110799,
+  0.99784299521785,
+  0.99789934972976,
+  0.99795449477828,
+  0.99800845028730,
+  0.99806123597027,
+  0.99811287133042,
+  0.99816337566108,
+  0.99821276804596,
+  0.99826106735952,
+  0.99830829226732,
+  0.99835446122649,
+  0.99839959248609,
+  0.99844370408765,
+  0.99848681386566,
+  0.99852893944805,
+  0.99857009825685,
+  0.99861030750869,
+  0.99864958421549,
+  0.99868794518504,
+  0.99872540702178,
+  0.99876198612738,
+  0.99879769870160,
+  0.99883256074295,
+  0.99886658804953,
+  0.99889979621983,
+  0.99893220065356,
+  0.99896381655254,
+  0.99899465892154,
+  0.99902474256924,
+  0.99905408210916,
+  0.99908269196056,
+  0.99911058634952,
+  0.99913777930986,
+  0.99916428468421,
+  0.99919011612505,
+  0.99921528709576,
+  0.99923981087174,
+  0.99926370054150,
+  0.99928696900779,
+  0.99930962898876,
+  0.99933169301910,
+  0.99935317345126,
+  0.99937408245662,
+  0.99939443202674,
+  0.99941423397457,
+  0.99943349993572,
+  0.99945224136972,
+  0.99947046956130,
+  0.99948819562171,
+  0.99950543049000,
+  0.99952218493439,
+  0.99953846955355,
+  0.99955429477803,
+  0.99956967087154,
+  0.99958460793242,
+  0.99959911589494,
+  0.99961320453077,
+  0.99962688345035,
+  0.99964016210433,
+  0.99965304978499,
+  0.99966555562769,
+  0.99967768861231,
+  0.99968945756473,
+  0.99970087115825,
+  0.99971193791510,
+  0.99972266620792,
+  0.99973306426121,
+  0.99974314015288,
+  0.99975290181568,
+  0.99976235703876,
+  0.99977151346914,
+  0.99978037861326,
+  0.99978895983845,
+  0.99979726437448,
+  0.99980529931507,
+  0.99981307161943,
+  0.99982058811377,
+  0.99982785549283,
+  0.99983488032144,
+  0.99984166903600,
+  0.99984822794606,
+  0.99985456323584,
+  0.99986068096572,
+  0.99986658707386,
+  0.99987228737764,
+  0.99987778757524,
+  0.99988309324717,
+  0.99988820985777,
+  0.99989314275675,
+  0.99989789718072,
+  0.99990247825468,
+  0.99990689099357,
+  0.99991114030376,
+  0.99991523098456,
+  0.99991916772971,
+  0.99992295512891,
+  0.99992659766930,
+  0.99993009973692,
+  0.99993346561824,
+  0.99993669950161,
+  0.99993980547870,
+  0.99994278754604,
+  0.99994564960642,
+  0.99994839547033,
+  0.99995102885747,
+  0.99995355339809,
+  0.99995597263451,
+  0.99995829002249,
+  0.99996050893264,
+  0.99996263265183,
+  0.99996466438460,
+  0.99996660725452,
+  0.99996846430558,
+  0.99997023850356,
+  0.99997193273736,
+  0.99997354982037,
+  0.99997509249183,
+  0.99997656341810,
+  0.99997796519400,
+  0.99997930034415,
+  0.99998057132421,
+  0.99998178052220,
+  0.99998293025975,
+  0.99998402279338,
+  0.99998506031574,
+  0.99998604495686,
+  0.99998697878536,
+  0.99998786380966,
+  0.99998870197921,
+  0.99998949518567,
+  0.99999024526408,
+  0.99999095399401,
+  0.99999162310077,
+  0.99999225425649,
+  0.99999284908128,
+  0.99999340914435,
+  0.99999393596510,
+  0.99999443101421,
+  0.99999489571473,
+  0.99999533144314,
+  0.99999573953040,
+  0.99999612126300,
+  0.99999647788395,
+  0.99999681059383,
+  0.99999712055178,
+  0.99999740887647,
+  0.99999767664709,
+  0.99999792490431,
+  0.99999815465123,
+  0.99999836685427,
+  0.99999856244415,
+  0.99999874231676,
+  0.99999890733405,
+  0.99999905832493,
+  0.99999919608613,
+  0.99999932138304,
+  0.99999943495056,
+  0.99999953749392,
+  0.99999962968950,
+  0.99999971218563,
+  0.99999978560337,
+  0.99999985053727,
+  0.99999990755616,
+  0.99999995720387
+};
+
+
+double dolby_win_128[128] = {
+4.3795702929468881e-005,
+0.00011867384265436617,
+0.0002307165763996192, 
+0.00038947282760568383,
+0.00060581272288302553,
+0.00089199695169487453,
+0.0012617254423430522,
+0.0017301724373162003,
+0.0023140071937421476,
+0.0030313989666022221,
+0.0039020049735530842,
+0.0049469401815512024,
+0.0061887279335368318,
+0.0076512306364647726,
+0.0093595599562652423,
+0.011339966208377799,
+0.013619706891715299,
+0.016226894586323766,
+0.019190324717288168,
+0.022539283975960878,
+0.026303340480472455,
+0.030512117046644357,
+0.03519504922365594,
+0.040381130021856941,
+0.046098643518702249,
+0.052374889768730587,
+0.059235903660769147,
+0.066706170556282418,
+0.074808341703430481,
+0.083562952548726227,
+0.092988147159339674,
+0.1030994120216919,
+0.11390932249409955,
+0.12542730516149531,
+0.13765941926783826,
+0.15060816028651081,
+0.16427228853114245,
+0.17864668550988483,
+0.19372224048676889,
+0.20948576943658073,
+0.22591996826744942,
+0.24300340184133981,
+0.26071052995068139,
+0.27901177101369551,
+0.29787360383626599,
+0.3172587073594233,
+0.33712613787396362,
+0.35743154274286698,
+0.37812740923363009,
+0.39916334663203618,
+0.42048639939189658,
+0.4420413886774246,
+0.4637712792815169,
+0.4856175685594023,
+0.50752069370766872,
+0.52942045344797806,
+0.55125643994680196,
+0.57296847662071559,
+0.59449705734411495,
+0.61578378249506627,
+0.63677178724712891,
+0.65740615754163356,
+0.67763432925662526,
+0.69740646622548552,
+0.71667581294953808,
+0.73539901809352737,
+0.75353642514900732,
+0.77105232699609816,
+0.78791518148597028,
+0.80409778560147072,
+0.81957740622770781,
+0.83433586607383625,
+0.84835958382689225,
+0.86163956818294229,
+0.87417136598406997,
+0.88595496528524853,
+0.89699465477567619,
+0.90729884157670959,
+0.91687983002436779,
+0.92575356460899649,
+0.93393934077779084,
+0.94145948779657318,
+0.94833902830402828,
+0.95460531956280026,
+0.96028768170574896,
+0.96541701848104766,
+0.97002543610646474,
+0.97414586584250062,
+0.97781169577969584,
+0.98105641710392333,
+0.98391328975491177,
+0.98641503193166202,
+0.98859353733226141,
+0.99047962335771556,
+0.9921028127769449,
+0.99349115056397752,
+0.99467105680259038,
+0.9956672157341897,
+0.99650250022834352,
+0.99719793020823266,
+0.99777266288955657,
+0.99824401211201486,
+0.99862749357391212,
+0.99893689243401962,
+0.99918434952623147,
+0.99938046234161726,
+0.99953439696357238,
+0.99965400728430465,
+0.99974595807027455,
+0.99981584876278362,
+0.99986833527824281,
+0.99990724749057802,
+0.99993570051598468,
+0.99995619835942084,
+0.99997072890647543,
+0.9999808496399144,
+0.99998776381655818,
+0.99999238714961569,
+0.99999540529959718,
+0.99999732268176988,
+0.99999850325054862,
+0.99999920402413744,
+0.9999996021706401,
+0.99999981649545566,
+0.99999992415545547,
+0.99999997338493041,
+0.99999999295825959,
+0.99999999904096815
+};
+
+#endif
+
--- /dev/null
+++ b/enc.h
@@ -1,0 +1,64 @@
+/**********************************************************************
+Header file: enc.h
+
+$Id: enc.h,v 1.2 1999/12/16 19:39:15 menno Exp $
+
+Authors:
+HP    Heiko Purnhagen, Uni Hannover <purnhage@tnt.uni-hannover.de>
+RG    Ralf Geiger, FhG/IIS
+
+Changes:
+14-jun-96   HP    first version
+18-jun-96   HP    added bit reservoir handling
+04-jul-96   HP    joined with t/f code by BG (check "DISABLE_TF")
+09-aug-96   HP    added EncXxxInfo(), EncXxxFree()
+15-aug-96   HP    changed EncXxxInit(), EncXxxFrame() interfaces to
+                  enable multichannel signals / float fSample, bitRate
+26-aug-96   HP    CVS
+19-feb-97   HP    added include <stdio.h>
+07-apr-98   RG    added argument lfePresent in EncTfFrame()
+**********************************************************************/
+
+
+#ifndef _enc_h_
+#define _enc_h_
+
+#include <stdio.h>              /* typedef FILE */
+
+#include "bitstream.h"		/* bit stream module */
+
+/* ---------- functions ---------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* EncTfInit() */
+/* Init t/f-based encoder core. */
+
+void EncTfInit (faacAACConfig *ac, int VBR_setting);
+
+
+
+/* EncTfFrame() */
+/* Encode one audio frame into one bit stream frame with */
+/* t/f-based encoder core. */
+
+int EncTfFrame (faacAACStream *as, BsBitStream *bitBuf);
+
+
+/* EncTfFree() */
+/* Free memory allocated by t/f-based encoder core. */
+
+void EncTfFree ();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* #ifndef _enc_h_ */
+
+/* end of enc.h */
+
--- /dev/null
+++ b/enc_tf.c
@@ -1,0 +1,718 @@
+
+#include <math.h>
+#include <stdlib.h>
+#include <memory.h>
+#include "aacenc.h"
+#include "bitstream.h"
+#include "interface.h" 
+#include "enc.h"
+#include "block.h"
+#include "tf_main.h"
+#include "psych.h"
+#include "aac_back_pred.h"
+#include "mc_enc.h"
+#include "ms.h"
+#include "is.h"
+#include "aac_qc.h"
+#include "all.h"
+#include "aac_se_enc.h"
+
+
+/* AAC tables */
+
+/* First attempt at supporting multiple sampling rates   *
+ * and bitrates correctly.                               */
+
+/* Tables for maximum nomber of scalefactor bands */
+/* Needs more fine-tuning. Only the values for 44.1kHz have been changed
+   on lower bitrates. */
+int max_sfb_s[/*bitrate_idx*/][/*srate_idx*/12] = {
+   /* 96  88  64  48  44  32  24  22  16  12  11   8 kHz */
+	{ 12, 12, 12, 13, 12, 13, 15, 15, 15, 15, 15, 15 }, /*  64000 bps */
+	{ 12, 12, 12, 13, 12, 13, 15, 15, 15, 15, 15, 15 }, /*  80000 bps */
+	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /*  96000 bps */
+	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 112000 bps */
+	{ 12, 12, 12, 13, 14, 13, 15, 15, 15, 15, 15, 15 }, /* 128000 bps */
+	{ 12, 12, 12, 13, 14, 13, 15, 15, 15, 15, 15, 15 }, /* 160000 bps */
+	{ 12, 12, 12, 13, 14, 13, 15, 15, 15, 15, 15, 15 }, /* 192000 bps */
+	{ 12, 12, 12, 13, 14, 13, 15, 15, 15, 15, 15, 15 }, /* 224000 bps */
+	{ 12, 12, 12, 13, 14, 13, 15, 15, 15, 15, 15, 15 }  /* 256000 bps */
+};
+int max_sfb_l[/*bitrate_idx*/][/*srate_idx*/12] = {
+   /* 96  88  64  48  44  32  24  22  16  12  11   8 kHz */
+	{ 49, 49, 47, 48, 42, 51, 47, 47, 43, 43, 43, 40 }, /*  64000 bps */
+	{ 49, 49, 47, 48, 42, 51, 47, 47, 43, 43, 43, 40 }, /*  80000 bps */
+	{ 49, 49, 47, 48, 45, 51, 47, 47, 43, 43, 43, 40 }, /*  96000 bps */
+	{ 49, 49, 47, 48, 45, 51, 47, 47, 43, 43, 43, 40 }, /* 112000 bps */
+	{ 49, 49, 47, 48, 49, 51, 47, 47, 43, 43, 43, 40 }, /* 128000 bps */
+	{ 49, 49, 47, 48, 49, 51, 47, 47, 43, 43, 43, 40 }, /* 160000 bps */
+	{ 49, 49, 47, 48, 49, 51, 47, 47, 43, 43, 43, 40 }, /* 192000 bps */
+	{ 49, 49, 47, 48, 49, 51, 47, 47, 43, 43, 43, 40 }, /* 224000 bps */
+	{ 49, 49, 47, 48, 49, 51, 47, 47, 43, 43, 43, 40 }  /* 256000 bps */
+};
+
+
+static int     block_size_samples = 1024;  /* nr of samples per block in one! audio channel */
+static int     short_win_in_long  = 8;
+static int     max_ch;    /* no of of audio channels */
+static double *spectral_line_vector[MAX_TIME_CHANNELS];
+static double *reconstructed_spectrum[MAX_TIME_CHANNELS];
+static double *overlap_buffer[MAX_TIME_CHANNELS];
+static double *DTimeSigBuf[MAX_TIME_CHANNELS];
+static double *DTimeSigLookAheadBuf[MAX_TIME_CHANNELS+2];
+
+/* static variables used by the T/F mapping */
+static enum QC_MOD_SELECT qc_select = AAC_QC;                   /* later f(encPara) */
+static enum AAC_PROFILE profile = MAIN;
+static enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS];
+static enum WINDOW_TYPE desired_block_type[MAX_TIME_CHANNELS];
+static enum WINDOW_TYPE next_desired_block_type[MAX_TIME_CHANNELS+2];
+
+/* Additional variables for AAC */
+static int aacAllowScalefacs = 1;              /* Allow AAC scalefactors to be nonconstant */
+static TNS_INFO tnsInfo[MAX_TIME_CHANNELS];
+
+AACQuantInfo quantInfo[MAX_TIME_CHANNELS];               /* Info structure for AAC quantization and coding */
+
+/* Channel information */
+Ch_Info channelInfo[MAX_TIME_CHANNELS];
+
+/* AAC shorter windows 960-480-120 */
+static int useShortWindows=0;  /* don't use shorter windows */
+
+// TEMPORARY HACK
+
+int srate_idx;
+int bitrate_idx;
+
+int sampling_rate;
+int bit_rate;
+
+// END OF HACK
+
+
+/* EncTfFree() */
+/* Free memory allocated by t/f-based encoder core. */
+
+void EncTfFree ()
+{
+	int chanNum;
+
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
+		if (DTimeSigBuf[chanNum]) free(DTimeSigBuf[chanNum]);
+		if (spectral_line_vector[chanNum]) free(spectral_line_vector[chanNum]);
+
+		if (reconstructed_spectrum[chanNum]) free(reconstructed_spectrum[chanNum]);
+		if (overlap_buffer[chanNum]) free(overlap_buffer[chanNum]);
+	}
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS+2;chanNum++) {
+		if (DTimeSigLookAheadBuf[chanNum]) free(DTimeSigLookAheadBuf[chanNum]);
+	}
+}
+
+
+/*****************************************************************************************
+ ***
+ *** Function: EncTfInit
+ ***
+ *** Purpose:  Initialize the T/F-part and the macro blocks of the T/F part of the VM
+ ***
+ *** Description:
+ *** 
+ ***
+ *** Parameters:
+ ***
+ ***
+ *** Return Value:
+ ***
+ *** **** MPEG-4 VM ****
+ ***
+ ****************************************************************************************/
+
+void EncTfInit (faacAACConfig *ac, int VBR_setting)
+{
+	int chanNum, i;
+	int SampleRates[] = {
+		96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0
+	};
+	int BitRates[] = {
+		64000,80000,96000,112000,128000,160000,192000,224000,256000,0
+	};
+
+	sampling_rate = ac->sampling_rate;
+	bit_rate = ac->bit_rate;
+
+	for (i = 0; ; i++)
+	{
+		if (SampleRates[i] == sampling_rate) {
+			srate_idx = i;
+			break;
+		}
+	}
+	for (i = 0; ; i++)
+	{
+		if (BitRates[i] == bit_rate) {
+			bitrate_idx = i;
+			break;
+		}
+	}
+
+	profile = MAIN;
+	qc_select = AAC_PRED;           /* enable prediction */
+
+	if (ac->profile == LOW) {
+		profile = LOW;
+		qc_select = AAC_QC;          /* disable prediction */
+	}
+
+	/* set the return values */
+	max_ch = ac->channels;
+
+	/* some global initializations */
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
+		DTimeSigBuf[chanNum]            = (double*)malloc(block_size_samples*sizeof(double));
+		spectral_line_vector[chanNum]   = (double*)malloc(2*block_size_samples*sizeof(double));
+
+		reconstructed_spectrum[chanNum] = (double*)malloc(block_size_samples*sizeof(double));
+		memset(reconstructed_spectrum[chanNum], 0, block_size_samples*sizeof(double));
+		overlap_buffer[chanNum] = (double*)malloc(sizeof(double)*block_size_samples);
+		memset(overlap_buffer[chanNum],0,(block_size_samples)*sizeof(double));
+		block_type[chanNum] = ONLY_LONG_WINDOW;
+	}
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS+2;chanNum++) {
+		DTimeSigLookAheadBuf[chanNum]   = (double*)malloc((block_size_samples)*sizeof(double));
+		memset(DTimeSigLookAheadBuf[chanNum],0,(block_size_samples)*sizeof(double));
+	}
+
+	PredInit();
+
+	/* initialize psychoacoustic module */
+	EncTf_psycho_acoustic_init();
+
+	/* initialize spectrum processing */
+	/* initialize quantization and coding */
+	tf_init_encode_spectrum_aac(0);
+
+	/* Init TNS */
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
+		TnsInit(sampling_rate,profile,&tnsInfo[chanNum]);
+		quantInfo[chanNum].tnsInfo = &tnsInfo[chanNum];         /* Set pointer to TNS data */
+	}
+}
+
+/*****************************************************************************************
+ ***
+ *** Function:    EncTfFrame
+ ***
+ *** Purpose:     processes a block of time signal input samples into a bitstream
+ ***              based on T/F encoding 
+ ***
+ *** Description:
+ *** 
+ ***
+ *** Parameters:
+ ***
+ ***
+ *** Return Value:  returns the number of used bits
+ ***
+ *** **** MPEG-4 VM ****
+ ***
+ ****************************************************************************************/
+
+int EncTfFrame (faacAACStream *as, BsBitStream  *fixed_stream)
+{
+	int used_bits;
+	int error;
+
+	/* Energy array (computed before prediction for long windows) */
+	double energy[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
+
+	/* determine the function parameters used earlier:   HP 21-aug-96 */
+	int          average_bits = as->frame_bits;
+	int          available_bitreservoir_bits = as->available_bits-as->frame_bits;
+
+	/* actual amount of bits currently in the bit reservoir */
+	/* it is the job of this module to determine 
+	the no of bits to use in addition to average_block_bits
+	max. available: average_block_bits + available_bitreservoir_bits */
+	int max_bitreservoir_bits = 8184;
+
+	/* max. allowed amount of bits in the reservoir  (used to avoid padding bits) */
+	long num_bits_available;
+
+	double *p_ratio[MAX_TIME_CHANNELS], allowed_distortion[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
+	double p_ratio_long[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
+	double p_ratio_short[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
+	int    nr_of_sfb[MAX_TIME_CHANNELS], sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
+	int sfb_offset_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS+1];
+
+	int no_sub_win, sub_win_size;
+
+	/* structures holding the output of the psychoacoustic model */
+	CH_PSYCH_OUTPUT_LONG chpo_long[MAX_TIME_CHANNELS+2];
+	CH_PSYCH_OUTPUT_SHORT chpo_short[MAX_TIME_CHANNELS+2][MAX_SHORT_WINDOWS];
+
+	memset(chpo_long,0,sizeof(CH_PSYCH_OUTPUT_LONG)*(MAX_TIME_CHANNELS+2));
+	memset(chpo_short,0,sizeof(CH_PSYCH_OUTPUT_SHORT)*(MAX_TIME_CHANNELS+2)*MAX_SHORT_WINDOWS);
+	memset(p_ratio_long,0,sizeof(double)*(MAX_TIME_CHANNELS)*MAX_SCFAC_BANDS);
+	memset(p_ratio_short,0,sizeof(double)*(MAX_TIME_CHANNELS)*MAX_SCFAC_BANDS);
+
+	{ /* convert float input to double, which is the internal format */
+		/* store input data in look ahead buffer which may be necessary for the window switching decision */
+		int i;
+		int chanNum;
+		
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			for( i=0; i<block_size_samples; i++ ) {
+				/* last frame input data are encoded now */
+				DTimeSigBuf[chanNum][i] = DTimeSigLookAheadBuf[chanNum][i];
+				DTimeSigLookAheadBuf[chanNum][i] = (double)as->inputBuffer[chanNum][i];
+			} /* end for(i ..) */
+		} /* end for(chanNum ... ) */
+
+		for (chanNum=2;chanNum<4;chanNum++) {
+			if (chanNum == 2) {
+				for(i = 0; i < block_size_samples; i++){
+					DTimeSigLookAheadBuf[chanNum][i] = (DTimeSigLookAheadBuf[0][i]+DTimeSigLookAheadBuf[1][i])*0.5;
+				}
+			} else {
+				for(i = 0; i < block_size_samples; i++){
+					DTimeSigLookAheadBuf[chanNum][i] = (DTimeSigLookAheadBuf[0][i]-DTimeSigLookAheadBuf[1][i])*0.5;
+				}
+			}
+		}
+
+	}
+
+	if (fixed_stream == NULL) {
+		psy_fill_lookahead(DTimeSigLookAheadBuf, max_ch+2);
+
+		return FNO_ERROR; /* quick'n'dirty fix for encoder startup    HP 21-aug-96 */
+	}
+
+	/* Keep track of number of bits used */
+	used_bits = 0;
+
+	/***********************************************************************/
+	/* Determine channel elements      */
+	/***********************************************************************/
+	DetermineChInfo(channelInfo,max_ch);
+
+	/******************************************************************************************************************************
+	*
+	* psychoacoustic
+	*
+	******************************************************************************************************************************/
+	{
+		int chanNum;
+		for (chanNum=0;chanNum<max_ch+2;chanNum++) {
+
+			EncTf_psycho_acoustic(
+				sampling_rate,
+				chanNum,
+				&DTimeSigLookAheadBuf[chanNum],
+				&next_desired_block_type[chanNum],
+				(int)qc_select,
+				block_size_samples,
+				chpo_long,
+				chpo_short
+				);
+		}
+	}
+
+	/******************************************************************************************************************************
+	*
+	* block_switch processing 
+	*
+	******************************************************************************************************************************/
+	{
+		int chanNum;
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+
+			/* A few definitions:                                                      */
+			/*   block_type:  Initially, the block_type used in the previous frame.    */
+			/*                Will be set to the block_type to use this frame.         */
+			/*                A block type will be selected to ensure a meaningful     */
+			/*                window transition.                                       */
+			/*   next_desired_block_type:  Block_type (LONG or SHORT) which the psycho */
+			/*                model wants to use next frame.  The psycho model is      */
+			/*                using a look-ahead buffer.                               */
+			/*   desired_block_type:  Block_type (LONG or SHORT) which the psycho      */
+			/*                previously wanted to use.  It is the desired block_type  */
+			/*                for this frame.                                          */
+			if ( (block_type[chanNum]==ONLY_SHORT_WINDOW)||(block_type[chanNum]==LONG_SHORT_WINDOW) ) {
+				if ( (desired_block_type[chanNum]==ONLY_LONG_WINDOW)&&(next_desired_block_type[chanNum]==ONLY_LONG_WINDOW) ) {
+					block_type[chanNum]=SHORT_LONG_WINDOW;
+				} else {
+					block_type[chanNum]=ONLY_SHORT_WINDOW;
+				}
+			} else if (next_desired_block_type[chanNum]==ONLY_SHORT_WINDOW) {
+				block_type[chanNum]=LONG_SHORT_WINDOW;
+			} else {
+				block_type[chanNum]=ONLY_LONG_WINDOW;
+			}
+			desired_block_type[chanNum]=next_desired_block_type[chanNum];
+		}
+	}
+
+//	printf("%d %d\n", block_type[0], block_type[1]);
+//	block_type[0] = ONLY_LONG_WINDOW;
+//	block_type[1] = ONLY_LONG_WINDOW;
+//	block_type[0] = ONLY_SHORT_WINDOW;
+//	block_type[1] = ONLY_SHORT_WINDOW;
+//	if (as->use_MS)
+//		block_type[1] = block_type[0];
+
+	{
+		int chanNum;
+
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+
+			/* Set window shape paremeter in quantInfo */
+			quantInfo[chanNum].window_shape = WS_DOLBY;
+//			quantInfo[chanNum].window_shape = WS_FHG;
+
+			switch( block_type[chanNum] ) {
+			case ONLY_SHORT_WINDOW  :
+				no_sub_win   = short_win_in_long;
+				sub_win_size = block_size_samples/short_win_in_long;
+				quantInfo[chanNum].max_sfb = max_sfb_s[bitrate_idx][srate_idx];
+#if 0
+				quantInfo[chanNum].num_window_groups = 4;
+				quantInfo[chanNum].window_group_length[0] = 1;
+				quantInfo[chanNum].window_group_length[1] = 2;
+				quantInfo[chanNum].window_group_length[2] = 3;
+				quantInfo[chanNum].window_group_length[3] = 2;
+#else
+				quantInfo[chanNum].num_window_groups = 1;
+				quantInfo[chanNum].window_group_length[0] = 8;
+#endif
+				break;
+				
+			default:
+				no_sub_win   = 1;
+				sub_win_size = block_size_samples;
+				quantInfo[chanNum].max_sfb = max_sfb_l[bitrate_idx][srate_idx];
+				quantInfo[chanNum].num_window_groups = 1;
+				quantInfo[chanNum].window_group_length[0]=1;
+				break;
+			}
+		}
+	}
+
+	{
+		int chanNum;
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+
+			/* Count number of bits used for gain_control_data */
+			used_bits += WriteGainControlData(&quantInfo[chanNum],     /* quantInfo contains packed gain control data */
+				NULL,           /* NULL BsBitStream.  Only counting bits, no need to write yet */
+				0);             /* Zero write flag means don't write */
+		}
+	}
+
+
+
+	/******************************************************************************************************************************
+	*
+	* T/F mapping
+	*
+	******************************************************************************************************************************/
+
+	{
+		int chanNum;
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			buffer2freq(
+				DTimeSigBuf[chanNum],
+				spectral_line_vector[chanNum],
+				overlap_buffer[chanNum],
+				block_type[chanNum],
+				quantInfo[chanNum].window_shape,
+				block_size_samples,
+				block_size_samples/2,
+				block_size_samples/short_win_in_long,
+				MOVERLAPPED
+				);
+		}
+	}
+
+	/******************************************************************************************************************************
+	*
+	* adapt ratios of psychoacoustic module to codec scale factor bands
+	*
+	******************************************************************************************************************************/
+
+//	if (as->use_MS) {
+		MSPreprocess(p_ratio_long, p_ratio_short, chpo_long, chpo_short,
+			channelInfo, block_type, quantInfo,max_ch);
+//	} else {
+//		int chanNum;
+//		for (chanNum=0;chanNum<max_ch;chanNum++) {
+//
+//			/* Save p_ratio from psychoacoustic model for next frame.  */
+//			/* Psycho model is using a look-ahead window for block switching */
+//			if (as->use_MS) {
+//				memcpy( (char*)p_ratio_long[chanNum], (char*)chpo_long[chanNum+2].p_ratio, (NSFB_LONG)*sizeof(double) );
+//				memcpy( (char*)p_ratio_short[chanNum],(char*)chpo_short[chanNum+2][0].p_ratio,(MAX_SHORT_WINDOWS*NSFB_SHORT)*sizeof(double) );
+//			} else {
+//				memcpy( (char*)p_ratio_long[chanNum], (char*)chpo_long[chanNum].p_ratio, (NSFB_LONG)*sizeof(double) );
+//				memcpy( (char*)p_ratio_short[chanNum],(char*)chpo_short[chanNum][0].p_ratio,(MAX_SHORT_WINDOWS*NSFB_SHORT)*sizeof(double) );
+//			}
+//		}
+//	}
+
+	{
+		int chanNum;
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			switch( block_type[chanNum] ) {
+			case ONLY_LONG_WINDOW:
+				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
+				nr_of_sfb[chanNum] = 49; //chpo_long[chanNum].no_of_cb;
+				p_ratio[chanNum]   = p_ratio_long[chanNum];
+				break;
+			case LONG_SHORT_WINDOW:
+				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
+				nr_of_sfb[chanNum] = 49; //chpo_long[chanNum].no_of_cb;
+				p_ratio[chanNum]   = p_ratio_long[chanNum];
+				break;
+			case ONLY_SHORT_WINDOW:
+				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_short[chanNum][0].cb_width, (NSFB_SHORT+1)*sizeof(int) );
+				nr_of_sfb[chanNum] = 14; //chpo_short[chanNum][0].no_of_cb;
+				p_ratio[chanNum]   = p_ratio_short[chanNum];
+				break;
+			case SHORT_LONG_WINDOW:
+				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
+				nr_of_sfb[chanNum] = 49; //chpo_long[chanNum].no_of_cb;
+				p_ratio[chanNum]   = p_ratio_long[chanNum];
+				break;
+			}
+		}
+	}
+
+	{
+		int chanNum;   
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			/* Construct sf band offset table */
+			int offset=0;
+			int sfb;
+			for (sfb=0;sfb<nr_of_sfb[chanNum];sfb++) {
+				sfb_offset_table[chanNum][sfb] = offset;
+				offset+=sfb_width_table[chanNum][sfb];
+			}
+			sfb_offset_table[chanNum][nr_of_sfb[chanNum]]=offset;
+		}
+	}
+
+
+	/******************************************************************************************************************************
+	*
+	* quantization and coding
+	*
+	******************************************************************************************************************************/
+	{ 
+		int padding_limit = max_bitreservoir_bits;
+		int maxNumBitsByteAligned;
+		int chanNum;   
+		int numWindows;
+		int windowLength;
+		int j,w;
+		int bandNumber;
+		int numFillBits;
+		int bitsLeftAfterFill;
+
+		/* bit budget */
+		num_bits_available = (long)(average_bits + available_bitreservoir_bits - used_bits);
+		
+		/* find the largest byte-aligned section with fewer bits than num_bits_available */
+		maxNumBitsByteAligned = ((num_bits_available >> 3) << 3);
+
+		/* Compute how many reservoir bits can be used and still be able to byte */
+		/* align without exceeding num_bits_available, and have room for an ID_END marker   */
+		available_bitreservoir_bits = maxNumBitsByteAligned - LEN_SE_ID - average_bits;
+
+		/******************************************/
+		/* Perform TNS analysis and filtering     */
+		/******************************************/
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			error = TnsEncode(nr_of_sfb[chanNum],            /* Number of bands per window */
+				quantInfo[chanNum].max_sfb,              /* max_sfb */
+				block_type[chanNum],
+				sfb_offset_table[chanNum],
+				spectral_line_vector[chanNum],
+				&tnsInfo[chanNum]);
+			if (error == FERROR)
+				return FERROR;
+		}
+
+		/******************************************/
+		/* Apply Intensity Stereo                 */
+		/******************************************/
+		if (as->use_IS) {
+			ISEncode(spectral_line_vector,
+				channelInfo,
+				sfb_offset_table,
+				block_type,
+				quantInfo,
+				max_ch);
+		}
+
+		/***********************************************************************/
+		/* If prediction is used, compute predictor info and residual spectrum */
+		/***********************************************************************/
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+//			if (qc_select == AAC_PRED) {
+			if (0) {
+				int numPredBands;
+				max_pred_sfb = 40;
+				numPredBands = min(max_pred_sfb,nr_of_sfb[chanNum]);
+				PredCalcPrediction( spectral_line_vector[chanNum],
+					reconstructed_spectrum[chanNum],
+					(int)block_type[chanNum],
+					numPredBands,
+					sfb_width_table[chanNum],
+					&(quantInfo[chanNum].pred_global_flag),
+					quantInfo[chanNum].pred_sfb_flag,
+					&(quantInfo[chanNum].reset_group_number),
+					chanNum);
+			} else {
+				quantInfo[chanNum].pred_global_flag = 0;
+			}
+		} /* for(chanNum... */
+
+		/******************************************/
+		/* Apply MS stereo                        */
+		/******************************************/
+//		if (as->use_MS) {
+			MSEncode(spectral_line_vector,
+				channelInfo,
+				sfb_offset_table,
+				block_type,
+				quantInfo,
+				max_ch);
+//		}
+
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			double dtmp;
+
+			/* Compute energy in each scalefactor band of each window */
+			numWindows = (block_type[chanNum]==ONLY_SHORT_WINDOW) ?	short_win_in_long : 1;
+			windowLength = block_size_samples/numWindows;
+			bandNumber=0;
+			for (w=0;w<numWindows;w++) {
+				int offset=0;
+				int sfb;
+				j = w*windowLength;
+
+
+				/* Only compute energy up to max_sfb */
+				for(sfb=0; sfb< quantInfo[chanNum].max_sfb; sfb++ ) {
+					/* calculate scale factor band energy */
+					int width,i;
+					energy[chanNum][bandNumber] = 0.0;
+					width=sfb_width_table[chanNum][sfb];
+					for(i=offset; i<(offset+width); i++ ) {
+						dtmp = spectral_line_vector[chanNum][j++];   
+						energy[chanNum][bandNumber] += dtmp*dtmp;
+					}
+					energy[chanNum][bandNumber] = energy[chanNum][bandNumber] / width;
+					bandNumber++;
+					offset+=width;
+				}  
+			}
+		}  /* for (chanNum... */
+
+		/************************************************/
+		/* Call the AAC quantization and coding module. */
+		/************************************************/
+		for (chanNum = 0; chanNum < max_ch; chanNum++) {
+
+			int bitsToUse;
+			bitsToUse = (int)((average_bits - used_bits)/max_ch);
+			bitsToUse += (int)(0.2*available_bitreservoir_bits/max_ch);
+
+			error = tf_encode_spectrum_aac( &spectral_line_vector[chanNum],
+				&p_ratio[chanNum],
+				&allowed_distortion[chanNum],
+				&energy[chanNum],
+				&block_type[chanNum],
+				&sfb_width_table[chanNum],
+				&nr_of_sfb[chanNum],
+				bitsToUse,
+				available_bitreservoir_bits,
+				padding_limit,
+				fixed_stream,
+				NULL,
+				1,                        /* nr of audio channels */
+				&reconstructed_spectrum[chanNum],
+				useShortWindows,
+				aacAllowScalefacs,
+				&quantInfo[chanNum],
+				&(channelInfo[chanNum]),
+				0/*no vbr*/,
+				bit_rate);
+			if (error == FERROR)
+				return error;
+		}
+
+		/* If short window, reconstruction not needed for prediction */
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			if ((block_type[chanNum]==ONLY_SHORT_WINDOW)) {
+				int sind;
+				for (sind=0;sind<1024;sind++) {
+					reconstructed_spectrum[chanNum][sind]=0.0;
+				}
+			}
+		}
+
+		/**********************************/
+		/* Write out all encoded channels */
+		/**********************************/
+		for (chanNum=0;chanNum<max_ch;chanNum++) {
+			if (channelInfo[chanNum].present) {
+				/* Write out a single_channel_element */
+				if (!channelInfo[chanNum].cpe) {
+					/* Write out sce */ /* BugFix by YT  '+=' sould be '=' */
+					used_bits = WriteSCE(&quantInfo[chanNum],   /* Quantization information */
+						channelInfo[chanNum].tag,
+						fixed_stream,           /* Bitstream */
+						1);                     /* Write flag, 1 means write */
+				} else {
+					if (channelInfo[chanNum].ch_is_left) {
+						/* Write out cpe */
+						used_bits = WriteCPE(&quantInfo[chanNum],   /* Quantization information,left */
+							&quantInfo[channelInfo[chanNum].paired_ch],   /* Right */
+							channelInfo[chanNum].tag,
+							channelInfo[chanNum].common_window,    /* common window */
+							&(channelInfo[chanNum].ms_info),
+							fixed_stream,           /* Bitstream */
+							1);                     /* Write flag, 1 means write */
+					}
+				}  /* if (!channelInfo[chanNum].cpe)  else */
+			} /* if (chann...*/
+		} /* for (chanNum...*/
+
+		/* Compute how many fill bits are needed to avoid overflowing bit reservoir */
+		/* Save room for ID_END terminator */
+		if (used_bits < (8 - LEN_SE_ID) ) {
+			numFillBits = 8 - LEN_SE_ID - used_bits;
+		} else {
+			numFillBits = 0;
+		}
+		
+		/* Write AAC fill_elements, smallest fill element is 7 bits. */
+		/* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */
+		numFillBits += 6;
+		bitsLeftAfterFill=WriteAACFillBits(fixed_stream,numFillBits);
+		used_bits += (numFillBits - bitsLeftAfterFill);
+
+		/* Write ID_END terminator */
+		BsPutBit(fixed_stream,ID_END,LEN_SE_ID);
+		used_bits += LEN_SE_ID;
+		
+		/* Now byte align the bitstream */
+		used_bits += ByteAlign(fixed_stream);
+
+	} /* Quantization and coding block */
+	return FNO_ERROR;
+}
+
--- /dev/null
+++ b/encoder.c
@@ -1,0 +1,624 @@
+
+/* Encoder DLL interface module.*/
+
+#ifdef FAAC_DLL
+#include <windows.h>
+#endif
+#include <memory.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "aacenc.h"
+#include "bitstream.h"	/* bit stream module */
+
+#include "enc.h"	/* encoder cores */
+
+#define BITHEADERBUFSIZE (65536)
+
+/* ---------- functions ---------- */
+
+
+faacAACStream *faacEncodeInit(faacAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize)
+{
+	int frameNumSample,delayNumSample;
+	int ch;
+	faacAACStream *as;
+
+	int startupNumFrame;
+
+	as = malloc( sizeof(faacAACStream));
+	if ((as->inputBuffer = (float**)malloc( ac->channels*sizeof(float*)))==NULL)
+		return NULL;
+	for (ch=0; ch < ac->channels; ch++)
+	{
+		if ((as->inputBuffer[ch]=(float*)malloc( 1024*sizeof(float)))==NULL)
+			return NULL;
+	}
+
+//	if (ac->sampling_rate != 44100)
+//		return NULL;
+	switch (ac->bit_rate) {
+	case 64000:
+	case 80000:
+	case 96000:
+	case 112000:
+	case 128000:
+	case 160000:
+	case 192000:
+	case 224000:
+	case 256000:
+		break;
+	default:
+		return NULL;
+	}
+	if (ac->channels != 2)
+		return NULL;
+	if ((ac->profile != MAIN_PROFILE)&&(ac->profile != LOW_PROFILE))
+		return NULL;
+
+	as->total_bits = 0;
+	as->frames = 0;
+	as->cur_frame = 0;
+	as->channels = ac->channels;
+	as->sampling_rate = ac->sampling_rate;
+	as->write_header = ac->write_header;
+	as->use_MS = ac->use_MS;
+	as->use_IS = ac->use_IS;
+	as->profile = ac->profile;
+	as->is_first_frame = 1;
+
+	if (as->write_header) {
+		*headerSize = 17;
+	} else {
+		*headerSize = 0;
+	}
+
+	EncTfInit(ac, 0);
+
+	frameNumSample = 1024;
+	delayNumSample = 2*frameNumSample;
+
+	*samplesToRead = frameNumSample * ac->channels;
+
+	as->frame_bits = (int)(ac->bit_rate*frameNumSample/ac->sampling_rate+0.5);
+	*bitBufferSize = (int)((as->frame_bits * 2 + 8)/8);
+
+
+	/* num frames to start up encoder due to delay compensation */
+	startupNumFrame = (delayNumSample+frameNumSample-1)/frameNumSample;
+
+	/* process audio file frame by frame */
+	as->cur_frame = -startupNumFrame;
+	as->available_bits = 8184;
+
+	return as;
+}
+
+int faacEncodeFrame(faacAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize)
+{
+	int i, error;
+	int usedNumBit, usedBytes;
+	BsBitStream *bitBuf;
+
+	// Is this the last (incomplete) frame
+	if ((Samples < 1024*as->channels)&&(Samples > 0)) {
+		// Padd with zeros
+		memset(Buffer + Samples, 0, (2048-Samples)*sizeof(short));
+	}
+
+	// Process Buffer
+	if (as->channels == 2)
+	{
+		if (Samples > 0)
+			for (i = 0; i < 1024; i++)
+			{
+				as->inputBuffer[0][i] = *Buffer++;
+				as->inputBuffer[1][i] = *Buffer++;
+			}
+		else // (Samples == 0) when called by faacEncodeFinish
+			for (i = 0; i < 1024; i++)
+			{
+				as->inputBuffer[0][i] = 0;
+				as->inputBuffer[1][i] = 0;
+			}
+	} else {
+		// No mono supported yet (basically only a problem with decoder
+		// the encoder in fact supports it).
+		return FERROR;
+	}
+
+	if (as->is_first_frame) {
+		EncTfFrame(as, (BsBitStream*)NULL);
+
+		as->is_first_frame = 0;
+		as->cur_frame++;
+
+		*bitBufSize = 0;
+
+		return FNO_ERROR;
+	}
+
+	bitBuf = BsOpenWrite(as->frame_bits * 10);
+
+	/* compute available number of bits */
+	/* frameAvailNumBit contains number of bits in reservoir */
+	/* variable bit rate: don't exceed bit reservoir size */
+	if (as->available_bits > 8184)
+		as->available_bits = 8184;
+		
+	/* Add to frameAvailNumBit the number of bits for this frame */
+	as->available_bits += as->frame_bits;
+
+	/* Encode frame */
+	error = EncTfFrame(as, bitBuf);
+
+	if (error == FERROR)
+		return FERROR;
+
+	usedNumBit = BsBufferNumBit(bitBuf);
+	as->total_bits += usedNumBit;
+
+	// Copy bitBuf into bitBuffer here
+	usedBytes = (int)((usedNumBit/8)+0.5);
+	*bitBufSize = usedBytes;
+	for (i = 0; i < usedBytes; i++)
+		bitBuffer[i] = bitBuf->data[i];
+	BsClose(bitBuf);
+
+	/* Adjust available bit counts */
+	as->available_bits -= usedNumBit;    /* Subtract bits used */
+
+	as->cur_frame++;
+
+	return FNO_ERROR;
+}
+
+int faacEncodeFinish(faacAACStream *as, unsigned char *bitBuffer, int *bitBufSize)
+{
+	unsigned char tmpBitBuffer[2048];
+	int tmpBitBufSize, i;
+	faacEncodeFrame(as, NULL, 0, tmpBitBuffer, &tmpBitBufSize);
+	for (i = 0; i < tmpBitBufSize; i++)
+		bitBuffer[i] = tmpBitBuffer[i];
+	faacEncodeFrame(as, NULL, 0, tmpBitBuffer, bitBufSize);
+	for (i = 0; i < *bitBufSize; i++)
+		bitBuffer[i+tmpBitBufSize] = tmpBitBuffer[i];
+	*bitBufSize += tmpBitBufSize;
+
+	return FNO_ERROR;
+}
+
+int faacEncodeFree(faacAACStream *as, unsigned char *headerBuf)
+{
+	BsBitStream *bitHeader;
+	float seconds;
+	int bits, bytes, ch;
+
+	seconds = (float)as->sampling_rate/(float)1024;
+	seconds = (float)as->cur_frame/seconds;
+
+	/* free encoder memory */
+	EncTfFree();
+
+	if (as->write_header)
+	{
+		int i;
+		static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};
+
+		as->total_bits += 17 * 8;
+
+		bitHeader = BsOpenWrite(BITHEADERBUFSIZE);
+
+		for (i = 0; ; i++)
+		{
+			if (SampleRates[i] == as->sampling_rate)
+				break;
+			else if (SampleRates[i] == 0)
+			{
+				return FERROR;
+			}
+		}
+
+		// ADIF_Header
+		BsPutBit(bitHeader,'A',8);
+		BsPutBit(bitHeader,'D',8);
+		BsPutBit(bitHeader,'I',8);
+		BsPutBit(bitHeader,'F',8);
+		BsPutBit(bitHeader,0,1);   // Copyright present
+		BsPutBit(bitHeader,0,1);   // Original
+		BsPutBit(bitHeader,0,1);   // Home
+		BsPutBit(bitHeader,0,1);   // Bitstream type
+		BsPutBit(bitHeader,(int)(as->total_bits/seconds),23);  // Bitrate
+		BsPutBit(bitHeader, 0, 4);   // num program config elements
+
+		// ADIF_buffer_fulness
+		BsPutBit(bitHeader, 0, 20);
+
+		// program_config_element
+		BsPutBit(bitHeader,0,4);
+		BsPutBit(bitHeader,as->profile,2);
+		BsPutBit(bitHeader,i,4);
+		BsPutBit(bitHeader,1,4);
+		BsPutBit(bitHeader,0,4);
+		BsPutBit(bitHeader,0,4);
+		BsPutBit(bitHeader,0,2);
+		BsPutBit(bitHeader,0,3);
+		BsPutBit(bitHeader,0,4);
+		BsPutBit(bitHeader,0,1);
+		BsPutBit(bitHeader,0,1);
+		BsPutBit(bitHeader,0,1);
+		// element_list
+		BsPutBit(bitHeader,(as->channels == 2),1);
+		BsPutBit(bitHeader,0,4);
+
+		ByteAlign(bitHeader);
+		// Comment
+		BsPutBit(bitHeader,0,8);
+
+		bits = BsBufferNumBit(bitHeader);
+
+		// Copy bitBuf into bitBuffer here
+		bytes = (int)((bits+8)/8);
+		for (i = 0; i < bytes; i++)
+			headerBuf[i] = bitHeader->data[i];
+		BsClose(bitHeader);
+	}
+
+	for (ch=0; ch < as->channels; ch++)
+		if(as->inputBuffer[ch]) free(as->inputBuffer[ch]);
+	if(as->inputBuffer) free(as->inputBuffer);
+	if (as) free(as);
+
+	return FNO_ERROR;
+}
+
+faacVersion *faacEncodeVersion()
+{
+	faacVersion *faacv = malloc(sizeof(faacVersion));
+
+	faacv->DLLMajorVersion = 1;
+	faacv->DLLMinorVersion = 1;
+	faacv->MajorVersion = 0;
+	faacv->MinorVersion = 55;
+	strcpy(faacv->HomePage, "http://www.slimline.net/aac/");
+
+	return faacv;
+}
+
+#ifdef FAAC_DLL
+
+BOOL APIENTRY DllMain(HANDLE hModule, 
+                      DWORD  ul_reason_for_call, 
+                      LPVOID lpReserved)
+{
+    return TRUE;
+}
+
+#else
+
+/* You can download libsndfile from http://www.zip.com.au/~erikd/libsndfile/ */
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#endif
+
+#include <sndfile.h>
+
+char *get_filename(char *pPath)
+{
+    char *pT;
+
+    for (pT = pPath; *pPath; pPath++) {
+        if ((pPath[0] == '\\' || pPath[0] == ':') && pPath[1] && (pPath[1] != '\\'))
+            pT = pPath + 1;
+    }
+
+    return pT;
+}
+
+void combine_path(char *path, char *dir, char *file)
+{
+	/* Should be a bit more sophisticated
+	   This code assumes that the path exists */
+
+	/* Assume dir is allocated big enough */
+	if (dir[strlen(dir)-1] != '\\')
+		strcat(dir, "\\");
+	strcat(dir, get_filename(file));
+	strcpy(path, dir);
+}
+
+void usage(void)
+{
+	printf("Usage:\n");
+	printf("faac.exe -options file ...\n");
+	printf("Options:\n");
+	printf(" -h    Shows this help screen.\n");
+	printf(" -pX   AAC profile (X can be LOW, or MAIN (default).\n");
+	printf(" -n    No header will be written to the AAC file.\n");
+	printf(" -bX   Bitrate in kbps (X can be: 64, 80, 96, 112, 128 (default),\n");
+	printf("       160, 192, 224 or 256).\n");
+	printf(" -ms   Use mid/side stereo coding (currently ignored).\n");
+	printf(" -is   Use intensity stereo coding.\n");
+	printf(" -oX   Set output directory.\n");
+	printf(" -r    Use raw data input file.\n");
+	printf(" file  Multiple files can be given as well as wild cards.\n");
+	printf("       Can be any of the filetypes supported by libsndfile\n");
+	printf("       (http://www.zip.com.au/~erikd/libsndfile/).\n");
+	printf("Example:\n");
+	printf("       faac.exe -b96 -oc:\\aac\\ *.wav\n");
+	return;
+}
+
+
+int main(int argc, char *argv[])
+{
+	int readNumSample;
+
+	short sampleBuffer[2048];
+	unsigned char *bitBuffer = NULL;
+	FILE *aacfile;
+	SNDFILE *sndfile;
+	SF_INFO sf_info;
+	int noSamples;
+	int error;
+	int bitBufSize;
+	int curBitBufSize;
+	int headerSize;
+	int i, frames, cfr;
+	int profile = MAIN_PROFILE;
+	int no_header = 0;
+	int use_IS = 0, use_MS = 0;
+	int bit_rate = 128;
+	char out_dir[255];
+	int out_dir_set = 0;
+	int raw_audio = 0;
+	char *argp;
+	char *FileNames[200];
+	int FileCount = 0;
+
+	faacAACStream *as;
+	faacAACConfig ac;
+	faacVersion *faacv;
+
+	long begin, end;
+
+	faacv = NULL;
+	faacv = faacEncodeVersion();
+	printf("FAAC cl (Freeware AAC Encoder)\n");
+	printf("FAAC homepage: %s\n", faacv->HomePage);
+	printf("Encoder engine version: %d.%d\n\n",
+		faacv->MajorVersion, faacv->MinorVersion);
+	if (faacv) free(faacv);
+
+	/* Process the command line */
+	if (argc == 1) {
+		usage();
+		return 1;
+	}
+
+	for (i = 1; i < argc; i++)
+	{
+		if ((argv[i][0] != '-')&&(argv[i][0] != '/')) {
+			if (strchr("-/", argv[i][0]))
+				argp = &argv[i][1];
+			else  argp = argv[i];
+
+			if (!strchr(argp, '*') && !strchr(argp, '?'))
+			{
+				FileNames[FileCount] = malloc((strlen(argv[i])+1)*sizeof(char));
+				strcpy(FileNames[FileCount], argv[i]);
+				FileCount++;
+			} else {
+#ifdef WIN32
+				HANDLE hFindFile;
+				WIN32_FIND_DATA fd;
+
+				char path[255], *p;
+
+				if (NULL == (p = strrchr(argp, '\\')))
+					p = strrchr(argp, '/');
+				if (p)
+				{
+					char ch = *p;
+
+					*p = 0;
+					strcat(strcpy(path, argp), "\\");
+					*p = ch;
+				}
+				else
+					*path = 0;
+
+				if (INVALID_HANDLE_VALUE != (hFindFile = FindFirstFile(argp, &fd)))
+				{
+					do
+					{
+						FileNames[FileCount] = malloc((strlen(fd.cFileName)
+							+ strlen(path) + 2)*sizeof(char));
+						strcat(strcpy(FileNames[FileCount], path), fd.cFileName);
+						FileCount++;
+					} while (FindNextFile(hFindFile, &fd));
+					FindClose(hFindFile);
+				}
+#else
+				printf("Wildcards not yet supported on systems other than WIN32\n");
+#endif
+			}
+		} else {
+			switch(argv[i][1]) {
+			case 'p':
+			case 'P':
+				if (argv[i][2] == 'l' || 'L')
+					profile = LOW_PROFILE;
+				else
+					profile = MAIN_PROFILE;
+				break;
+			case 'n':
+			case 'N':
+				no_header = 1;
+				break;
+			case 'm':
+			case 'M':
+				use_MS = 1;
+				break;
+			case 'i':
+			case 'I':
+				use_IS = 1;
+				break;
+			case 'r':
+			case 'R':
+				raw_audio = 1;
+				break;
+			case 'b':
+			case 'B':
+				bit_rate = atoi(&argv[i][2]);
+				break;
+			case 'o':
+			case 'O':
+				out_dir_set = 1;
+				strcpy(out_dir, &argv[i][2]);
+				break;
+			case 'h':
+			case 'H':
+				usage();
+				return 1;
+			}
+		}
+	}
+
+	if (FileCount == 0) {
+		return 1;
+	}
+
+	for (i = 0; i < FileCount; i++) {
+		char aac_fn[255];
+		char *fnp;
+
+		printf("0%\tBusy encoding %s.\r", FileNames[i]);
+
+#ifdef WIN32
+		begin = GetTickCount();
+#else
+		begin = clock();
+#endif
+
+		if (raw_audio) {
+			sf_info.format =  SF_FORMAT_RAW;
+			sf_info.format |= SF_FORMAT_PCM_BE;
+			sf_info.channels = 2;
+			sf_info.pcmbitwidth = 16;
+			sf_info.samplerate = 44100;
+		}
+
+		sndfile = sf_open_read(FileNames[i], &sf_info);
+		if (sndfile==NULL) {
+			printf("Error while encoding %s.\n", FileNames[i]);
+			continue;
+		}
+
+		frames = (int)(sf_info.samples/1024+0.5);
+
+		if (out_dir_set)
+			combine_path(aac_fn, out_dir, FileNames[i]);
+		else
+			strcpy(aac_fn, FileNames[i]);
+		fnp = strrchr(aac_fn,'.');
+		fnp[0] = '\0';
+		strcat(aac_fn,".aac");
+
+		aacfile = fopen(aac_fn, "wb");
+		if (aacfile==NULL) {
+			printf("Error while encoding %s.\n", FileNames[i]);
+			continue;
+		}
+
+		ac.channels = sf_info.channels;
+		ac.sampling_rate = sf_info.samplerate;
+		ac.bit_rate = bit_rate * 1000;
+		ac.profile = profile;
+		ac.use_MS = use_MS;
+		ac.use_IS = use_IS;
+		ac.write_header = !no_header;
+
+		as = faacEncodeInit(&ac, &readNumSample, &bitBufSize, &headerSize);
+		if (as == NULL) {
+			printf("Error while encoding %s.\n", FileNames[i]);
+			continue;
+		}
+
+		if (headerSize > 0) {
+			bitBuffer = malloc(headerSize*sizeof(char));
+			memset(bitBuffer, 0, headerSize*sizeof(char));
+			// Skip headerSize bytes
+			// They should be written after calling faacEncodeFree
+			fwrite(bitBuffer, 1, headerSize, aacfile);
+			if (bitBuffer) { free(bitBuffer); bitBuffer = NULL; }
+		}
+
+		bitBuffer = malloc(bitBufSize*sizeof(char));
+
+		cfr = 0;
+
+		// Keep encoding frames until the end of the audio file
+		do {
+			cfr++;
+
+			noSamples = sf_read_short(sndfile, sampleBuffer, readNumSample);
+
+			error = faacEncodeFrame(as, sampleBuffer, noSamples, bitBuffer, &curBitBufSize);
+			if (error == FERROR) {
+				printf("Error while encoding %s.\n", FileNames[i]);
+				break;
+			}
+
+			fwrite(bitBuffer, 1, curBitBufSize, aacfile);
+			
+			printf("%.2f%%\tBusy encoding %s.\r", min(((double)cfr/(double)frames)*100,100),FileNames[i]);
+
+		} while (noSamples == readNumSample);
+
+		if (error == FERROR) {
+			continue;
+		}
+
+		error = faacEncodeFinish(as, bitBuffer, &curBitBufSize);
+		if (error == FERROR) {
+			printf("Error while encoding %s.\n", FileNames[i]);
+			continue;
+		}
+
+		fwrite(bitBuffer, 1, curBitBufSize, aacfile);
+
+		sf_close(sndfile);
+
+		fclose(aacfile);
+
+		error = faacEncodeFree(as, bitBuffer);
+		if (error == FERROR) {
+			printf("Error while encoding %s.\n", FileNames[i]);
+			continue;
+		}
+
+		// Write the header to the beginning of the file now
+		if (headerSize > 0) {
+			aacfile = fopen(aac_fn, "rb+");
+			fwrite(bitBuffer, 1, headerSize, aacfile);
+			fclose(aacfile);
+		}
+
+		if (bitBuffer) { free(bitBuffer); bitBuffer = NULL; }
+
+#ifdef WIN32
+		end = GetTickCount();
+#else
+		end = clock();
+#endif
+		printf("Encoding %s took: %d sec.\n", FileNames[i], (end-begin)/1000);
+	}
+
+	return FNO_ERROR;
+}
+
+
+#endif
--- /dev/null
+++ b/faac.dsp
@@ -1,0 +1,150 @@
+# Microsoft Developer Studio Project File - Name="faac" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=faac - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "faac.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "faac.mak" CFG="faac - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "faac - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "faac - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "faac - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libsndfile.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "faac - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libsndfile.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "faac - Win32 Release"
+# Name "faac - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aac_back_pred.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\aac_qc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\aac_se_enc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bitstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\enc_tf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\encoder.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\imdct.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\is.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mc_enc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ms.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\psych.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pulse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\tns.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\transfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.c
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/faac.dsw
@@ -1,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "faac"=.\faac.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "faac_dll"=.\faac_dll.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+++ b/faac_dll.dsp
@@ -1,0 +1,159 @@
+# Microsoft Developer Studio Project File - Name="faac_dll" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=faac_dll - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "faac_dll.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "faac_dll.mak" CFG="faac_dll - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "faac_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "faac_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "faac_dll - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "faac_dll___Win32_Release"
+# PROP BASE Intermediate_Dir "faac_dll___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseDLL"
+# PROP Intermediate_Dir "ReleaseDLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAAC_DLL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W1 /O2 /D "NDEBUG" /D "FAAC_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAAC_DLL_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"ReleaseDLL/faac.dll"
+
+!ELSEIF  "$(CFG)" == "faac_dll - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "faac_dll___Win32_Debug"
+# PROP BASE Intermediate_Dir "faac_dll___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugDLL"
+# PROP Intermediate_Dir "DebugDLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAAC_DLL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "FAAC_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAAC_DLL_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/faac.dll" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "faac_dll - Win32 Release"
+# Name "faac_dll - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aac_back_pred.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\aac_qc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\aac_se_enc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bitstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\enc_tf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\encoder.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\imdct.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\is.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mc_enc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ms.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\psych.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pulse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\tns.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\transfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.c
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/hufftab5.h
@@ -1,0 +1,311 @@
+
+int huff1[][2] = {
+		{ 11,  2040},
+		{ 9,  497},{ 11,  2045},{ 10,  1013},{ 7,  104},{ 10,  1008},
+		{ 11,  2039},{ 9,  492},{ 11,  2037},{ 10,  1009},{ 7,  114},
+		{ 10,  1012},{ 7,  116},{ 5,  17},{ 7,  118},{ 9,  491},
+		{ 7,  108},{ 10,  1014},{ 11,  2044},{ 9,  481},{ 11,  2033},
+		{ 9,  496},{ 7,  97},{ 9,  502},{ 11,  2034},{ 9,  490},
+		{ 11,  2043},{ 9,  498},{ 7,  105},{ 9,  493},{ 7,  119},
+		{ 5,  23},{ 7,  111},{ 9,  486},{ 7,  100},{ 9,  485},
+		{ 7,  103},{ 5,  21},{ 7,  98},{ 5,  18},{ 1,  0},
+		{ 5,  20},{ 7,  101},{ 5,  22},{ 7,  109},{ 9,  489},
+		{ 7,  99},{ 9,  484},{ 7,  107},{ 5,  19},{ 7,  113},
+		{ 9,  483},{ 7,  112},{ 9,  499},{ 11,  2046},{ 9,  487},
+		{ 11,  2035},{ 9,  495},{ 7,  96},{ 9,  494},{ 11,  2032},
+		{ 9,  482},{ 11,  2042},{ 10,  1011},{ 7,  106},{ 9,  488},
+		{ 7,  117},{ 5,  16},{ 7,  115},{ 9,  500},{ 7,  110},
+		{ 10,  1015},{ 11,  2038},{ 9,  480},{ 11,  2041},{ 10,  1010},
+		{ 7,  102},{ 9,  501},{ 11,  2047},{ 9,  503},{ 11,  2036}
+	};
+int huff2[][2] = {
+	{ 9,  499},
+		{ 7,  111},{ 9,  509},{ 8,  235},{ 6,  35},{ 8,  234},
+		{ 9,  503},{ 8,  232},{ 9,  506},{ 8,  242},{ 6,  45},
+		{ 7,  112},{ 6,  32},{ 5,  6},{ 6,  43},{ 7,  110},
+		{ 6,  40},{ 8,  233},{ 9,  505},{ 7,  102},{ 8,  248},
+		{ 8,  231},{ 6,  27},{ 8,  241},{ 9,  500},{ 7,  107},
+		{ 9,  501},{ 8,  236},{ 6,  42},{ 7,  108},{ 6,  44},
+		{ 5,  10},{ 6,  39},{ 7,  103},{ 6,  26},{ 8,  245},
+		{ 6,  36},{ 5,  8},{ 6,  31},{ 5,  9},{ 3,  0},
+		{ 5,  7},{ 6,  29},{ 5,  11},{ 6,  48},{ 8,  239},
+		{ 6,  28},{ 7,  100},{ 6,  30},{ 5,  12},{ 6,  41},
+		{ 8,  243},{ 6,  47},{ 8,  240},{ 9,  508},{ 7,  113},
+		{ 9,  498},{ 8,  244},{ 6,  33},{ 8,  230},{ 8,  247},
+		{ 7,  104},{ 9,  504},{ 8,  238},{ 6,  34},{ 7,  101},
+		{ 6,  49},{ 4,  2},{ 6,  38},{ 8,  237},{ 6,  37},
+		{ 7,  106},{ 9,  507},{ 7,  114},{ 9,  510},{ 7,  105},
+		{ 6,  46},{ 8,  246},{ 9,  511},{ 7,  109},{ 9,  502}
+	};
+int huff3[][2] = {
+		{ 1,  0},
+		{ 4,  9},{ 8,  239},{ 4,  11},{ 5,  25},{ 8,  240},
+		{ 9,  491},{ 9,  486},{ 10,  1010},{ 4,  10},{ 6,  53},
+		{ 9,  495},{ 6,  52},{ 6,  55},{ 9,  489},{ 9,  493},
+		{ 9,  487},{ 10,  1011},{ 9,  494},{ 10,  1005},{ 13,  8186},
+		{ 9,  492},{ 9,  498},{ 11,  2041},{ 11,  2040},{ 10,  1016},
+		{ 12,  4088},{ 4,  8},{ 6,  56},{ 10,  1014},{ 6,  54},
+		{ 7,  117},{ 10,  1009},{ 10,  1003},{ 10,  1004},{ 12,  4084},
+		{ 5,  24},{ 7,  118},{ 11,  2036},{ 6,  57},{ 7,  116},
+		{ 10,  1007},{ 9,  499},{ 9,  500},{ 11,  2038},{ 9,  488},
+		{ 10,  1002},{ 13,  8188},{ 8,  242},{ 9,  497},{ 12,  4091},
+		{ 10,  1013},{ 11,  2035},{ 12,  4092},{ 8,  238},{ 10,  1015},
+		{ 15,  32766},{ 9,  496},{ 11,  2037},{ 15,  32765},{ 13,  8187},
+		{ 14,  16378},{ 16,  65535},{ 8,  241},{ 10,  1008},{ 14,  16380},
+		{ 9,  490},{ 10,  1006},{ 14,  16379},{ 12,  4086},{ 12,  4090},
+		{ 15,  32764},{ 11,  2034},{ 12,  4085},{ 16,  65534},{ 10,  1012},
+		{ 11,  2039},{ 15,  32763},{ 12,  4087},{ 12,  4089},{ 15,  32762}
+	};
+int huff4[][2] = {
+		{ 4,  7},
+		{ 5,  22},{ 8,  246},{ 5,  24},{ 4,  8},{ 8,  239},
+		{ 9,  495},{ 8,  243},{ 11,  2040},{ 5,  25},{ 5,  23},
+		{ 8,  237},{ 5,  21},{ 4,  1},{ 8,  226},{ 8,  240},
+		{ 7,  112},{ 10,  1008},{ 9,  494},{ 8,  241},{ 11,  2042},
+		{ 8,  238},{ 8,  228},{ 10,  1010},{ 11,  2038},{ 10,  1007},
+		{ 11,  2045},{ 4,  5},{ 5,  20},{ 8,  242},{ 4,  9},
+		{ 4,  4},{ 8,  229},{ 8,  244},{ 8,  232},{ 10,  1012},
+		{ 4,  6},{ 4,  2},{ 8,  231},{ 4,  3},{ 4,  0},
+		{ 7,  107},{ 8,  227},{ 7,  105},{ 9,  499},{ 8,  235},
+		{ 8,  230},{ 10,  1014},{ 7,  110},{ 7,  106},{ 9,  500},
+		{ 10,  1004},{ 9,  496},{ 10,  1017},{ 8,  245},{ 8,  236},
+		{ 11,  2043},{ 8,  234},{ 7,  111},{ 10,  1015},{ 11,  2041},
+		{ 10,  1011},{ 12,  4095},{ 8,  233},{ 7,  109},{ 10,  1016},
+		{ 7,  108},{ 7,  104},{ 9,  501},{ 10,  1006},{ 9,  498},
+		{ 11,  2036},{ 11,  2039},{ 10,  1009},{ 12,  4094},{ 10,  1005},
+		{ 9,  497},{ 11,  2037},{ 11,  2046},{ 10,  1013},{ 11,  2044}
+	};
+int huff5[][2] = {
+		{ 13,  8191},
+		{ 12,  4087},{ 11,  2036},{ 11,  2024},{ 10,  1009},{ 11,  2030},
+		{ 11,  2041},{ 12,  4088},{ 13,  8189},{ 12,  4093},{ 11,  2033},
+		{ 10,  1000},{ 9,  488},{ 8,  240},{ 9,  492},{ 10,  1006},
+		{ 11,  2034},{ 12,  4090},{ 12,  4084},{ 10,  1007},{ 9,  498},
+		{ 8,  232},{ 7,  112},{ 8,  236},{ 9,  496},{ 10,  1002},
+		{ 11,  2035},{ 11,  2027},{ 9,  491},{ 8,  234},{ 5,  26},
+		{ 4,  8},{ 5,  25},{ 8,  238},{ 9,  495},{ 11,  2029},
+		{ 10,  1008},{ 8,  242},{ 7,  115},{ 4,  11},{ 1,  0},
+		{ 4,  10},{ 7,  113},{ 8,  243},{ 11,  2025},{ 11,  2031},
+		{ 9,  494},{ 8,  239},{ 5,  24},{ 4,  9},{ 5,  27},
+		{ 8,  235},{ 9,  489},{ 11,  2028},{ 11,  2038},{ 10,  1003},
+		{ 9,  499},{ 8,  237},{ 7,  114},{ 8,  233},{ 9,  497},
+		{ 10,  1005},{ 11,  2039},{ 12,  4086},{ 11,  2032},{ 10,  1001},
+		{ 9,  493},{ 8,  241},{ 9,  490},{ 10,  1004},{ 11,  2040},
+		{ 12,  4089},{ 13,  8188},{ 12,  4092},{ 12,  4085},{ 11,  2026},
+		{ 10,  1011},{ 10,  1010},{ 11,  2037},{ 12,  4091},{ 13,  8190}
+	};
+int huff6[][2] = {
+		{ 11,  2046},
+		{ 10,  1021},{ 9,  497},{ 9,  491},{ 9,  500},{ 9,  490},
+		{ 9,  496},{ 10,  1020},{ 11,  2045},{ 10,  1014},{ 9,  485},
+		{ 8,  234},{ 7,  108},{ 7,  113},{ 7,  104},{ 8,  240},
+		{ 9,  486},{ 10,  1015},{ 9,  499},{ 8,  239},{ 6,  50},
+		{ 6,  39},{ 6,  40},{ 6,  38},{ 6,  49},{ 8,  235},
+		{ 9,  503},{ 9,  488},{ 7,  111},{ 6,  46},{ 4,  8},
+		{ 4,  4},{ 4,  6},{ 6,  41},{ 7,  107},{ 9,  494},
+		{ 9,  495},{ 7,  114},{ 6,  45},{ 4,  2},{ 4,  0},
+		{ 4,  3},{ 6,  47},{ 7,  115},{ 9,  506},{ 9,  487},
+		{ 7,  110},{ 6,  43},{ 4,  7},{ 4,  1},{ 4,  5},
+		{ 6,  44},{ 7,  109},{ 9,  492},{ 9,  505},{ 8,  238},
+		{ 6,  48},{ 6,  36},{ 6,  42},{ 6,  37},{ 6,  51},
+		{ 8,  236},{ 9,  498},{ 10,  1016},{ 9,  484},{ 8,  237},
+		{ 7,  106},{ 7,  112},{ 7,  105},{ 7,  116},{ 8,  241},
+		{ 10,  1018},{ 11,  2047},{ 10,  1017},{ 9,  502},{ 9,  493},
+		{ 9,  504},{ 9,  489},{ 9,  501},{ 10,  1019},{ 11,  2044}
+	};
+int huff7[][2] = {
+		{ 1,  0},
+		{ 3,  5},{ 6,  55},{ 7,  116},{ 8,  242},{ 9,  491},
+		{ 10,  1005},{ 11,  2039},{ 3,  4},{ 4,  12},{ 6,  53},
+		{ 7,  113},{ 8,  236},{ 8,  238},{ 9,  494},{ 9,  501},
+		{ 6,  54},{ 6,  52},{ 7,  114},{ 8,  234},{ 8,  241},
+		{ 9,  489},{ 9,  499},{ 10,  1013},{ 7,  115},{ 7,  112},
+		{ 8,  235},{ 8,  240},{ 9,  497},{ 9,  496},{ 10,  1004},
+		{ 10,  1018},{ 8,  243},{ 8,  237},{ 9,  488},{ 9,  495},
+		{ 10,  1007},{ 10,  1009},{ 10,  1017},{ 11,  2043},{ 9,  493},
+		{ 8,  239},{ 9,  490},{ 9,  498},{ 10,  1011},{ 10,  1016},
+		{ 11,  2041},{ 11,  2044},{ 10,  1006},{ 9,  492},{ 9,  500},
+		{ 10,  1012},{ 10,  1015},{ 11,  2040},{ 12,  4093},{ 12,  4094},
+		{ 11,  2038},{ 10,  1008},{ 10,  1010},{ 10,  1014},{ 11,  2042},
+		{ 11,  2045},{ 12,  4092},{ 12,  4095}
+	};
+int huff8[][2] = {
+		{ 5,  14},
+		{ 4,  5},{ 5,  16},{ 6,  48},{ 7,  111},{ 8,  241},
+		{ 9,  506},{ 10,  1022},{ 4,  3},{ 3,  0},{ 4,  4},
+		{ 5,  18},{ 6,  44},{ 7,  106},{ 7,  117},{ 8,  248},
+		{ 5,  15},{ 4,  2},{ 4,  6},{ 5,  20},{ 6,  46},
+		{ 7,  105},{ 7,  114},{ 8,  245},{ 6,  47},{ 5,  17},
+		{ 5,  19},{ 6,  42},{ 6,  50},{ 7,  108},{ 8,  236},
+		{ 8,  250},{ 7,  113},{ 6,  43},{ 6,  45},{ 6,  49},
+		{ 7,  109},{ 7,  112},{ 8,  242},{ 9,  505},{ 8,  239},
+		{ 7,  104},{ 6,  51},{ 7,  107},{ 7,  110},{ 8,  238},
+		{ 8,  249},{ 10,  1020},{ 9,  504},{ 7,  116},{ 7,  115},
+		{ 8,  237},{ 8,  240},{ 8,  246},{ 9,  502},{ 9,  509},
+		{ 10,  1021},{ 8,  243},{ 8,  244},{ 8,  247},{ 9,  503},
+		{ 9,  507},{ 9,  508},{ 10,  1023}
+	};
+int huff9[][2] = {
+		{ 1,  0},
+		{ 3,  5},{ 6,  55},{ 8,  231},{ 9,  478},{ 10,  974},
+		{ 10,  985},{ 11,  1992},{ 11,  1997},{ 12,  4040},{ 12,  4061},
+		{ 13,  8164},{ 13,  8172},{ 3,  4},{ 4,  12},{ 6,  53},
+		{ 7,  114},{ 8,  234},{ 8,  237},{ 9,  482},{ 10,  977},
+		{ 10,  979},{ 10,  992},{ 11,  2008},{ 12,  4047},{ 12,  4053},
+		{ 6,  54},{ 6,  52},{ 7,  113},{ 8,  232},{ 8,  236},
+		{ 9,  481},{ 10,  975},{ 10,  989},{ 10,  987},{ 11,  2000},
+		{ 12,  4039},{ 12,  4052},{ 12,  4068},{ 8,  230},{ 7,  112},
+		{ 8,  233},{ 9,  477},{ 9,  483},{ 10,  978},{ 10,  988},
+		{ 11,  1996},{ 11,  1994},{ 11,  2014},{ 12,  4056},{ 12,  4074},
+		{ 13,  8155},{ 9,  479},{ 8,  235},{ 9,  476},{ 9,  486},
+		{ 10,  981},{ 10,  990},{ 11,  1995},{ 11,  2013},{ 11,  2012},
+		{ 12,  4045},{ 12,  4066},{ 12,  4071},{ 13,  8161},{ 10,  976},
+		{ 9,  480},{ 9,  484},{ 10,  982},{ 11,  1989},{ 11,  2001},
+		{ 11,  2011},{ 12,  4050},{ 11,  2016},{ 12,  4057},{ 12,  4075},
+		{ 13,  8163},{ 13,  8169},{ 11,  1988},{ 9,  485},{ 10,  983},
+		{ 11,  1990},{ 11,  1999},{ 11,  2010},{ 12,  4043},{ 12,  4058},
+		{ 12,  4067},{ 12,  4073},{ 13,  8166},{ 13,  8179},{ 13,  8183},
+		{ 11,  2003},{ 10,  984},{ 10,  993},{ 11,  2004},{ 11,  2009},
+		{ 12,  4051},{ 12,  4062},{ 13,  8157},{ 13,  8153},{ 13,  8162},
+		{ 13,  8170},{ 13,  8177},{ 13,  8182},{ 11,  2002},{ 10,  980},
+		{ 10,  986},{ 11,  1991},{ 11,  2007},{ 11,  2018},{ 12,  4046},
+		{ 12,  4059},{ 13,  8152},{ 13,  8174},{ 14,  16368},{ 13,  8180},
+		{ 14,  16370},{ 11,  2017},{ 10,  991},{ 11,  1993},{ 11,  2006},
+		{ 12,  4042},{ 12,  4048},{ 12,  4069},{ 12,  4070},{ 13,  8171},
+		{ 13,  8175},{ 14,  16371},{ 14,  16372},{ 14,  16373},{ 12,  4064},
+		{ 11,  1998},{ 11,  2005},{ 12,  4038},{ 12,  4049},{ 12,  4065},
+		{ 13,  8160},{ 13,  8168},{ 13,  8176},{ 14,  16369},{ 14,  16376},
+		{ 14,  16374},{ 15,  32764},{ 12,  4072},{ 11,  2015},{ 12,  4041},
+		{ 12,  4055},{ 12,  4060},{ 13,  8156},{ 13,  8159},{ 13,  8173},
+		{ 13,  8181},{ 14,  16377},{ 14,  16379},{ 15,  32765},{ 15,  32766},
+		{ 13,  8167},{ 12,  4044},{ 12,  4054},{ 12,  4063},{ 13,  8158},
+		{ 13,  8154},{ 13,  8165},{ 13,  8178},{ 14,  16378},{ 14,  16375},
+		{ 14,  16380},{ 14,  16381},{ 15,  32767}
+	};
+int huff10[][2] = {
+		{ 6,  34},
+		{ 5,  8},{ 6,  29},{ 6,  38},{ 7,  95},{ 8,  211},
+		{ 9,  463},{ 10,  976},{ 10,  983},{ 10,  1005},{ 11,  2032},
+		{ 11,  2038},{ 12,  4093},{ 5,  7},{ 4,  0},{ 4,  1},
+		{ 5,  9},{ 6,  32},{ 7,  84},{ 7,  96},{ 8,  213},
+		{ 8,  220},{ 9,  468},{ 10,  973},{ 10,  990},{ 11,  2023},
+		{ 6,  28},{ 4,  2},{ 5,  6},{ 5,  12},{ 6,  30},
+		{ 6,  40},{ 7,  91},{ 8,  205},{ 8,  217},{ 9,  462},
+		{ 9,  476},{ 10,  985},{ 10,  1009},{ 6,  37},{ 5,  11},
+		{ 5,  10},{ 5,  13},{ 6,  36},{ 7,  87},{ 7,  97},
+		{ 8,  204},{ 8,  221},{ 9,  460},{ 9,  478},{ 10,  979},
+		{ 10,  999},{ 7,  93},{ 6,  33},{ 6,  31},{ 6,  35},
+		{ 6,  39},{ 7,  89},{ 7,  100},{ 8,  216},{ 8,  223},
+		{ 9,  466},{ 9,  482},{ 10,  989},{ 10,  1006},{ 8,  209},
+		{ 7,  85},{ 6,  41},{ 7,  86},{ 7,  88},{ 7,  98},
+		{ 8,  206},{ 8,  224},{ 8,  226},{ 9,  474},{ 10,  980},
+		{ 10,  995},{ 11,  2027},{ 9,  457},{ 7,  94},{ 7,  90},
+		{ 7,  92},{ 7,  99},{ 8,  202},{ 8,  218},{ 9,  455},
+		{ 9,  458},{ 9,  480},{ 10,  987},{ 10,  1000},{ 11,  2028},
+		{ 9,  483},{ 8,  210},{ 8,  203},{ 8,  208},{ 8,  215},
+		{ 8,  219},{ 9,  454},{ 9,  469},{ 9,  472},{ 10,  970},
+		{ 10,  986},{ 11,  2026},{ 11,  2033},{ 9,  481},{ 8,  212},
+		{ 8,  207},{ 8,  214},{ 8,  222},{ 8,  225},{ 9,  464},
+		{ 9,  470},{ 10,  977},{ 10,  981},{ 10,  1010},{ 11,  2030},
+		{ 11,  2043},{ 10,  1001},{ 9,  461},{ 9,  456},{ 9,  459},
+		{ 9,  465},{ 9,  471},{ 9,  479},{ 10,  975},{ 10,  992},
+		{ 10,  1007},{ 11,  2022},{ 11,  2040},{ 12,  4090},{ 10,  1003},
+		{ 9,  477},{ 9,  467},{ 9,  473},{ 9,  475},{ 10,  978},
+		{ 10,  972},{ 10,  988},{ 10,  1002},{ 11,  2029},{ 11,  2035},
+		{ 11,  2041},{ 12,  4089},{ 11,  2034},{ 10,  974},{ 9,  484},
+		{ 10,  971},{ 10,  984},{ 10,  982},{ 10,  994},{ 10,  997},
+		{ 11,  2024},{ 11,  2036},{ 11,  2037},{ 11,  2039},{ 12,  4091},
+		{ 11,  2042},{ 10,  1004},{ 10,  991},{ 10,  993},{ 10,  996},
+		{ 10,  998},{ 10,  1008},{ 11,  2025},{ 11,  2031},{ 12,  4088},
+		{ 12,  4094},{ 12,  4092},{ 12,  4095}
+	};
+int huff11[][2] = {
+		{ 4,  0},
+		{ 5,  6},{ 6,  25},{ 7,  61},{ 8,  156},{ 8,  198},
+		{ 9,  423},{ 10,  912},{ 10,  962},{ 10,  991},{ 11,  2022},
+		{ 11,  2035},{ 12,  4091},{ 11,  2028},{ 12,  4090},{ 12,  4094},
+		{ 10,  910},{ 5,  5},{ 4,  1},{ 5,  8},{ 6,  20},
+		{ 7,  55},{ 7,  66},{ 8,  146},{ 8,  175},{ 9,  401},
+		{ 9,  421},{ 9,  437},{ 10,  926},{ 10,  960},{ 10,  930},
+		{ 10,  973},{ 11,  2006},{ 8,  174},{ 6,  23},{ 5,  7},
+		{ 5,  9},{ 6,  24},{ 7,  57},{ 7,  64},{ 8,  142},
+		{ 8,  163},{ 8,  184},{ 9,  409},{ 9,  428},{ 9,  449},
+		{ 10,  945},{ 10,  918},{ 10,  958},{ 10,  970},{ 8,  157},
+		{ 7,  60},{ 6,  21},{ 6,  22},{ 6,  26},{ 7,  59},
+		{ 7,  68},{ 8,  145},{ 8,  165},{ 8,  190},{ 9,  406},
+		{ 9,  430},{ 9,  441},{ 10,  929},{ 10,  913},{ 10,  933},
+		{ 10,  981},{ 8,  148},{ 8,  154},{ 7,  54},{ 7,  56},
+		{ 7,  58},{ 7,  65},{ 8,  140},{ 8,  155},{ 8,  176},
+		{ 8,  195},{ 9,  414},{ 9,  427},{ 9,  444},{ 10,  927},
+		{ 10,  911},{ 10,  937},{ 10,  975},{ 8,  147},{ 8,  191},
+		{ 7,  62},{ 7,  63},{ 7,  67},{ 7,  69},{ 8,  158},
+		{ 8,  167},{ 8,  185},{ 9,  404},{ 9,  418},{ 9,  442},
+		{ 9,  451},{ 10,  934},{ 10,  935},{ 10,  955},{ 10,  980},
+		{ 8,  159},{ 9,  416},{ 8,  143},{ 8,  141},{ 8,  144},
+		{ 8,  152},{ 8,  166},{ 8,  182},{ 8,  196},{ 9,  415},
+		{ 9,  431},{ 9,  447},{ 10,  921},{ 10,  959},{ 10,  948},
+		{ 10,  969},{ 10,  999},{ 8,  168},{ 9,  438},{ 8,  171},
+		{ 8,  164},{ 8,  170},{ 8,  178},{ 8,  194},{ 8,  197},
+		{ 9,  408},{ 9,  420},{ 9,  440},{ 10,  908},{ 10,  932},
+		{ 10,  964},{ 10,  966},{ 10,  989},{ 10,  1000},{ 8,  173},
+		{ 10,  943},{ 9,  402},{ 8,  189},{ 8,  188},{ 9,  398},
+		{ 9,  407},{ 9,  410},{ 9,  419},{ 9,  433},{ 10,  909},
+		{ 10,  920},{ 10,  951},{ 10,  979},{ 10,  977},{ 10,  987},
+		{ 11,  2013},{ 8,  180},{ 10,  990},{ 9,  425},{ 9,  411},
+		{ 9,  412},{ 9,  417},{ 9,  426},{ 9,  429},{ 9,  435},
+		{ 10,  907},{ 10,  946},{ 10,  952},{ 10,  974},{ 10,  993},
+		{ 10,  992},{ 11,  2002},{ 11,  2021},{ 8,  183},{ 11,  2019},
+		{ 9,  443},{ 9,  424},{ 9,  422},{ 9,  432},{ 9,  434},
+		{ 9,  439},{ 10,  923},{ 10,  922},{ 10,  954},{ 10,  949},
+		{ 10,  982},{ 11,  2007},{ 10,  996},{ 11,  2008},{ 11,  2026},
+		{ 8,  186},{ 11,  2024},{ 10,  928},{ 9,  445},{ 9,  436},
+		{ 10,  906},{ 9,  452},{ 10,  914},{ 10,  938},{ 10,  944},
+		{ 10,  956},{ 10,  983},{ 11,  2004},{ 11,  2012},{ 11,  2011},
+		{ 11,  2005},{ 11,  2032},{ 8,  193},{ 11,  2043},{ 10,  968},
+		{ 10,  931},{ 10,  917},{ 10,  925},{ 10,  940},{ 10,  942},
+		{ 10,  965},{ 10,  984},{ 10,  994},{ 10,  998},{ 11,  2020},
+		{ 11,  2023},{ 11,  2016},{ 11,  2025},{ 11,  2039},{ 9,  400},
+		{ 11,  2034},{ 10,  915},{ 9,  446},{ 9,  448},{ 10,  916},
+		{ 10,  919},{ 10,  941},{ 10,  963},{ 10,  961},{ 10,  978},
+		{ 11,  2010},{ 11,  2009},{ 11,  2015},{ 11,  2027},{ 11,  2036},
+		{ 11,  2042},{ 9,  405},{ 11,  2040},{ 10,  957},{ 10,  924},
+		{ 10,  939},{ 10,  936},{ 10,  947},{ 10,  953},{ 10,  976},
+		{ 10,  995},{ 10,  997},{ 11,  2018},{ 11,  2014},{ 11,  2029},
+		{ 11,  2033},{ 11,  2041},{ 11,  2044},{ 9,  403},{ 12,  4093},
+		{ 10,  988},{ 10,  950},{ 10,  967},{ 10,  972},{ 10,  971},
+		{ 10,  985},{ 10,  986},{ 11,  2003},{ 11,  2017},{ 11,  2030},
+		{ 11,  2031},{ 11,  2037},{ 11,  2038},{ 12,  4092},{ 12,  4095},
+		{ 9,  413},{ 9,  450},{ 8,  181},{ 8,  161},{ 8,  150},
+		{ 8,  151},{ 8,  149},{ 8,  153},{ 8,  160},{ 8,  162},
+		{ 8,  172},{ 8,  169},{ 8,  177},{ 8,  179},{ 8,  187},
+		{ 8,  192},{ 9,  399},{ 5,  4}
+	};
+int huff12[][2] = {
+		{ 18,  262120},
+		{ 18,  262118},{ 18,  262119},{ 18,  262117},{ 19,  524277},{ 19,  524273},
+		{ 19,  524269},{ 19,  524278},{ 19,  524270},{ 19,  524271},{ 19,  524272},
+		{ 19,  524284},{ 19,  524285},{ 19,  524287},{ 19,  524286},{ 19,  524279},
+		{ 19,  524280},{ 19,  524283},{ 19,  524281},{ 18,  262116},{ 19,  524282},
+		{ 18,  262115},{ 17,  131055},{ 17,  131056},{ 16,  65525},{ 17,  131054},
+		{ 16,  65522},{ 16,  65523},{ 16,  65524},{ 16,  65521},{ 15,  32758},
+		{ 15,  32759},{ 14,  16377},{ 14,  16373},{ 14,  16375},{ 14,  16371},
+		{ 14,  16374},{ 14,  16370},{ 13,  8183},{ 13,  8181},{ 12,  4089},
+		{ 12,  4087},{ 12,  4086},{ 11,  2041},{ 12,  4084},{ 11,  2040},
+		{ 10,  1017},{ 10,  1015},{ 10,  1013},{ 9,  504},{ 9,  503},
+		{ 8,  250},{ 8,  248},{ 8,  246},{ 7,  121},{ 6,  58},
+		{ 6,  56},{ 5,  26},{ 4,  11},{ 3,  4},{ 1,  0},
+		{ 4,  10},{ 4,  12},{ 5,  27},{ 6,  57},{ 6,  59},
+		{ 7,  120},{ 7,  122},{ 8,  247},{ 8,  249},{ 9,  502},
+		{ 9,  505},{ 10,  1012},{ 10,  1014},{ 10,  1016},{ 11,  2037},
+		{ 11,  2036},{ 11,  2038},{ 11,  2039},{ 12,  4085},{ 12,  4088},
+		{ 13,  8180},{ 13,  8182},{ 13,  8184},{ 14,  16376},{ 14,  16372},
+		{ 16,  65520},{ 15,  32756},{ 16,  65526},{ 15,  32757},{ 18,  262114},
+		{ 19,  524249},{ 19,  524250},{ 19,  524251},{ 19,  524252},{ 19,  524253},
+		{ 19,  524254},{ 19,  524248},{ 19,  524242},{ 19,  524243},{ 19,  524244},
+		{ 19,  524245},{ 19,  524246},{ 19,  524274},{ 19,  524255},{ 19,  524263},
+		{ 19,  524264},{ 19,  524265},{ 19,  524266},{ 19,  524267},{ 19,  524262},
+		{ 19,  524256},{ 19,  524257},{ 19,  524258},{ 19,  524259},{ 19,  524260},
+		{ 19,  524261},{ 19,  524247},{ 19,  524268},{ 19,  524276},{ 19,  524275}
+	};
+
+
--- /dev/null
+++ b/imdct.c
@@ -1,0 +1,189 @@
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "tf_main.h"
+#include "transfo.h"
+#include "block.h"
+#include "dolby_win.h"
+
+#define DPI	3.14159265358979323846264338327950288
+
+static double zero = 0;
+
+static void vcopy( double src[], double dest[], int inc_src, int inc_dest, int vlen )
+{
+	int i;
+
+	for( i=0; i<vlen; i++ ) {
+		*dest = *src;
+		dest += inc_dest;
+		src  += inc_src;
+	}
+}
+
+static void vmult( double src1[], double src2[], double dest[], 
+            int inc_src1, int inc_src2, int inc_dest, int vlen )
+{
+	int i;
+
+	for( i=0; i<vlen; i++ ) {
+		*dest = *src1 * *src2;
+		dest += inc_dest;
+		src1 += inc_src1;
+		src2 += inc_src2;
+	}
+}
+
+static void vadd( double src1[], double src2[], double dest[], 
+            int inc_src1, int inc_src2, int inc_dest, int vlen )
+{
+	int i;
+
+	for( i=0; i<vlen; i++ ) {
+		*dest = *src1 + *src2;
+		dest += inc_dest;
+		src1 += inc_src1;
+		src2 += inc_src2;
+	}
+}
+ 
+
+/* Calculate window */
+void calc_window( double window[], int len, Window_shape wfun_select )
+{
+	int i;
+	extern double dolby_win_1024[];
+	extern double dolby_win_128[];
+
+	switch(wfun_select)
+    {
+    case WS_FHG: 
+		for( i=0; i<len; i++ )
+			window[i] = sin((DPI/(2*len)) * (i + 0.5));
+		break;
+		
+    case WS_DOLBY: 
+		switch(len)
+		{
+		case BLOCK_LEN_SHORT:
+			for( i=0; i<len; i++ ) 
+				window[i] = dolby_win_128[i]; 
+			break;
+		case BLOCK_LEN_LONG:
+			for( i=0; i<len; i++ ) 
+				window[i] = dolby_win_1024[i]; 
+			break;
+		}
+		break;
+    }
+}
+#define MAX_SHIFT_LEN_LONG 4096
+
+/* %%%%%%%%%%%%%%%%% MDCT - STUFF %%%%%%%%%%%%%%%% */
+
+void mdct( double in_data[], double out_data[], int len )
+{
+	vcopy(in_data, out_data, 1, 1, len); 
+	MDCT(out_data, len);
+}
+
+void buffer2freq(
+  double           p_in_data[], 
+  double           p_out_mdct[],
+  double           p_overlap[],
+  enum WINDOW_TYPE block_type,
+  Window_shape     wfun_select,      /* offers the possibility to select different window functions */
+  int              nlong,            /* shift length for long windows   */
+  int              nmed,             /* shift length for medium windows */
+  int              nshort,           /* shift length for short windows  */
+  Mdct_in      overlap_select     /*  YT 970615 for son_PP */
+)
+{
+	double         transf_buf[ 2*MAX_SHIFT_LEN_LONG ];
+	double         windowed_buf[ 2*MAX_SHIFT_LEN_LONG ];
+	double         *p_o_buf;
+	int            k;
+
+	double           window_long[MAX_SHIFT_LEN_LONG]; 
+	double           window_long_prev[MAX_SHIFT_LEN_LONG]; 
+	double           window_short[MAX_SHIFT_LEN_LONG]; 
+	double           window_short_prev[MAX_SHIFT_LEN_LONG]; 
+	double           *window_short_prev_ptr;
+
+	int nflat_ls    = (nlong-nshort)/ 2; 
+	int transfak_ls =  nlong/nshort; 
+	
+	static Window_shape wfun_select_prev=WS_FHG;
+	static int firstTime=1;
+	window_short_prev_ptr = window_short_prev ; 
+
+	calc_window( window_long,      nlong, wfun_select ); 
+	calc_window( window_long_prev, nlong, wfun_select_prev ); 
+	calc_window( window_short,      nshort, wfun_select ); 
+	calc_window( window_short_prev, nshort, wfun_select_prev ); 
+	
+	/* create / shift old values */
+	/* We use p_overlap here as buffer holding the last frame time signal*/
+	/* YT 970615 for son_pp */
+	if (firstTime){
+		firstTime=0;
+		vcopy( &zero, transf_buf, 0, 1, nlong );
+	} else
+		vcopy( p_overlap, transf_buf, 1, 1, nlong );
+
+	/* Append new data */
+	vcopy( p_in_data, transf_buf+nlong, 1, 1, nlong );
+	vcopy( p_in_data, p_overlap,        1, 1, nlong );
+
+	/* Set ptr to transf-Buffer */
+	p_o_buf = transf_buf;
+	
+	
+	/* Separate action for each Block Type */
+	switch( block_type ) {
+	case ONLY_LONG_WINDOW :
+		vmult( p_o_buf, window_long_prev, windowed_buf,       1, 1,  1, nlong );
+		vmult( p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, 1, -1, 1, nlong );
+		mdct( windowed_buf, p_out_mdct, 2*nlong );    
+		break;
+		
+	case LONG_SHORT_WINDOW :
+		vmult( p_o_buf, window_long_prev, windowed_buf, 1, 1, 1, nlong );
+		vcopy( p_o_buf+nlong, windowed_buf+nlong, 1, 1, nflat_ls );
+		vmult( p_o_buf+nlong+nflat_ls, window_short+nshort-1, windowed_buf+nlong+nflat_ls, 1, -1, 1, nshort );
+		vcopy( &zero, windowed_buf+2*nlong-1, 0, -1, nflat_ls );
+		mdct( windowed_buf, p_out_mdct, 2*nlong );
+		break;
+
+	case SHORT_LONG_WINDOW :
+		vcopy( &zero, windowed_buf, 0, 1, nflat_ls );
+		vmult( p_o_buf+nflat_ls, window_short_prev_ptr, windowed_buf+nflat_ls, 1, 1, 1, nshort );
+		vcopy( p_o_buf+nflat_ls+nshort, windowed_buf+nflat_ls+nshort, 1, 1, nflat_ls );
+		vmult( p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, 1, -1, 1, nlong );
+		mdct( windowed_buf, p_out_mdct, 2*nlong );
+		break;
+
+	case ONLY_SHORT_WINDOW :
+		p_o_buf += nflat_ls;
+		for (k=transfak_ls-1; k-->=0; ) {
+			vmult( p_o_buf,        window_short_prev_ptr,          windowed_buf,        1, 1,  1, nshort );
+			vmult( p_o_buf+nshort, window_short+nshort-1, windowed_buf+nshort, 1, -1, 1, nshort );
+			mdct( windowed_buf, p_out_mdct, 2*nshort );
+
+			p_out_mdct += nshort;
+			/* YT 970615 for sonPP*/
+			p_o_buf += nshort;
+			window_short_prev_ptr = window_short; 
+		}
+		break;
+	}
+
+	/* Set output data 
+	vcopy(transf_buf, p_out_mdct,1, 1, nlong); */
+	
+	/* --- Save old window shape --- */
+	wfun_select_prev = wfun_select;
+}
+
+/***********************************************************************************************/ 
--- /dev/null
+++ b/interface.h
@@ -1,0 +1,214 @@
+/************************* 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.
+ *                                                                           *
+ ****************************************************************************/
+#ifndef _interface_h_
+#define _interface_h_
+
+/*
+ * interface between the encoder and decoder
+ */
+
+#define C_LN10		2.30258509299404568402		/* ln(10) */
+#define C_PI		3.14159265358979323846		/* pi */
+#define C_SQRT2		1.41421356237309504880		/* sqrt(2) */
+
+#define MINTHR		.5
+#define SF_C1		(13.33333/1.333333)
+
+/* prediction */
+#define	PRED_ORDER	2
+#define PRED_ALPHA	0.9
+#define PRED_A		0.95
+#define PRED_B		0.95
+
+enum
+{
+    /* 
+     * block switching
+     */
+    LN			= 2048,
+    SN			= 256,
+    LN2			= LN/2,
+    SN2			= SN/2,
+    LN4			= LN/4,
+    SN4			= SN/4,
+    NSHORT		= LN/SN,
+    MAX_SBK		= NSHORT,
+
+    NUM_WIN_SEQ,
+    WLONG		= 0, /* ONLY_LONG_WINDOW,  */
+    WSTART, 
+    WSHORT, 
+    WSTOP, 
+    
+    MAXBANDS		= 16*NSHORT,	/* max number of scale factor bands ((NSFB_SHORT+1)*MAX_SHORT_IN_LONG_BLOCK) */
+    MAXFAC		= 121,		/* maximum scale factor */
+    MIDFAC		= (MAXFAC-1)/2,
+    SF_OFFSET		= 100,		/* global gain must be positive */
+
+    /*
+     * specify huffman tables as signed (1) or unsigned (0)
+     */
+    HUF1SGN		= 1, 
+    HUF2SGN		= 1, 
+    HUF3SGN		= 0, 
+    HUF4SGN		= 0, 
+    HUF5SGN		= 1, 
+    HUF6SGN		= 1, 
+    HUF7SGN		= 0, 
+    HUF8SGN		= 0, 
+    HUF9SGN		= 0, 
+    HUF10SGN		= 0, 
+    HUF11SGN		= 0, 
+
+    BY4BOOKS		= 4,
+    ESCBOOK		= 11,
+    NSPECBOOKS		= ESCBOOK + 1,
+    BOOKSCL		= NSPECBOOKS,
+    NBOOKS		= NSPECBOOKS+1,
+    INTENSITY_HCB	= 15,
+    INTENSITY_HCB2	= 14,
+    
+    LONG_SECT_BITS	= 5, 
+    SHORT_SECT_BITS	= 3, 
+
+    /*
+     * Program Configuration
+     */
+    Main_Profile	= 0, 
+    LC_Profile		= 1, 
+    SRS_Profile		= 2,
+
+    Fs_48		= 3, 
+    Fs_44		= 4, 
+    Fs_32		= 5, 
+
+    /*
+     * Misc constants
+     */
+    CC_DOM		= 0,	/* before TNS */ 
+    CC_IND		= 1,  
+     
+    /* 
+     * Raw bitstream constants
+     */
+    LEN_SE_ID		= 3,
+    LEN_TAG		= 4,
+    LEN_GLOB_GAIN       = 8,
+    LEN_COM_WIN		= 1,
+    LEN_ICS_RESERV	= 1, 
+    LEN_WIN_SEQ		= 2,
+    LEN_WIN_SH		= 1,
+    LEN_MAX_SFBL	= 6, 
+    LEN_MAX_SFBS	= 4, 
+    LEN_CB		= 4,
+    LEN_SCL_PCM		= 8,
+    LEN_PRED_PRES	= 1,
+    LEN_PRED_RST	= 1,
+    LEN_PRED_RSTGRP	= 5,
+    LEN_PRED_ENAB	= 1,
+    LEN_MASK_PRES	= 2,
+    LEN_MASK		= 1,
+    LEN_PULSE_PRES	= 1,
+    LEN_TNS_PRES	= 1,
+    LEN_TNS_NFILTL      = 2,
+    LEN_TNS_NFILTS      = 1,
+    LEN_TNS_COEFF_RES   = 1,
+    LEN_TNS_LENGTHL     = 6,
+    LEN_TNS_LENGTHS     = 4,
+    LEN_TNS_ORDERL      = 5,
+    LEN_TNS_ORDERS      = 3,
+    LEN_TNS_DIRECTION   = 1,
+    LEN_TNS_COMPRESS    = 1,
+    LEN_GAIN_PRES	= 1,
+
+    LEN_NEC_NPULSE	= 2, 
+    LEN_NEC_ST_SFB	= 6, 
+    LEN_NEC_POFF	= 5, 
+    LEN_NEC_PAMP	= 4, 
+    NUM_NEC_LINES	= 4, 
+    NEC_OFFSET_AMP	= 4, 
+
+    LEN_NCC		= 3,
+    LEN_IS_CPE		= 1, 
+    LEN_CC_LR		= 1,
+    LEN_CC_DOM		= 1,
+    LEN_CC_SGN		= 1,
+    LEN_CCH_GES		= 2,
+    LEN_CCH_CGP		= 1,
+
+    LEN_D_CNT		= 4,
+    LEN_D_ESC		= 12,
+    LEN_F_CNT		= 4,
+    LEN_F_ESC		= 8,
+    LEN_BYTE		= 8,
+    LEN_PAD_DATA	= 8,
+
+    LEN_PC_COMM		= 8, 
+
+    /* sfb 40, coef 672, pred bw of 15.75 kHz */
+    MAX_PRED_SFB	= 48,  // Max = 48, was 40
+
+    ID_SCE 		= 0,
+    ID_CPE,
+    ID_CCE,
+    ID_LFE,
+    ID_DSE,
+    ID_PCE,
+    ID_FIL,
+    ID_END,
+
+    /* PLL's don't like idle channels! */
+    FILL_VALUE		= 0x55,
+
+    /*
+     * program configuration element
+     */
+    LEN_PROFILE		= 2, 
+    LEN_SAMP_IDX	= 4, 
+    LEN_NUM_ELE		= 4, 
+    LEN_NUM_LFE		= 2, 
+    LEN_NUM_DAT		= 3, 
+    LEN_NUM_CCE		= 4, 
+    LEN_MIX_PRES	= 1, 
+    LEN_ELE_IS_CPE	= 1,
+    LEN_IND_SW_CCE	= 1,  
+    LEN_COMMENT_BYTES	= 8, 
+         
+    /*
+     * audio data interchange format header
+     */
+    LEN_ADIF_ID		= (32/8), 
+    LEN_COPYRT_PRES	= 1, 
+    LEN_COPYRT_ID	= (72/8), 
+    LEN_ORIG		= 1, 
+    LEN_HOME		= 1, 
+    LEN_BS_TYPE		= 1, 
+    LEN_BIT_RATE	= 23, 
+    LEN_NUM_PCE		= 4, 
+    LEN_ADIF_BF		= 20, 
+    XXX
+};
+
+#endif   /* #ifndef _interface_h_ */
+
--- /dev/null
+++ b/is.c
@@ -1,0 +1,143 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+"This software module was originally developed 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/*******************************************************************************************
+ *
+ * IS stereo coding module
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.  Simple IS stereo support.
+ ***************************************************************************************/
+
+
+#include "is.h"
+
+/* Perform IS encoding.  Spectrum is non-interleaved.  */
+/* This would be a lot simpler on interleaved spectral data */
+void ISEncode(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+	      AACQuantInfo* quantInfo,
+	      int numberOfChannels)
+{
+	int chanNum;
+	int sfbNum;
+	int lineNum,line_offset;
+	int startWindow,stopWindow,w;
+
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+				channelInfo[leftChan].is_info.is_present=0;
+				channelInfo[rightChan].is_info.is_present=0;
+
+				/* Perform IS if block_types are the same */
+				if (block_type[leftChan]==block_type[rightChan]) {
+					int numGroups;
+					int maxSfb;
+					int g,b,minBand;
+					IS_Info *isInfo;
+
+					channelInfo[leftChan].common_window = 1;  /* Use common window */
+					channelInfo[rightChan].is_info.is_present=1;
+
+					numGroups = quantInfo[leftChan].num_window_groups;
+					maxSfb = quantInfo[leftChan].max_sfb;
+
+					/* Currently, enable Intensity Stereo above band IS_MIN_BAND */
+					isInfo = &(channelInfo[rightChan].is_info);
+					minBand = (block_type[rightChan]==ONLY_SHORT_WINDOW) ? IS_MIN_BAND_S : IS_MIN_BAND_L;
+					minBand = (minBand>maxSfb) ? maxSfb : minBand;
+					startWindow=0;
+					for (g=0;g<numGroups;g++) {
+
+						int numWindows;
+
+						/* Disable lower frequency bands */
+						for (sfbNum=0;sfbNum<minBand;sfbNum++) {
+							b = g*maxSfb+sfbNum;
+							isInfo->is_used[b] = 0;  /* Disable IS */
+						}
+
+						/* Enable IS bands */
+						numWindows = quantInfo[leftChan].window_group_length[g];
+						stopWindow = startWindow + numWindows;
+						for (sfbNum=minBand;sfbNum<maxSfb;sfbNum++) {
+							double ratio,log_ratio;
+							int is_position;
+
+							/* First, compute energies and intensity stereo position */
+							double energy_l=0.0;   /* Left channel energy */
+							double energy_r=0.0;   /* Right channel energy */
+							double energy_s=0.0;   /* Sum channel energy */
+							for (w=startWindow;w<stopWindow;w++) {
+								line_offset = w*BLOCK_LEN_SHORT;
+								for (lineNum=sfb_offset_table[rightChan][sfbNum];
+								lineNum<sfb_offset_table[rightChan][sfbNum+1];
+								lineNum++) {
+									double l = spectrum[leftChan][line_offset+lineNum];
+									double r = spectrum[rightChan][line_offset+lineNum];
+									double s = l+r;
+									energy_l += l*l;
+									energy_r += r*r;
+									energy_s += s*s;
+								}
+							}
+							b = g*maxSfb+sfbNum;
+							ratio = energy_l/energy_r;
+							log_ratio = 2.0 * log(ratio) / log(2.0);
+							is_position = (int) floor( log_ratio + 0.5);
+							isInfo->fac[b] = is_position;
+							quantInfo[rightChan].scale_factor[b] = is_position;
+							isInfo->is_used[b] = 1;  /* Enable IS */
+							isInfo->sign[b] = 0;     /* In phase only */
+
+							/* Now replace right and left spectral coefficients */
+							for (w=startWindow;w<stopWindow;w++) {
+								line_offset = w*BLOCK_LEN_SHORT;
+								for (lineNum=sfb_offset_table[rightChan][sfbNum];
+								lineNum<sfb_offset_table[rightChan][sfbNum+1];
+								lineNum++) {
+									double l = spectrum[leftChan][line_offset+lineNum];
+									double r = spectrum[rightChan][line_offset+lineNum];
+									double new_spec = (l+r) * sqrt(energy_l/(energy_s+1));
+									spectrum[leftChan][line_offset+lineNum] = new_spec;  /* Replace left */
+									spectrum[rightChan][line_offset+lineNum] = 0.0;
+								}
+							}
+						}
+						startWindow = stopWindow;
+					}
+				}  /* if (block_type... */
+			}  /* if ((channelInfo... */
+		}  /* if (channelInfo... */
+	}  /* for (chanNum... */
+} 
+
--- /dev/null
+++ b/is.h
@@ -1,0 +1,40 @@
+/*******************************************************************************************
+ *
+ * IS stereo coding module
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.  Simple IS stereo support.
+ ***************************************************************************************/
+
+#ifndef IS_ENC
+#define IS_ENC
+
+#include "all.h"
+#include "tf_main.h"
+#include "aac_qc.h"
+#include "math.h"
+
+#define IS_MIN_BAND_L 28
+#define IS_MIN_BAND_S 7
+
+void ISEncode(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+	      AACQuantInfo* quantInfo,
+	      int numberOfChannels);                 /* Number of channels */
+
+void ISReconstruct(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+		   Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+		   int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+		   enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+		   AACQuantInfo* quantInfo,
+		   int numberOfChannels);                 /* Number of channels */
+
+
+
+#endif
+
--- /dev/null
+++ b/mc_enc.c
@@ -1,0 +1,84 @@
+/*******************************************************************************************
+ *
+ * Multichannel allocation module.
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * RG    Ralf Geiger, FhG/IIS
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.
+ * 07-apr-98   RG   Added determination of LFE channel.
+ ***************************************************************************************/
+
+#include "mc_enc.h"
+
+void DetermineChInfo(Ch_Info* chInfo, int numChannels) {
+   
+  /* If LFE present                                                       */
+  /*  Num channels       # of SCE's       # of CPE's       #of LFE's      */ 
+  /*  ============       ==========       ==========       =========      */
+  /*      1                  1                0               0           */
+  /*      2                  0                1               0           */
+  /*      3                  1                1               0           */
+  /*      4                  1                1               1           */
+  /*      5                  1                2               0           */
+  /* For more than 5 channels, use the following elements:                */
+  /*      2*N                1                2*(N-1)         1           */
+  /*      2*N+1              1                2*N             0           */
+  /*                                                                      */
+  /* Else:                                                                */
+  /*                                                                      */  
+  /*  Num channels       # of SCE's       # of CPE's       #of LFE's      */
+  /*  ============       ==========       ==========       =========      */
+  /*      1                  1                0               0           */
+  /*      2                  0                1               0           */
+  /*      3                  1                1               0           */
+  /*      4                  2                1               0           */
+  /*      5                  1                2               0           */
+  /* For more than 5 channels, use the following elements:                */
+  /*      2*N                2                2*(N-1)         0           */
+  /*      2*N+1              1                2*N             0           */
+
+  int sceTag=0;
+  int cpeTag=0;
+  int numChannelsLeft=numChannels;
+
+ 
+  /* First element is sce, except for 2 channel case */
+  if (numChannelsLeft!=2) {
+    chInfo[numChannels-numChannelsLeft].present = 1;
+    chInfo[numChannels-numChannelsLeft].tag=sceTag++;
+    chInfo[numChannels-numChannelsLeft].cpe=0;
+    numChannelsLeft--;
+  }
+
+  /* Next elements are cpe's */
+  while (numChannelsLeft>1) {
+    /* Left channel info */
+    chInfo[numChannels-numChannelsLeft].present = 1;
+    chInfo[numChannels-numChannelsLeft].tag=cpeTag++;
+    chInfo[numChannels-numChannelsLeft].cpe=1;
+    chInfo[numChannels-numChannelsLeft].common_window=0;
+    chInfo[numChannels-numChannelsLeft].ch_is_left=1;
+    chInfo[numChannels-numChannelsLeft].paired_ch=numChannels-numChannelsLeft+1;
+    numChannelsLeft--;
+  
+    /* Right channel info */
+    chInfo[numChannels-numChannelsLeft].present = 1;
+    chInfo[numChannels-numChannelsLeft].cpe=1;
+    chInfo[numChannels-numChannelsLeft].common_window=0;
+    chInfo[numChannels-numChannelsLeft].ch_is_left=0;
+    chInfo[numChannels-numChannelsLeft].paired_ch=numChannels-numChannelsLeft-1;
+    numChannelsLeft--;
+  }
+  
+  /* Is there another channel left ? */
+  if (numChannelsLeft) {
+      chInfo[numChannels-numChannelsLeft].present = 1;
+      chInfo[numChannels-numChannelsLeft].tag=sceTag++;
+      chInfo[numChannels-numChannelsLeft].cpe=0;
+    numChannelsLeft--;
+  }
+}
+
--- /dev/null
+++ b/mc_enc.h
@@ -1,0 +1,47 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+"This software module was originally developed 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/*******************************************************************************************
+ *
+ * Multichannel allocation module.
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ * RG    Ralf Geiger, FhG/IIS
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.
+ * 07-apr-98   RG   Added determination of LFE channel.
+ ***************************************************************************************/
+
+
+#ifndef MC_ENC
+#define MC_ENC
+
+#include "all.h"
+
+void DetermineChInfo(Ch_Info* chInfo, int numChannels);
+
+
+#endif
+
--- /dev/null
+++ b/ms.c
@@ -1,0 +1,305 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+"This software module was originally developed 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/*******************************************************************************************
+ *
+ * MS stereo coding module
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.  Lacks psychoacoustics for MS stereo.
+ ***************************************************************************************/
+
+#include "psych.h"
+#include "ms.h"
+
+void MSPreprocess(double p_ratio_long[][MAX_SCFAC_BANDS],
+				  double p_ratio_short[][MAX_SCFAC_BANDS],
+				  CH_PSYCH_OUTPUT_LONG p_chpo_long[],
+				  CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS],
+				  Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+				  enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+				  AACQuantInfo* quantInfo,               /* Quant info */
+				  int numberOfChannels
+				  )
+{
+	int chanNum;
+	int sfbNum;
+
+	static int block = 0;
+	int used = 0, notused = 0;
+
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+				channelInfo[leftChan].ms_info.is_present=0;
+
+				/* Perform MS if block_types are the same */
+				if (block_type[leftChan]==block_type[rightChan]) { 
+
+					int numGroups;
+					int groupIndex = 0;
+					int maxSfb;
+					int g,b,w, j;
+					int use_ms_short;
+					MS_Info *msInfo;
+
+					channelInfo[leftChan].common_window = 1;  /* Use common window */
+					channelInfo[leftChan].ms_info.is_present=1;
+
+					numGroups = quantInfo[leftChan].num_window_groups;
+					maxSfb = quantInfo[leftChan].max_sfb;
+					w=0;
+
+					/* Determine which bands should be enabled */
+					msInfo = &(channelInfo[leftChan].ms_info);
+
+					for (g=0;g<numGroups;g++) {
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							use_ms_short = 1;
+							b = g*maxSfb+sfbNum;
+
+							if (block_type[leftChan] == ONLY_SHORT_WINDOW) {
+
+								for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+									use_ms_short = min(use_ms_short, p_chpo_short[1][j].use_ms[sfbNum]);
+								}
+								msInfo->ms_used[b] = use_ms_short;
+								if (msInfo->ms_used[b]) {
+									used++;
+									for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[0][(j*maxSfb)+sfbNum] = p_chpo_short[2][j].p_ratio[sfbNum];
+										p_ratio_short[1][(j*maxSfb)+sfbNum] = p_chpo_short[3][j].p_ratio[sfbNum];
+									}
+								} else {
+									notused++;
+									for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[0][(j*maxSfb)+sfbNum] = p_chpo_short[0][j].p_ratio[sfbNum];
+										p_ratio_short[1][(j*maxSfb)+sfbNum] = p_chpo_short[1][j].p_ratio[sfbNum];
+									}
+								}
+
+							} else {
+
+								msInfo->ms_used[b] = p_chpo_long[1].use_ms[sfbNum];
+								if (msInfo->ms_used[b]) {
+									used++;
+									p_ratio_long[0][sfbNum] = p_chpo_long[2].p_ratio[sfbNum];
+									p_ratio_long[1][sfbNum] = p_chpo_long[3].p_ratio[sfbNum];
+								} else {
+									notused++;
+									p_ratio_long[0][sfbNum] = p_chpo_long[0].p_ratio[sfbNum];
+									p_ratio_long[1][sfbNum] = p_chpo_long[1].p_ratio[sfbNum];
+								}
+
+							}
+						}
+						groupIndex+=quantInfo[leftChan].window_group_length[g];
+					}
+				} else {
+					int chan;
+					int numGroups;
+					int groupIndex = 0;
+					int maxSfb;
+					int g,b,w, j;
+					MS_Info *msInfo;
+
+					for (chan = 0; chan < 2; chan++) {
+						maxSfb = quantInfo[chan].max_sfb;
+						w=0;
+
+						/* Determine which bands should be enabled */
+						msInfo = &(channelInfo[leftChan].ms_info);
+						numGroups = quantInfo[chan].num_window_groups;
+
+						for (g=0;g<numGroups;g++) {
+							for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+								b = g*maxSfb+sfbNum;
+
+								if (block_type[chan] == ONLY_SHORT_WINDOW) {
+
+									msInfo->ms_used[b] = 0;
+									for (j = groupIndex; j < quantInfo[chan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[chan][(j*maxSfb)+sfbNum] = p_chpo_short[chan][j].p_ratio[sfbNum];
+									}
+
+								} else {
+
+									msInfo->ms_used[b] = 0;
+									p_ratio_long[chan][sfbNum] = p_chpo_long[chan].p_ratio[sfbNum];
+									
+								}
+							}
+							groupIndex+=quantInfo[chan].window_group_length[g];
+						}
+					}
+				}
+			}
+		}
+	}
+
+//	printf("%d used: %d, notused: %d\n", block++, used, notused);
+}
+
+/* Perform MS encoding.  Spectrum is non-interleaved.  */
+/* This would be a lot simpler on interleaved spectral data */
+void MSEncode(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+	      AACQuantInfo* quantInfo,               /* Quant info */
+	      int numberOfChannels)                  /* Number of channels */
+{
+	int chanNum;
+	int sfbNum;
+	int lineNum;
+	double sum,diff;
+
+	/* Look for channel_pair_elements */
+//	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+	chanNum = 0;
+		if (channelInfo[0].ms_info.is_present) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+
+
+					int numGroups;
+					int maxSfb;
+					int g,b,w,line_offset;
+					int startWindow,stopWindow;
+					IS_Info *isInfo;
+					MS_Info *msInfo;
+
+					channelInfo[leftChan].common_window = 1;  /* Use common window */
+					channelInfo[leftChan].ms_info.is_present=1;
+
+					numGroups = quantInfo[leftChan].num_window_groups;
+					maxSfb = quantInfo[leftChan].max_sfb;
+					w=0;
+
+					/* Determine which bands should be enabled */
+					/* Right now, simply enable bands which do not use intensity stereo */
+					isInfo = &(channelInfo[rightChan].is_info);
+					msInfo = &(channelInfo[leftChan].ms_info);
+#if 1
+					for (g=0;g<numGroups;g++) {
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							b = g*maxSfb+sfbNum;
+							msInfo->ms_used[b] = (((!isInfo->is_used[b])||(!isInfo->is_present))&&msInfo->ms_used[b]);
+						}
+					}
+#endif
+					/* Perform sum and differencing on bands in which ms_used flag */
+					/* has been set. */
+					line_offset=0;
+					startWindow = 0;
+					for (g=0;g<numGroups;g++) {
+						int numWindows = quantInfo[leftChan].window_group_length[g];
+						stopWindow = startWindow + numWindows;
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							/* Enable MS mask */
+							if (msInfo->ms_used[g*maxSfb+sfbNum]) {
+								for (w=startWindow;w<stopWindow;w++) {
+									for (lineNum=sfb_offset_table[leftChan][sfbNum];
+									lineNum<sfb_offset_table[leftChan][sfbNum+1];
+									lineNum++) {
+										line_offset = w*BLOCK_LEN_SHORT;
+										sum=spectrum[leftChan][line_offset+lineNum]+spectrum[rightChan][line_offset+lineNum];
+										diff=spectrum[leftChan][line_offset+lineNum]-spectrum[rightChan][line_offset+lineNum];
+										spectrum[leftChan][line_offset+lineNum] = 0.5 * sum;
+										spectrum[rightChan][line_offset+lineNum] = 0.5 * diff;
+									}  /* for (lineNum... */
+								}  /* for (w=... */
+							}
+						}  /* for (sfbNum... */
+						startWindow = stopWindow;
+					} /* for (g... */
+				}  /* if (block_type... */
+//	}  /* for (chanNum... */
+}
+
+
+void MSReconstruct(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+		   Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+		   int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+		   enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+		   AACQuantInfo* quantInfo,               /* Quant info */
+		   int numberOfChannels)                 /* Number of channels */
+{
+	int chanNum;
+	int sfbNum;
+	int lineNum;
+	double sum,diff;
+
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+
+				MS_Info *msInfo;
+				msInfo = &(channelInfo[leftChan].ms_info);
+				if (msInfo->is_present) {
+					int numGroups = quantInfo[leftChan].num_window_groups;
+					int maxSfb = quantInfo[leftChan].max_sfb;
+					int g,w,line_offset;
+					int startWindow,stopWindow;
+					w=0;
+
+					/* Perform sum and differencing on bands in which ms_used flag */
+					/* has been set. */
+					line_offset=0;
+					startWindow = 0;
+					for (g=0;g<numGroups;g++) {
+						int numWindows = quantInfo[leftChan].window_group_length[g];
+						stopWindow = startWindow + numWindows;
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							/* Enable MS mask */
+							if ((msInfo->ms_used[g*maxSfb+sfbNum]) || (msInfo->is_present==2)) {
+								for (w=startWindow;w<stopWindow;w++) {
+									line_offset = w*BLOCK_LEN_SHORT;
+									for (lineNum=sfb_offset_table[leftChan][sfbNum];
+									lineNum<sfb_offset_table[leftChan][sfbNum+1];
+									lineNum++) {
+										sum=spectrum[leftChan][line_offset+lineNum];
+										diff=spectrum[rightChan][line_offset+lineNum];
+										spectrum[leftChan][line_offset+lineNum] = (sum+diff);
+										spectrum[rightChan][line_offset+lineNum] = (sum-diff);
+									}  /* for (lineNum... */
+								}  /* for (w=start... */
+							}  /* if (msInfo... */
+						}  /* for (sfbNum... */
+						startWindow = stopWindow;
+					} /* for (g... */
+				}  /* if (ms_info.is_present... */
+			}  /* if (channelInfo... */
+		}  /* if (channelInfo[chanNum].present */
+	}  /* for (chanNum... */
+}
+
--- /dev/null
+++ b/ms.h
@@ -1,0 +1,68 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+"This software module was originally developed 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/*******************************************************************************************
+ *
+ * MS stereo coding module
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ *
+ * Changes:
+ * 22-jan-98   CL   Initial revision.  Lacks psychoacoustics for MS stereo.
+ ***************************************************************************************/
+
+#ifndef MS_ENC
+#define MS_ENC
+
+#include "all.h"
+#include "tf_main.h"
+#include "aac_qc.h"
+
+
+void MSPreprocess(double p_ratio_long[][MAX_SCFAC_BANDS],
+				  double p_ratio_short[][MAX_SCFAC_BANDS],
+				  CH_PSYCH_OUTPUT_LONG p_chpo_long[],
+				  CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS],
+				  Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+				  enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+				  AACQuantInfo* quantInfo,               /* Quant info */
+				  int numberOfChannels
+				  );
+
+void MSEncode(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+	      AACQuantInfo* quantInfo,
+	      int numberOfChannels);                 /* Number of channels */
+
+void MSReconstruct(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
+		   Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+		   int sfb_offset_table[][MAX_SCFAC_BANDS+1],
+		   enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
+		   AACQuantInfo* quantInfo,               /* Quant info */
+		   int numberOfChannels);                 /* Number of channels */
+
+#endif
+
--- /dev/null
+++ b/psych.c
@@ -1,0 +1,1480 @@
+/**********************************************************************
+MPEG-4 Audio VM
+
+
+
+This software module was originally developed by
+
+Fraunhofer Gesellschaft IIS / University of Erlangen (UER
+
+and edited by
+
+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.
+
+-----
+This software module was modified by
+
+Tadashi Araki (Ricoh Company, ltd.)
+Tatsuya Okada (Waseda Univ.)
+Itaru Kaneko (Graphics Communication Laboratories)
+
+and edited by
+
+in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
+ISO/IEC 13818-7, 14496-1,2 and 3.
+
+Almost all part of the function EncTf_psycho_acoustic() is made by
+T. Araki and T. Okada and its copyright belongs to Ricoh.
+The function psy_get_absthr() is made by I. Kaneko
+and its copyright belongs to Graphics Communication Laboratories.
+
+Copyright (c) 1997.
+
+
+Source file: 
+
+$Id: psych.c,v 1.1 1999/12/13 09:01:31 lenox Exp $
+$Id: psych.c,v 1.1 1999/12/13 09:01:31 lenox Exp $
+$Id: psych.c,v 1.1 1999/12/13 09:01:31 lenox Exp $
+
+**********************************************************************/
+
+/* CREATED BY :  Bernhard Grill -- August-96  */
+#include <stdlib.h>
+#include <math.h>
+
+#include "tf_main.h"
+#include "psych.h"
+
+
+static SR_INFO sr_info_aac[MAX_SAMPLING_RATES+1] =
+{
+  { 8000  },
+  { 11025 },
+  { 12000 },
+  { 16000 },
+
+/* added by T. Araki (1997.10.16) */
+  { 22050, 47, 15,
+     { /*  cb_width_long[NSFB_LONG] */
+      4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,
+      8,  8,  8,  12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32,
+      36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
+     },
+     { /* cb_width_short[NSFB_SHORT] */
+      4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8, 12, 16, 16, 20
+     }
+  },
+/* added by T. Araki (1997.10.16) end */
+
+  { 24000 },
+  { 32000 },
+
+/* added by T. Araki (1997.07.09) */
+  { 44100, 49, 14,
+     { /*  cb_width_long[NSFB_LONG] */
+      4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8, 
+      12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32,
+      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96 
+     }, 
+     { /* cb_width_short[NSFB_SHORT] */
+      4,  4,  4,  4,  4,  8,  8,  8, 12, 12, 12, 16, 16, 16 
+     }
+/* added by T. Araki (1997.07.09) end */
+
+  },
+  { 48000, 49, 14,
+     { /*  cb_width_long[NSFB_LONG] */
+      4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8, 
+      12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32,
+      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96 
+     }, 
+     { /* cb_width_short[NSFB_SHORT] */
+      4,  4,  4,  4,  4,  8,  8,  8, 12, 12, 12, 16, 16, 16 
+     }
+  },
+  { 96000 },
+  { -1 }
+};
+
+/* added by T. Araki (1997.07.10) */
+static PARTITION_TABLE_LONG  part_tbl_long_all[MAX_SAMPLING_RATES+1] =
+{
+  { 8000  },
+  { 11025 },
+  { 12000 },
+  { 16000 },
+ 
+/* added by T. Araki (1997.10.16) */
+  { 22050, 63,
+     { /* w_low */
+      0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68,
+      72, 77, 82, 87, 92, 97, 102, 108, 114, 120, 126, 133, 140, 147, 155,
+      163, 172, 181, 191, 201, 212, 224, 237, 251, 266, 282, 299, 318, 338,
+      360, 383, 408, 435, 464, 495, 528, 564, 602, 643, 687, 734, 785, 840,
+      899, 963
+     },
+     {/* w_high */
+      3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71,
+      76, 81, 86, 91, 96, 101, 107, 113, 119, 125, 132, 139, 146, 154, 162,
+      171, 180, 190, 200, 211, 223, 236, 250, 265, 281, 298, 317, 337, 359,
+      382, 407, 434, 463, 494, 527, 563, 601, 642, 686, 733, 784, 839, 898,
+      962, 1023
+     },
+     { /* width */
+      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
+      6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
+      19, 20, 22, 23, 25, 27, 29, 31, 33, 36, 38, 41, 44, 47, 51, 55, 59,
+      64, 61
+     }
+  },
+/* added by T. Araki (1997.10.16) end */
+
+  { 24000 },
+  { 32000 },
+  { 44100, 70,
+     { /* w_low */
+      0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+      39, 42, 45, 48, 51, 54, 57, 60, 63, 67, 71, 75, 79, 83, 88, 93, 98,
+      104, 110, 117, 124, 132, 140, 149, 158, 168, 179, 191, 204, 218, 233,
+      249, 266, 284, 304, 325, 348, 372, 398, 426, 456, 489, 525, 564, 607,
+      654, 707, 766, 833, 909, 997
+     },
+     { /* w_high */
+      1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 38, 
+      41, 44, 47, 50, 53, 56, 59, 62, 66, 70, 74, 78, 82, 87, 92, 97, 103,
+      109, 116, 123, 131, 139, 148, 157, 167, 178, 190, 203, 217, 232, 248,
+      265, 283, 303, 324, 347, 371, 397, 425, 455, 488, 524, 563, 606, 653,
+      706, 765, 832, 908, 996, 1023
+     },
+     { /* width */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 
+      3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11,
+      12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 28, 30, 33, 36, 39,
+      43, 47, 53, 59, 67, 76, 88, 27
+     }
+  },
+  { 48000, 69,
+     { /* w_low */
+      0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+      38, 41, 44, 47, 50, 53, 56, 59, 62, 66, 70, 74, 78, 82, 87, 92, 97,
+      103, 109, 116, 123, 131, 139, 148, 158, 168, 179, 191, 204, 218, 233,
+      249, 266, 284, 304, 325, 348, 372, 398, 426, 457, 491, 528, 568, 613,
+      663, 719, 782, 854, 938
+     },
+     { /* w_high */
+      1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37,
+      40, 43, 46, 49, 52, 55, 58, 61, 65, 69, 73, 77, 81, 86, 91, 96, 102,
+      108, 115, 122, 130, 138, 147, 157, 167, 178, 190, 203, 217, 232, 248,
+      265, 283, 303, 324, 347, 371, 397, 425, 456, 490, 527, 567, 612, 662,
+      718, 781, 853, 937, 1023
+     }, 
+     { /* width */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+      3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 12,
+      13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 28, 31, 34, 37, 40, 45, 50,
+      56, 63, 72, 84, 86
+     }
+  },
+  { 96000 },
+  { -1 }
+};
+
+static PARTITION_TABLE_SHORT  part_tbl_short_all[MAX_SAMPLING_RATES+1] =
+{
+  { 8000  },
+  { 11025 },
+  { 12000 },
+  { 16000 },
+
+/* added by T. Araki (1997.10.16) */
+  { 22050, 46,
+     { /* w_low */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 22, 24, 26, 28, 30, 32, 34, 36, 39, 42, 45, 48, 52, 56, 60, 64, 69,
+      74, 79, 85, 91, 98, 105, 113, 121
+     },
+     { /* w_high */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      21, 23, 25, 27, 29, 31, 33, 35, 38, 41, 44, 47, 51, 55, 59, 63, 68, 73,
+      78, 84, 90, 97, 104, 112, 120, 127
+     },
+     { /* width */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+      2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 7
+     }
+  },
+/* added by T. Araki (1997.10.16) end */
+
+  { 24000 },
+  { 32000 },
+  { 44100, 42, 
+     { /* w_low */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
+      22, 24, 26, 28, 30, 32, 35, 38, 41, 44, 48, 52, 56, 60, 65, 70, 76,
+      82, 89, 97, 106, 116
+     },
+     { /* w_high */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21,
+      23, 25, 27, 29, 31, 34, 37, 40, 43, 47, 51, 55, 59, 64, 69, 75, 81,
+      88, 96, 105, 115, 127
+     },
+     { /* width */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+      2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 12
+     }
+  },
+  { 48000, 42,
+     { /* w_low */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21,
+      23, 25, 27, 29, 31, 34, 37, 40, 43, 46, 50, 54, 58, 63, 68, 74, 80,
+      87, 95, 104, 114, 126
+     },
+     { /* w_high */
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22,
+      24, 26, 28, 30, 33, 36, 39, 42, 45, 49, 53, 57, 62, 67, 73, 79, 86,
+      94, 103, 113, 125, 127
+     }, 
+     { /* width */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+      2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 12, 1
+     }
+  },
+  { 96000 },
+  { -1 }
+};
+/* added by T. Araki (1997.07.10) end */
+
+/* added by T. Araki (1997.10.16) */
+static double          sample[MAX_TIME_CHANNELS+2][BLOCK_LEN_LONG*2];
+                               /* sample value */
+
+static FFT_TABLE_LONG    fft_tbl_long;  /* table for long fft */
+static FFT_TABLE_SHORT    fft_tbl_short;  /* table for short fft */
+static PARTITION_TABLE_LONG    *part_tbl_long;  
+                               /* partition table for long block */
+static PARTITION_TABLE_SHORT    *part_tbl_short;
+                               /* partition table for short block */
+/*static PSY_STATVARIABLE_LONG    psy_stvar_long;*/
+static PSY_STATVARIABLE_LONG    psy_stvar_long[MAX_TIME_CHANNELS+2];
+                               /* static variables for long block */
+/*static PSY_STATVARIABLE_SHORT    psy_stvar_short;*/
+static PSY_STATVARIABLE_SHORT    psy_stvar_short[MAX_TIME_CHANNELS+2];
+                               /* static variables for short block */
+/* added by T. Araki (1997.10.16) end */
+
+void EncTf_psycho_acoustic_init( void )
+{
+  int chanNum;
+/* added by T. Araki (1997.10.16) */
+      psy_fft_table_init(&fft_tbl_long, &fft_tbl_short);
+         /* initializing fft table */
+      for (chanNum=0;chanNum<MAX_TIME_CHANNELS+2;chanNum++) {
+	psy_calc_init(&sample[chanNum], &psy_stvar_long[chanNum], &psy_stvar_short[chanNum]);
+	/* initializing static variables */
+  }
+/* added by T. Araki (1997.10.16) end */
+
+}
+
+/* added by T. Okada (1997.07.10) */
+void psy_fft_table_init(FFT_TABLE_LONG *fft_tbl_long, 
+			FFT_TABLE_SHORT *fft_tbl_short
+			)
+{    
+
+    int i,j,k,n,n2,n4,n8;
+    double c,s,dc,ds,t;
+
+    /* generating Hann window */
+    for(i = 0; i < BLOCK_LEN_LONG*2; i++)
+		fft_tbl_long->hw[i] = 0.5 * (1-cos(2.0*M_PI*(i+0.5)/(BLOCK_LEN_LONG*2)));
+    for(i = 0; i < BLOCK_LEN_SHORT*2; i++)
+		fft_tbl_short->hw[i] = 0.5 * (1-cos(2.0*M_PI*(i+0.5)/(BLOCK_LEN_SHORT*2)));
+
+    /* generating sin table (long) */
+    n = BLOCK_LEN_LONG * 2;
+    n2 = n/2;  
+    n4 = n2/2;  
+    n8 = n4/2;
+
+    t = sin(M_PI / (double)n);
+    dc = 2.0*t*t;
+    ds = sqrt(dc * (2.0 - dc));
+    t = 2*dc;
+    c = fft_tbl_long->st[n4] = 1.0;
+    s = fft_tbl_long->st[0] = 0;
+
+    for(i = 1; i < n8; ++i){
+	c -= dc;  dc += t * c;
+	s += ds;  ds -= t * s;
+	fft_tbl_long->st[i] = s;  fft_tbl_long->st[n4 - i] = c;
+    }
+    if (n8 != 0) fft_tbl_long->st[n8] = sqrt(0.5);
+    for (i = 0; i < n4; i++)
+	fft_tbl_long->st[n2 - i] = fft_tbl_long->st[i];
+    for (i = 0; i < n2 + n4; i++)
+	fft_tbl_long->st[i + n2] = -fft_tbl_long->st[i];
+
+    /* generating sin table (short) */
+    n = BLOCK_LEN_SHORT * 2;
+    n2 = n/2;  
+    n4 = n2/2;  
+    n8 = n4/2;
+
+    t = sin(M_PI / (double)n);
+    dc = 2*t*t;
+    ds = sqrt(dc * (2.0 - dc));
+    t = 2*dc;
+    c = fft_tbl_short->st[n4] = 1.0;
+    s = fft_tbl_short->st[0] = 0;
+
+    for(i = 1; i < n8; ++i){
+	c -= dc;  dc += t * c;
+	s += ds;  ds -= t * s;
+	fft_tbl_short->st[i] = s;  fft_tbl_short->st[n4 - i] = c;
+    }
+    if (n8 != 0) fft_tbl_short->st[n8] = sqrt(0.5);
+    for (i = 0; i < n4; i++)
+	fft_tbl_short->st[n2 - i] = fft_tbl_short->st[i];
+    for (i = 0; i < n2 + n4; i++)
+	fft_tbl_short->st[i + n2] = - fft_tbl_short->st[i];
+
+    /* generating bit inverse table (long) */
+    n = BLOCK_LEN_LONG * 2;
+    n2 = n/2; i = j = 0;
+
+    for(;;){
+	fft_tbl_long->brt[i] = j;
+	if( ++i >= n ) break;
+	k = n2;
+	while(k <= j){
+	    j -= k;
+	    k /= 2;
+	}
+	j += k;
+    }
+
+    /* generating bit inverse table (short) */
+    n = BLOCK_LEN_SHORT * 2;
+    n2 = n/2; i = j = 0;
+
+    for(;;){
+	fft_tbl_short->brt[i] = j;
+	if( ++i >= n ) break;
+	k = n2;
+	while(k <= j){
+	    j -= k;
+	    k /= 2;
+	}
+	j += k;
+    }
+}
+/* added by T. Okada (1997.07.10) end */
+
+/* added by T. Araki (1997.07.10) */
+void psy_part_table_init( 
+			   double sampling_rate,
+			   PARTITION_TABLE_LONG **part_tbl_long,
+			   PARTITION_TABLE_SHORT **part_tbl_short
+			   )
+{
+    int b,bb; /* Jul 10 */
+    double tmp;
+	int partition[1024], j, w;
+
+	*part_tbl_long = &part_tbl_long_all[0];
+
+	/* find correct sampling rate depending parameters */
+	while( (*part_tbl_long)->sampling_rate != (int)sampling_rate ) {
+		(*part_tbl_long)++;
+	}
+
+	*part_tbl_short = &part_tbl_short_all[0];
+
+	/* find correct sampling rate depending parameters */
+	while( (*part_tbl_short)->sampling_rate != (int)sampling_rate ) {
+		(*part_tbl_short)++;
+	}
+
+	for (b = 0; b < (*part_tbl_long)->len; b++) {
+		for(w = (*part_tbl_long)->w_low[b]; w <= (*part_tbl_long)->w_high[b]; ++w){
+			partition[w] = b;
+		}
+	}
+
+	for(b = 0; b < (*part_tbl_long)->len ; b++) {
+		for (j=0;(b != partition[j]);j++);
+		{
+			double ji = j + ((*part_tbl_long)->width[b]-1)/2.0;
+			double freq = (*part_tbl_long)->sampling_rate*ji/2048;
+			double bark = 13*atan(0.00076*freq)+3.5*atan((freq/7500)*(freq/7500));
+			(*part_tbl_long)->bval[b] = bark;
+		}
+	}
+
+	for (b = 0; b < (*part_tbl_short)->len; b++) {
+		for(w = (*part_tbl_short)->w_low[b]; w <= (*part_tbl_short)->w_high[b]; ++w){
+			partition[w] = b;
+		}
+	}
+
+	for(b = 0; b < (*part_tbl_short)->len ; b++) {
+		for (j=0;(b != partition[j]);j++);
+		{
+			double ji = j + ((*part_tbl_short)->width[b]-1)/2.0;
+			double freq = (*part_tbl_short)->sampling_rate*ji/256;
+			double bark = 13*atan(0.00076*freq) + 3.5*atan((freq/7500)*(freq/7500));
+			(*part_tbl_short)->bval[b]=bark;
+		}
+	}
+
+    /* added by T. Okada (1997.07.10) */
+    for( b = 0; b < (*part_tbl_long)->len; ++b){
+		tmp = 0.0;
+		for( bb = 0; bb < (*part_tbl_long)->len; ++bb)
+			tmp += sprdngf( (*part_tbl_long),(*part_tbl_short), bb, b, 0);
+		(*part_tbl_long)->rnorm[b] = 1.0/tmp;
+    }
+    /* added by T. Okada (1997.07.10) end */
+
+    /* added by T. Araki (1997.10.16) */
+    for( b = 0; b < (*part_tbl_short)->len; ++b){
+		tmp = 0.0;
+		for( bb = 0; bb < (*part_tbl_short)->len; ++bb)
+			tmp += sprdngf( (*part_tbl_long), (*part_tbl_short), bb, b, 1);
+		(*part_tbl_short)->rnorm[b] = 1.0/tmp;
+    }
+    /* added by T. Araki (1997.10.16) end */
+
+	for(b = 0; b < (*part_tbl_long)->len; b++) {
+		(*part_tbl_long)->bmax[b] = pow(10, -3*(0.5+0.5*(M_PI*(min((*part_tbl_long)->bval[b], 15.5)/15.5))));
+	}
+	for(b = 0; b < (*part_tbl_short)->len; b++) {
+		(*part_tbl_short)->bmax[b] = pow(10, -3*(0.5+0.5*(M_PI*(min((*part_tbl_short)->bval[b], 15.5)/15.5))));
+	}
+}
+
+
+void psy_calc_init( 
+		   double sample[][BLOCK_LEN_LONG*2],
+		   PSY_STATVARIABLE_LONG *psy_stvar_long,
+		   PSY_STATVARIABLE_SHORT *psy_stvar_short
+		   )
+{
+	int ch = 0;
+	int i;
+
+	for(i = 0; i < BLOCK_LEN_LONG*2; ++i){
+		sample[ch][i] = 0.0;
+	}
+
+    /*  for(ch = 0; ch < Chans; ++ch){ */
+    for(i = 0; i < BLOCK_LEN_LONG*3; ++i){
+      psy_stvar_long->fft_r[i] = 0.0;
+      psy_stvar_long->fft_f[i] = 0.0;
+    }
+    /*  }*/
+
+  psy_stvar_long->p_fft = 0;
+
+  /*  for(ch = 0; ch < Chans; ++ch){*/
+    for(i = 0; i < NPART_LONG*2; ++i){
+      psy_stvar_long->nb[i] = 90.0;
+    }
+    /*}*/
+
+  psy_stvar_long->p_nb = NPART_LONG;
+/* added by T. Araki (1997.07.10) end */
+
+/* added by T. Araki (1997.10.16) */
+  /*  for(ch = 0; ch < Chans; ++ch){*/
+    for(i = 0; i < BLOCK_LEN_SHORT; ++i){
+      psy_stvar_short->last6_fft_r[i] = 0.0;
+      psy_stvar_short->last6_fft_f[i] = 0.0;
+      psy_stvar_short->last7_fft_r[i] = 0.0;
+      psy_stvar_short->last7_fft_f[i] = 0.0;
+    }
+    /*  }*/
+
+    /*  for(ch = 0; ch < Chans; ++ch){*/
+    for(i = 0; i < NPART_SHORT; ++i){
+      psy_stvar_short->last7_nb[i] = 90.0;
+    }
+    /* }*/
+/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_fill_lookahead(double *p_time_signal[], int no_of_chan)
+{
+	int i, ch;
+
+	for (ch = 0; ch < no_of_chan; ch++) {
+		for(i = 0; i < BLOCK_LEN_LONG; i++){
+			sample[ch][i+BLOCK_LEN_LONG] = p_time_signal[ch][i]/32767;
+		}
+	}
+}
+
+/* main */
+void EncTf_psycho_acoustic( 
+			   /* input */
+			   double sampling_rate,
+			   int    no_of_chan,         /* no of audio channels */
+			   double *p_time_signal[],
+			   enum WINDOW_TYPE block_type[],
+			   int qcSelect,
+			   int frameLength,
+			   /* output */
+			   CH_PSYCH_OUTPUT_LONG p_chpo_long[],
+			   CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS]
+			   )
+{
+	int             ch, i, b;
+    SR_INFO         *p_sri;
+
+	/* added by T. Araki (1997.07.10) */
+
+    static int   flag = 0;
+
+	static double save_tb_l[2][70];
+	static double save_tb_s[2][8][42];
+	static double save_cw_l[70];
+	static double save_cw_s[8][42];
+	int use_ms_l[NSFB_LONG];
+	int use_ms_s[MAX_SHORT_WINDOWS][NSFB_SHORT];
+
+    PSY_VARIABLE_LONG    psy_var_long;  /* variables for long block */
+    PSY_VARIABLE_SHORT    psy_var_short;  /* variables for short block */
+
+	memset(&psy_var_long, 0, sizeof(psy_var_long));
+	memset(&psy_var_short, 0, sizeof(psy_var_short));
+	/* added by T. Araki (1997.07.10) end */
+
+    p_sri = &sr_info_aac[0];
+	
+	/* find correct sampling rate depending parameters */
+	while( p_sri->sampling_rate != (long)sampling_rate ) {
+		p_sri++;
+	}
+
+	/* added by T. Araki (1997.07.10) */
+	if( flag==0 ) {
+		psy_part_table_init(sampling_rate, &part_tbl_long, &part_tbl_short);
+		/* initializing Table B 2.1.*.a, B 2.1.*.b in N1650 */
+		flag = 1;
+	}
+
+	{
+		ch =0;
+		psy_step1(p_time_signal,sample, no_of_chan);
+		psy_step2(&sample[no_of_chan], &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &fft_tbl_long, 
+			&fft_tbl_short, ch);
+		psy_step3(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
+		psy_step4(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
+
+		if (no_of_chan == 0) {
+			for (b = 0; b < 70; b++)
+				save_cw_l[b] = psy_var_long.cw[b];
+			for (i = 0; i < 8; i++)
+				for (b = 0; b < 42; b++)
+					save_cw_s[i][b] = psy_var_short.cw[i][b];
+		}
+		if (no_of_chan == 1) {
+			for (b = 0; b < 70; b++)
+				save_cw_l[b] = min(psy_var_long.cw[b], save_cw_l[b]);
+			for (i = 0; i < 8; i++)
+				for (b = 0; b < 42; b++)
+					save_cw_s[i][b] = min(psy_var_short.cw[i][b], save_cw_s[i][b]);
+		}
+		if (no_of_chan > 1) {
+			for (b = 0; b < 70; b++)
+				psy_var_long.cw[b] = save_cw_l[b];
+			for (i = 0; i < 8; i++)
+				for (b = 0; b < 42; b++)
+					psy_var_short.cw[i][b] = save_cw_s[i][b];
+		}
+
+		psy_step5(part_tbl_long, part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], 
+			&psy_var_long, &psy_var_short, ch);
+		psy_step6(part_tbl_long, part_tbl_short, &psy_var_long, &psy_var_short);
+
+		for (b = 0; b < 70; b++)
+			psy_stvar_long[no_of_chan].en[b] = psy_var_long.en[b];
+		for (i = 0; i < 8; i++)
+			for (b = 0; b < 42; b++)
+				psy_stvar_short[no_of_chan].en[i][b] = psy_var_short.en[i][b];
+
+		psy_step7(part_tbl_long, part_tbl_short, &psy_var_long, &psy_var_short);
+
+		if (no_of_chan < 2) {
+			for (b = 0; b < 70; b++)
+				save_tb_l[no_of_chan][b] = psy_var_long.tb[b];
+			for (i = 0; i < 8; i++)
+				for (b = 0; b < 42; b++)
+					save_tb_s[no_of_chan][i][b] = psy_var_short.tb[i][b];
+		} else {
+			for (b = 0; b < 70; b++)
+				psy_var_long.tb[b] = save_tb_l[no_of_chan-2][b];
+			for (i = 0; i < 8; i++)
+				for (b = 0; b < 42; b++)
+					psy_var_short.tb[i][b] = save_tb_s[no_of_chan-2][i][b];
+		}
+
+		psy_step8(part_tbl_long, part_tbl_short, &psy_var_long, &psy_var_short);
+		psy_step9(part_tbl_long, part_tbl_short, &psy_var_long, &psy_var_short);
+		psy_step10(part_tbl_long, part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], 
+			&psy_var_long, &psy_var_short, ch);
+		psy_step11(part_tbl_long, part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], ch);
+
+		psy_step11andahalf(part_tbl_long, part_tbl_short, psy_stvar_long, psy_stvar_short, no_of_chan);
+
+		psy_step12(part_tbl_long, part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], 
+			&psy_var_long, &psy_var_short, ch);
+		psy_step13(&psy_var_long, block_type, ch);
+		psy_step14(p_sri, part_tbl_long, part_tbl_short, &psy_stvar_long[no_of_chan], 
+			&psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
+		psy_step15(use_ms_l, use_ms_s, p_sri, &psy_var_long, &psy_var_short, no_of_chan);
+	}	
+
+	/*  for( ch=0; ch<no_of_chan; ch++ ) { */
+	{   /* Now performed for only one channel at a time, CL 97.01.10 */
+		int i;
+
+		p_chpo_long[no_of_chan].p_ratio   = psy_stvar_long[no_of_chan].ismr;
+		/* changed by T. Araki (1997.7.10) */
+		p_chpo_long[no_of_chan].cb_width  = p_sri->cb_width_long;
+//		p_chpo_long[no_of_chan].no_of_cb  = p_sri->num_cb_long;
+//		if (no_of_chan == 1)
+//			p_chpo_long[no_of_chan].use_ms = use_ms_l;
+//		memcpy(p_chpo_long[no_of_chan].p_ratio, psy_stvar_long[no_of_chan].ismr, NPART_LONG*sizeof(double));
+//		memcpy(p_chpo_long[no_of_chan].cb_width, p_sri->cb_width_long, NPART_LONG*sizeof(int));
+		p_chpo_long[no_of_chan].no_of_cb = p_sri->num_cb_long;
+		if (no_of_chan == 1)
+			memcpy(p_chpo_long[no_of_chan].use_ms, use_ms_l, NPART_LONG*sizeof(int));
+
+		for( i=0; i<MAX_SHORT_WINDOWS; i++ ) {
+			p_chpo_short[no_of_chan][i].p_ratio  = psy_stvar_short[no_of_chan].ismr[i];
+			/* changed by T. Araki (1997.10.16) */
+			p_chpo_short[no_of_chan][i].cb_width = p_sri->cb_width_short;
+			p_chpo_short[no_of_chan][i].no_of_cb = p_sri->num_cb_short;
+//			if (no_of_chan == 1)
+//				p_chpo_short[no_of_chan][i].use_ms = use_ms_s[i];
+//			memcpy(p_chpo_short[no_of_chan][i].p_ratio, psy_stvar_short[no_of_chan].ismr[i],NPART_SHORT*sizeof(double));
+			/* changed by T. Araki (1997.10.16) */
+//			memcpy(p_chpo_short[no_of_chan][i].cb_width, p_sri->cb_width_short, NPART_SHORT*sizeof(int));
+			p_chpo_short[no_of_chan][i].no_of_cb = p_sri->num_cb_short;
+			if (no_of_chan == 1)
+				memcpy(p_chpo_short[no_of_chan][i].use_ms, use_ms_s[i], NPART_SHORT*sizeof(int));
+		}
+
+	}
+}
+
+/* added by T. Okada (1997.7.10) */
+double sprdngf(PARTITION_TABLE_LONG *part_tbl_long,
+			   PARTITION_TABLE_SHORT *part_tbl_short,
+			   int bb1, int bb2, int short_block)
+{
+	static double sprd_l[70][70];
+	static double sprd_s[46][46];
+	static int init = 1;
+
+	if (init) {
+		double tmpx,tmpy,tmpz,b1,b2;
+		int b, bb;
+
+		for( b = 0; b < part_tbl_long->len; ++b) {
+			b2 = part_tbl_long->bval[b];
+			for( bb = 0; bb < part_tbl_long->len; ++bb) {
+				b1 = part_tbl_long->bval[bb];
+
+				//tmpx = (b2 >= b1) ? 3.0*(b2-b1) : 1.5*(b2-b1);
+				tmpx = (bb >= b) ? 3.0*(b2-b1) : 1.5*(b2-b1);
+
+				tmpz = 8.0 * psy_min( (tmpx-0.5)*(tmpx-0.5) - 2.0*(tmpx-0.5),0.0 );
+
+				tmpy = 15.811389 + 7.5*(tmpx + 0.474)-17.5 *sqrt(1.0 + (tmpx+0.474)*(tmpx+0.474));
+
+				sprd_l[b][bb] = ( tmpy < -100.0 ? 0.0 : pow(10.0, (tmpz + tmpy)/10.0) );
+			}
+		}
+
+		for( b = 0; b < part_tbl_short->len; ++b) {
+			b2 = part_tbl_short->bval[b];
+			for( bb = 0; bb < part_tbl_short->len; ++bb) {
+				b1 = part_tbl_short->bval[bb];
+
+				//tmpx = (b2 >= b1) ? 3.0*(b2-b1) : 1.5*(b2-b1);
+				tmpx = (bb >= b) ? 3.0*(b2-b1) : 1.5*(b2-b1);
+				
+				tmpz = 8.0 * psy_min( (tmpx-0.5)*(tmpx-0.5) - 2.0*(tmpx-0.5),0.0 );
+
+				tmpy = 15.811389 + 7.5*(tmpx + 0.474)-17.5 *sqrt(1.0 + (tmpx+0.474)*(tmpx+0.474));
+
+				sprd_s[b][bb] = ( tmpy < -100.0 ? 0.0 : pow(10.0, (tmpz + tmpy)/10.0) );
+			}
+		}
+
+		init = 0;
+	}
+
+	if (short_block)
+		return sprd_s[bb1][bb2];
+	else {
+		return sprd_l[bb1][bb2];
+	}
+}
+
+void psy_step1(double* p_time_signal[], 
+	       double sample[][BLOCK_LEN_LONG*2], 
+	       int ch) 
+{
+	int i;
+
+	for(i = 0; i < BLOCK_LEN_LONG; i++){
+		sample[ch][i] = sample[ch][i+BLOCK_LEN_LONG];
+		sample[ch][i+BLOCK_LEN_LONG] = p_time_signal[/*ch*/0][i]/32767;
+	}
+}
+
+void psy_step2(double sample[][BLOCK_LEN_LONG*2], 
+               PSY_STATVARIABLE_LONG *psy_stvar_long, 
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       FFT_TABLE_LONG *fft_tbl_long,
+	       FFT_TABLE_SHORT *fft_tbl_short,
+	       int ch
+	       )
+{
+    int w,i,j,k,l,h,n,d,ik,k2,n4;
+    double t,s,c,dx,dy;
+	double *xl,*yl;
+
+    /* FFT for long */
+	xl = (double *)malloc( sizeof(double) * BLOCK_LEN_LONG * 2 );
+	yl = (double *)malloc( sizeof(double) * BLOCK_LEN_LONG * 2 );
+
+    psy_stvar_long->p_fft += BLOCK_LEN_LONG;
+
+    if(psy_stvar_long->p_fft == BLOCK_LEN_LONG * 3)
+		psy_stvar_long->p_fft = 0;
+
+    /* window *//* static int it = 0; */
+    for(i = 0; i < BLOCK_LEN_LONG*2; ++i){
+		xl[i] = fft_tbl_long->hw[i] * sample[ch][i];
+		yl[i] = 0.0;
+    }
+
+    n = BLOCK_LEN_LONG*2;
+    n4 = n/4;
+
+    for (i = 0; i < n; ++i) {    /* bit inverse */
+		j = fft_tbl_long->brt[i];
+		if (i < j) {
+			t = xl[i];  xl[i] = xl[j];  xl[j] = t;
+			t = yl[i];  yl[i] = yl[j];  yl[j] = t;
+		}
+    }
+    for (k = 1; k < n; k = k2) {    /* translation */
+		h = 0;  k2 = k + k;  d = n / k2;
+		for (j = 0; j < k; j++) {
+			c = fft_tbl_long->st[h + n4];
+			s = fft_tbl_long->st[h];
+			for (i = j; i < n; i += k2) {
+				ik = i + k;
+				dx = s * yl[ik] + c * xl[ik];
+				dy = c * yl[ik] - s * xl[ik];
+				xl[ik] = xl[i] - dx;  xl[i] += dx;
+				yl[ik] = yl[i] - dy;  yl[i] += dy;
+			}
+			h += d;
+		}
+    }
+
+    for(w = 0; w < BLOCK_LEN_LONG; ++w){
+		psy_stvar_long->fft_r[w+psy_stvar_long->p_fft] 
+			= sqrt(xl[w]*xl[w] + yl[w]*yl[w]);
+
+		if( xl[w] > 0.0 ){
+			if( yl[w] >= 0.0 )
+				psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( yl[w] / xl[w] );
+			else
+				psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( yl[w] / xl[w] )+ M_PI * 2.0;
+		} else if( xl[w] < 0.0 ) {
+			psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( yl[w] / xl[w] ) + M_PI;
+		} else {
+			if( yl[w] > 0.0 )
+				psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = M_PI * 0.5;
+			else if( yl[w] < 0.0 )
+				psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = M_PI * 1.5;
+			else
+				psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = 0.0; /* tmp */
+		}
+    }
+
+	if (xl) free(xl);
+	if (yl) free(yl);
+
+
+	/* added by T. Araki (1997.10.16) */
+	/* FFT for short */
+	xl = (double *)malloc( sizeof(double) * BLOCK_LEN_SHORT * 2 );
+	yl = (double *)malloc( sizeof(double) * BLOCK_LEN_SHORT * 2 );
+
+	for(l = 0; l < MAX_SHORT_WINDOWS; ++l){
+
+        /* window */        
+        for(i = 0; i < BLOCK_LEN_SHORT*2; ++i){
+			xl[i] = fft_tbl_short->hw[i] * sample[ch][/*OFFSET_FOR_SHORT +*/ BLOCK_LEN_SHORT * l + i];
+			yl[i] = 0.0;
+		}
+
+		n = BLOCK_LEN_SHORT*2;
+		n4 = n/4;
+
+		for (i = 0; i < n; ++i) {    /* bit inverse */
+			j = fft_tbl_short->brt[i];
+			if (i < j) {
+				t = xl[i];  xl[i] = xl[j];  xl[j] = t;
+				t = yl[i];  yl[i] = yl[j];  yl[j] = t;
+			}
+		}
+		for (k = 1; k < n; k = k2) {    /* translation */
+			h = 0;  k2 = k + k;  d = n / k2;
+			for (j = 0; j < k; j++) {
+				c = fft_tbl_short->st[h + n4];
+				s = fft_tbl_short->st[h];
+				for (i = j; i < n; i += k2) {
+					ik = i + k;
+					dx = s * yl[ik] + c * xl[ik];
+					dy = c * yl[ik] - s * xl[ik];
+					xl[ik] = xl[i] - dx;  xl[i] += dx;
+					yl[ik] = yl[i] - dy;  yl[i] += dy;
+				}
+				h += d;
+			}
+		}
+
+		for(w = 0; w < BLOCK_LEN_SHORT; w++){
+			psy_stvar_short->fft_r[l][w] 
+				= sqrt(xl[w]*xl[w] + yl[w]*yl[w]);
+
+			if( xl[w] > 0.0 ){
+				if( yl[w] >= 0.0 )
+					psy_stvar_short->fft_f[l][w] = atan( yl[w] / xl[w] );
+				else
+					psy_stvar_short->fft_f[l][w] = atan( yl[w] / xl[w] )+ M_PI * 2.0;
+			} else if( xl[w] < 0.0 ) {
+				psy_stvar_short->fft_f[l][w] = atan( yl[w] / xl[w] ) + M_PI;
+			} else {
+				if( yl[w] > 0.0 )
+					psy_stvar_short->fft_f[l][w] = M_PI * 0.5;
+				else if( yl[w] < 0.0 )
+					psy_stvar_short->fft_f[l][w] = M_PI * 1.5;
+				else
+					psy_stvar_short->fft_f[l][w] = 0.0; /* tmp */
+			}
+		}
+    }
+
+	if (xl) free(xl);
+	if (yl) free(yl);
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step3(PSY_STATVARIABLE_LONG *psy_stvar_long, 
+               PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+               PSY_VARIABLE_LONG *psy_var_long, 
+               PSY_VARIABLE_SHORT *psy_var_short, 
+               int ch
+	       )
+{
+    int w,i;
+    int p1_l,p2_l;
+
+	p1_l = psy_stvar_long->p_fft - BLOCK_LEN_LONG;
+    if( p1_l < 0 )
+		p1_l = BLOCK_LEN_LONG * 2;
+    p2_l = p1_l - BLOCK_LEN_LONG;
+    if( p2_l < 0 )
+		p2_l = BLOCK_LEN_LONG * 2;
+
+    for(w = 0; w < BLOCK_LEN_LONG; ++w){
+		psy_var_long->r_pred[w] = 2.0 * psy_stvar_long->fft_r[p1_l + w] - psy_stvar_long->fft_r[p2_l + w];
+		psy_var_long->f_pred[w] = 2.0 * psy_stvar_long->fft_f[p1_l + w] - psy_stvar_long->fft_f[p2_l + w];
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(w = 0; w < BLOCK_LEN_SHORT; ++w){
+        psy_var_short->r_pred[0][w] = 2.0 * psy_stvar_short->last7_fft_r[w] - psy_stvar_short->last6_fft_r[w];
+        psy_var_short->f_pred[0][w] = 2.0 * psy_stvar_short->last7_fft_f[w] - psy_stvar_short->last6_fft_f[w];
+        psy_var_short->r_pred[1][w] = 2.0 * psy_stvar_short->fft_r[0][w] - psy_stvar_short->last7_fft_r[w];
+        psy_var_short->f_pred[1][w] = 2.0 * psy_stvar_short->fft_f[0][w] - psy_stvar_short->last7_fft_f[w];
+    }
+
+    for(i = 2; i < MAX_SHORT_WINDOWS; ++i){
+        for(w = 0; w < BLOCK_LEN_SHORT; ++w){
+			psy_var_short->r_pred[i][w] = 2.0 * psy_stvar_short->fft_r[i - 1][w] - psy_stvar_short->fft_r[i - 2][w];
+			psy_var_short->f_pred[i][w] = 2.0 * psy_stvar_short->fft_f[i - 1][w] - psy_stvar_short->fft_f[i - 2][w];
+		}
+    }
+
+    for(w = 0; w < BLOCK_LEN_SHORT; ++w){
+        psy_stvar_short->last6_fft_r[w] = psy_stvar_short->fft_r[6][w];
+		psy_stvar_short->last6_fft_f[w] = psy_stvar_short->fft_f[6][w];
+        psy_stvar_short->last7_fft_r[w] = psy_stvar_short->fft_r[7][w];
+		psy_stvar_short->last7_fft_f[w] = psy_stvar_short->fft_f[7][w];
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step4(PSY_STATVARIABLE_LONG *psy_stvar_long,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short,
+	       int ch
+	       )
+{
+    int w,i;
+    double r,f,rp,fp;
+
+    for(w = 0; w < BLOCK_LEN_LONG; ++w){
+		r = psy_stvar_long->fft_r[psy_stvar_long->p_fft+w];
+		f = psy_stvar_long->fft_f[psy_stvar_long->p_fft+w];
+		rp = psy_var_long->r_pred[w];
+		fp = psy_var_long->f_pred[w];
+		
+		if( r + fabs(rp) != 0.0 )
+			psy_var_long->c[w] = sqrt( psy_sqr(r*cos(f) - rp*cos(fp))
+				+psy_sqr(r*sin(f) - rp*sin(fp)) )/ ( r + fabs(rp) ) ;
+		else
+			psy_var_long->c[w] = 0.0; /* tmp */
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0; i < MAX_SHORT_WINDOWS; ++i){
+        for(w = 0; w < BLOCK_LEN_SHORT; ++w){
+			r = psy_stvar_short->fft_r[i][w];
+			f = psy_stvar_short->fft_f[i][w];
+			rp = psy_var_short->r_pred[i][w];
+			fp = psy_var_short->f_pred[i][w];
+			
+			if( r + fabs(rp) != 0.0 )
+				psy_var_short->c[i][w] = sqrt( psy_sqr(r*cos(f) - rp*cos(fp))
+					+psy_sqr(r*sin(f) - rp*sin(fp)) )/ ( r + fabs(rp) ) ;
+			else
+				psy_var_short->c[i][w] = 0.0; /* tmp */
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step5(PARTITION_TABLE_LONG *part_tbl_long, 
+	       PARTITION_TABLE_SHORT *part_tbl_short, 
+	       PSY_STATVARIABLE_LONG *psy_stvar_long,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short,
+	       int ch
+	       )
+{
+    int b,w,i;
+    double tmp_cb;
+
+    for(b = 0; b < part_tbl_long->len; ++b){
+		psy_var_long->e[b] = 0.0;
+		tmp_cb = 0.0;
+
+		/* added by T. Araki (1997.10.16) */
+		for(w = part_tbl_long->w_low[b]; w <= part_tbl_long->w_high[b]; ++w){
+			psy_var_long->e[b] += psy_sqr(psy_stvar_long->fft_r[psy_stvar_long->p_fft+w]);
+			tmp_cb += psy_sqr(psy_stvar_long->fft_r[psy_stvar_long->p_fft+w]) * psy_var_long->c[w];
+		}
+		/* added by T. Araki (1997.10.16) end */
+
+		psy_var_long->c[b] = tmp_cb;
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0; i < MAX_SHORT_WINDOWS; ++i){
+        for(b = 0; b < part_tbl_short->len; ++b){
+			psy_var_short->e[i][b] = 0.0;
+			tmp_cb = 0.0;
+
+			for(w = part_tbl_short->w_low[b]; w <= part_tbl_short->w_high[b]; ++w){
+				psy_var_short->e[i][b] += psy_sqr(psy_stvar_short->fft_r[i][w]);
+				tmp_cb += psy_sqr(psy_stvar_short->fft_r[i][w]) * psy_var_short->c[i][w]; 
+			}
+
+			psy_var_short->c[i][b] = tmp_cb;
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step6(PARTITION_TABLE_LONG *part_tbl_long, 
+	       PARTITION_TABLE_SHORT *part_tbl_short, 
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       )
+{
+    int b,bb,i;
+    double ecb,ct;
+    double sprd;
+
+    for(b = 0; b < part_tbl_long->len; ++b){
+		ecb = 0.0;
+		ct = 0.0;
+		for(bb = 0; bb < part_tbl_long->len; ++bb){
+			sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 0);
+			ecb += psy_var_long->e[bb] * sprd;
+			ct += psy_var_long->c[bb] * sprd;
+		}
+		if (ecb!=0.0) {
+			psy_var_long->cb[b] = ct / ecb;
+		} else {
+			psy_var_long->cb[b] = 0.0;
+		}
+		psy_var_long->en[b] = ecb * part_tbl_long->rnorm[b];
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0; i < MAX_SHORT_WINDOWS; ++i){ 
+        for(b = 0; b < part_tbl_short->len; ++b){
+			ecb = 0.0;
+			ct = 0.0;
+			for(bb = 0; bb < part_tbl_short->len; ++bb){
+				sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 1);
+				ecb += psy_var_short->e[i][bb] * sprd;
+				ct += psy_var_short->c[i][bb] * sprd;
+			}
+			if (ecb!=0.0) {	
+				psy_var_short->cb[i][b] = ct / ecb;
+			} else {
+				psy_var_short->cb[i][b] = 0.0;
+			}
+			psy_var_short->en[i][b] = ecb * part_tbl_short->rnorm[b];
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step7(PARTITION_TABLE_LONG *part_tbl_long,
+	       PARTITION_TABLE_SHORT *part_tbl_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short)
+{
+    int b,i;
+
+    for(b = 0; b < part_tbl_long->len; ++b){
+		if (psy_var_long->cb[b] > 0.0) {
+			psy_var_long->tb[b] = -0.299 - 0.43 * log(psy_var_long->cb[b]);
+		} else {
+			psy_var_long->tb[b] = 1.0;
+		}
+		if( psy_var_long->tb[b] > 1.0 )
+			psy_var_long->tb[b] = 1.0;
+		else if( psy_var_long->tb[b] < 0.0 )
+			psy_var_long->tb[b] = 0.0;
+    }
+
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0;  i < MAX_SHORT_WINDOWS; ++i){
+        for(b = 0; b < part_tbl_short->len; ++b){
+			if (psy_var_short->cb[i][b]>0.0) {
+				psy_var_short->tb[i][b] = -0.299 - 0.43 * log(psy_var_short->cb[i][b]);
+			} else {
+				psy_var_short->tb[i][b] = 1.0;
+			}
+			if( psy_var_short->tb[i][b] > 1.0 )
+				psy_var_short->tb[i][b] = 1.0;
+			else if( psy_var_short->tb[i][b] < 0.0 )
+				psy_var_short->tb[i][b] = 0.0;
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+
+void psy_step8(PARTITION_TABLE_LONG *part_tbl_long,
+	       PARTITION_TABLE_SHORT *part_tbl_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short)
+{
+	int b,i;
+	double tmn = 18.0, nmt = 6.0;
+
+	for(b = 0; b < part_tbl_long->len; ++b) {
+		psy_var_long->snr[b] = psy_var_long->tb[b] * tmn + (1.0 - psy_var_long->tb[b] ) * nmt;
+	}
+
+	/* added by T. Araki (1997.10.16) */
+	for(i = 0;  i < MAX_SHORT_WINDOWS; ++i){
+		for(b = 0; b < part_tbl_short->len; ++b)
+			psy_var_short->snr[i][b] = psy_var_short->tb[i][b] * tmn + (1.0 - psy_var_short->tb[i][b] ) * nmt ;
+	}
+	/* added by T. Araki (1997.10.16) end */
+}    
+
+void psy_step9(PARTITION_TABLE_LONG *part_tbl_long,
+	       PARTITION_TABLE_SHORT *part_tbl_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       )
+{
+    int b,i;
+    
+    for(b = 0; b < part_tbl_long->len; ++b)
+		psy_var_long->bc[b] = pow(10.0, -psy_var_long->snr[b]/10.0);
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0;  i < MAX_SHORT_WINDOWS; ++i){
+        for(b = 0; b < part_tbl_short->len; ++b)
+			psy_var_short->bc[i][b] = pow(10.0, -psy_var_short->snr[i][b]/10.0);
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step10(PARTITION_TABLE_LONG *part_tbl_long,
+		PARTITION_TABLE_SHORT *part_tbl_short,
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		PSY_VARIABLE_LONG *psy_var_long, 
+		PSY_VARIABLE_SHORT *psy_var_short,
+		int ch
+		)
+{
+    int b,i;
+    
+    psy_stvar_long->p_nb += NPART_LONG;
+
+    if( psy_stvar_long->p_nb == NPART_LONG*2 ) psy_stvar_long->p_nb = 0;
+
+    for(b = 0; b < part_tbl_long->len; ++b){
+		psy_stvar_long->nb[psy_stvar_long->p_nb + b]
+			= psy_var_long->en[b] * psy_var_long->bc[b];
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0;  i < MAX_SHORT_WINDOWS; ++i){
+        for(b = 0; b < part_tbl_short->len; ++b){
+			psy_stvar_short->nb[i][b]
+				= psy_var_short->en[i][b] * psy_var_short->bc[i][b];
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step11(PARTITION_TABLE_LONG *part_tbl_long, 
+		PARTITION_TABLE_SHORT *part_tbl_short, 
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		int ch
+		)
+{
+    int b,i;
+    int p1,p2;
+	double temp;
+
+    p1 = psy_stvar_long->p_nb;
+    if( p1 == 0 ) p2 = NPART_LONG;
+    else if( p1 == NPART_LONG ) p2 = 0;
+
+    for(b = 0; b < part_tbl_long->len; b++) {
+		temp = psy_min( psy_stvar_long->nb[p1+b],2.0*psy_stvar_long->nb[p2+b]);
+		if (temp > 0.01)
+			psy_stvar_long->nb[p1+b] = temp;
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(b = 0; b < part_tbl_short->len; ++b){
+		temp = psy_min( psy_stvar_short->nb[0][b], 2.0*psy_stvar_short->last7_nb[b]);
+		if (temp > 0.01)
+			psy_stvar_short->nb[0][b] = temp;
+    }
+
+	for(b = 0; b < part_tbl_short->len; ++b){
+		psy_stvar_short->last7_nb[b] = psy_stvar_short->nb[7][b];
+	}
+
+	for(i = 1;  i < MAX_SHORT_WINDOWS; i++){
+		for(b = 0; b < part_tbl_short->len; b++){
+			temp = psy_min( psy_stvar_short->nb[i][b],2.0*psy_stvar_short->nb[i - 1][b]);
+			if (temp > 0.01)
+				psy_stvar_short->nb[i][b] = temp;
+		}
+	}
+	/* added by T. Araki (1997.10.16) end */
+}
+
+void psy_step11andahalf(PARTITION_TABLE_LONG *part_tbl_long, 
+						PARTITION_TABLE_SHORT *part_tbl_short, 
+						PSY_STATVARIABLE_LONG *psy_stvar_long, 
+						PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+						int ch)
+{
+
+	int b, i,p1,p2;
+	double t;
+	double tempL, tempR, tempM, tempS;
+
+    p1 = psy_stvar_long->p_nb;
+    if( p1 == 0 ) p2 = NPART_LONG;
+    else if( p1 == NPART_LONG ) p2 = 0;
+
+	if (ch==3) {
+		for(b = 0; b < part_tbl_long->len; b++) {
+			t = psy_stvar_long[2].nb[p1+b]/psy_stvar_long[3].nb[p1+b];
+			if (t>1)
+				t = 1/t;
+			tempL = max(psy_stvar_long[0].nb[p1+b]*t, min(psy_stvar_long[0].nb[p1+b], part_tbl_long->bmax[b]*psy_stvar_long[0].en[b]));
+			tempR = max(psy_stvar_long[1].nb[p1+b]*t, min(psy_stvar_long[1].nb[p1+b], part_tbl_long->bmax[b]*psy_stvar_long[1].en[b]));
+
+			t = min(tempL,tempR);
+			tempM = min(t, max(psy_stvar_long[2].nb[p1+b], min(part_tbl_long->bmax[b]*psy_stvar_long[3].en[b], psy_stvar_long[3].nb[p1+b])));
+			tempS = min(t, max(psy_stvar_long[3].nb[p1+b], min(part_tbl_long->bmax[b]*psy_stvar_long[2].en[b], psy_stvar_long[2].nb[p1+b])));
+
+			if ((psy_stvar_long[0].nb[p1+b] >= 1.58*psy_stvar_long[1].nb[p1+b])&&(psy_stvar_long[1].nb[p1+b] >= 1.58*psy_stvar_long[0].nb[p1+b])) {
+				psy_stvar_long[2].nb[p1+b] = tempM;
+				psy_stvar_long[3].nb[p1+b] = tempS;
+			}
+		}
+
+		for (i = 0; i < MAX_SHORT_WINDOWS; i++) {
+			for(b = 0; b < part_tbl_short->len; b++) {
+				t = psy_stvar_short[2].nb[i][b]/psy_stvar_short[3].nb[i][b];
+				if (t>1)
+					t = 1/t;
+				tempL = max(psy_stvar_short[0].nb[i][b]*t, min(psy_stvar_short[0].nb[i][b], part_tbl_short->bmax[b]*psy_stvar_short[0].en[i][b]));
+				tempR = max(psy_stvar_short[1].nb[i][b]*t, min(psy_stvar_short[1].nb[i][b], part_tbl_short->bmax[b]*psy_stvar_short[1].en[i][b]));
+
+				t = min(tempL,tempR);
+				tempM = min(t, max(psy_stvar_short[2].nb[i][b], min(part_tbl_short->bmax[b]*psy_stvar_short[3].en[i][b], psy_stvar_short[3].nb[i][b])));
+				tempS = min(t, max(psy_stvar_short[3].nb[i][b], min(part_tbl_short->bmax[b]*psy_stvar_short[2].en[i][b], psy_stvar_short[2].nb[i][b])));
+
+				if ((psy_stvar_short[0].nb[i][b] >= 1.58*psy_stvar_short[1].nb[i][b])&&(psy_stvar_short[1].nb[i][b] >= 1.58*psy_stvar_short[0].nb[i][b])) {
+					psy_stvar_short[2].nb[i][b] = tempM;
+					psy_stvar_short[3].nb[i][b] = tempS;
+				}
+			}
+		}
+	}
+}
+
+
+/* added by T. Araki (1997.7.10) */
+void psy_step12(PARTITION_TABLE_LONG *part_tbl_long,
+				PARTITION_TABLE_SHORT *part_tbl_short,
+				PSY_STATVARIABLE_LONG *psy_stvar_long,
+				PSY_STATVARIABLE_SHORT *psy_stvar_short,
+				PSY_VARIABLE_LONG *psy_var_long,
+				PSY_VARIABLE_SHORT *psy_var_short,
+				int ch
+				)
+{
+    int b;
+
+    psy_var_long->pe = 0.0;
+    for(b = 0; b < part_tbl_long->len; ++b){
+		double tp = log((psy_stvar_long->nb[psy_stvar_long->p_nb + b] + 0.0001)
+			/ (psy_var_long->e[b] + 0.0001)); 
+
+		tp = min(0.0, tp);
+		psy_var_long->pe -= part_tbl_long->width[b] * tp;
+    }
+}
+
+void psy_step13(PSY_VARIABLE_LONG *psy_var_long, 
+	        enum WINDOW_TYPE *block_type,
+		int ch
+		)
+{
+//	if (psy_var_long->pe < 1800)
+//	printf("%f\n", psy_var_long->pe);
+	if(psy_var_long->pe < 1800) {
+        *block_type = ONLY_LONG_WINDOW;
+	} else {
+        *block_type = ONLY_SHORT_WINDOW;
+	}
+}
+
+void psy_step14(SR_INFO *p_sri,
+				PARTITION_TABLE_LONG *part_tbl_long, 
+				PARTITION_TABLE_SHORT *part_tbl_short,
+				PSY_STATVARIABLE_LONG *psy_stvar_long,
+				PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+				PSY_VARIABLE_LONG *psy_var_long, 
+				PSY_VARIABLE_SHORT *psy_var_short,
+				int ch
+				)
+{
+    int b, n, w, i;
+    int w_low, w_high;
+    double thr, minthr;
+    
+    w_high = 0;
+    for(n = 0; n < p_sri->num_cb_long; ++n){
+		w_low = w_high;
+		w_high += p_sri->cb_width_long[n];
+
+        psy_var_long->epart[n] = 0.0;
+		for(w = w_low; w < w_high; ++w){
+			psy_var_long->epart[n] += psy_sqr(psy_stvar_long->fft_r[psy_stvar_long->p_fft + w]);
+		}
+    }
+
+    for(b = 0; b < part_tbl_long->len; ++b){
+        thr = psy_stvar_long->nb[psy_stvar_long->p_nb + b]
+			/ part_tbl_long->width[b];
+        for(w = part_tbl_long->w_low[b]; w <= part_tbl_long->w_high[b]; ++w){
+			psy_var_long->thr[w] = thr;
+		}
+    }
+
+    w_high = 0;
+    for(n = 0; n < p_sri->num_cb_long; ++n){
+        w_low = w_high;
+		w_high += p_sri->cb_width_long[n];
+
+        minthr = psy_var_long->thr[w_low];
+		for(w = w_low+1; w < w_high; ++w){
+			if(psy_var_long->thr[w] < minthr){
+				minthr = psy_var_long->thr[w];
+			}
+		}
+
+		psy_var_long->npart[n] = minthr * (w_high - w_low);
+    }
+
+    for(n = 0; n < p_sri->num_cb_long; ++n){
+		if (psy_var_long->epart[n]!=0.0) {
+			psy_stvar_long->ismr[n] = psy_var_long->npart[n] / psy_var_long->epart[n];
+		} else {
+			psy_stvar_long->ismr[n] = 0.0;
+		}
+    }
+
+	/* added by T. Araki (1997.10.16) */
+    for(i = 0; i < MAX_SHORT_WINDOWS; ++i){
+        w_high = 0;
+		for(n = 0; n < p_sri->num_cb_short; ++n){
+			w_low = w_high;
+			w_high += p_sri->cb_width_short[n];
+
+			psy_var_short->epart[i][n] = 0.0;
+			for(w = w_low; w < w_high; ++w){
+				psy_var_short->epart[i][n] += psy_sqr(psy_stvar_short->fft_r[i][w]);
+			}
+		}
+
+		for(b = 0; b < part_tbl_short->len; ++b){
+            thr = psy_stvar_short->nb[i][b] / part_tbl_short->width[b];
+			for(w = part_tbl_short->w_low[b]; w <= part_tbl_short->w_high[b]; ++w){
+				psy_var_short->thr[i][w] = thr;
+			}
+		}
+
+		w_high = 0;
+		for(n = 0; n < p_sri->num_cb_short; ++n){
+            w_low = w_high;
+			w_high += p_sri->cb_width_short[n];
+
+			minthr = psy_var_short->thr[i][w_low];
+			for(w = w_low + 1; w < w_high; ++w){
+				if(psy_var_short->thr[i][w] < minthr){
+					minthr = psy_var_short->thr[i][w];
+				}
+			}
+
+			psy_var_short->npart[i][n] = minthr * (w_high - w_low);
+        }
+
+		for(n = 0; n < p_sri->num_cb_short; ++n){
+			if (psy_var_short->epart[i][n]!=0.0) {
+				psy_stvar_short->ismr[i][n] = psy_var_short->npart[i][n] / psy_var_short->epart[i][n];
+			} else {
+				psy_stvar_short->ismr[i][n] = 0.0;
+			}
+		}
+    }
+	/* added by T. Araki (1997.10.16) end */
+}
+
+
+void psy_step15(int use_ms_l[49],
+				int use_ms_s[8][14],
+				SR_INFO *p_sri,
+				PSY_VARIABLE_LONG *psy_var_long, 
+				PSY_VARIABLE_SHORT *psy_var_short,
+				int ch
+				)
+{
+	static double save_npart_l[49];
+	static double save_npart_s[8][14];
+
+	int b, i;
+	double temp, x1, x2, db;
+
+	if (ch == 0) {
+		for (b = 0; b < p_sri->num_cb_long; b++)
+			save_npart_l[b] = psy_var_long->npart[b];
+		for (i = 0; i < 8; i++)
+			for (b = 0; b < p_sri->num_cb_short; b++)
+				save_npart_s[i][b] = psy_var_short->npart[i][b];
+	}
+
+	if (ch == 1) {
+		for (b = 0; b < p_sri->num_cb_long; b++) {
+			x1 = min(save_npart_l[b],psy_var_long->npart[b]);
+			x2 = max(save_npart_l[b],psy_var_long->npart[b]);
+			if (x2 >= 1000*x1)
+				db=30;
+			else
+				db = 10*log10(x2/x1);
+			temp = 0.35*(db)/5.0;
+//			printf("%d\t%f\n", b, temp);
+			if (temp < 0.5)
+				use_ms_l[b] = 1;
+			else
+				use_ms_l[b] = 0;
+		}
+		for (i = 0; i < 8; i++) {
+			for (b = 0; b < p_sri->num_cb_long; b++) {
+				x1 = min(save_npart_s[i][b],psy_var_short->npart[i][b]);
+				x2 = max(save_npart_s[i][b],psy_var_short->npart[i][b]);
+				if (x2 >= 1000*x1)
+					db=30;
+				else
+					db = 10*log10(x2/x1);
+				temp = 0.35*(db)/5.0;
+//				printf("%d\t%f\n", b, temp);
+				if (temp < 0.5)
+					use_ms_s[i][b] = 1;
+				else
+					use_ms_s[i][b] = 0;
+			}
+		}
+	}
+}
+
+
--- /dev/null
+++ b/psych.h
@@ -1,0 +1,336 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+ "This software module was originally developed by 
+ Fraunhofer Gesellschaft IIS / University of Erlangen (UER) 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.
+
+-----
+This software module was modified by
+
+Tadashi Araki (Ricoh Company, ltd.)
+Tatsuya Okada (Waseda Univ.)
+
+and edited by
+
+in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
+ISO/IEC 13818-7, 14496-1,2 and 3.
+
+Copyright (c) 1997.
+
+ *                                                                           *
+ ****************************************************************************/
+
+/* CREATED BY :  Bernhard Grill -- August-96  */
+
+#include "all.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+typedef struct { 
+  long   sampling_rate;                   /* the following entries are for this sampling rate */
+  int    num_cb_long;
+  int    num_cb_short;
+  int    cb_width_long[NSFB_LONG];
+  int    cb_width_short[NSFB_SHORT+2];
+  double fixed_ratio_long[NSFB_LONG];
+  double fixed_ratio_short[NSFB_SHORT+2];
+} SR_INFO;
+
+/* added by T. Araki (1997.10.17) */
+#define OFFSET_FOR_SHORT 448
+#define NPART_LONG 72
+#define NPART_SHORT 48
+/* added by T. Araki (1997.10.17) end */
+
+/* added by T. Araki (1997.07.10) */
+typedef struct {
+  double hw[BLOCK_LEN_LONG*2];     /* Hann window table */
+  double st[BLOCK_LEN_LONG*5/2];   /* sin table*/
+  int    brt[BLOCK_LEN_LONG*2];    /* bit inverse table */
+} FFT_TABLE_LONG;
+
+typedef struct {
+  double hw[BLOCK_LEN_SHORT*2];     /* Hann window table */
+  double st[BLOCK_LEN_SHORT*5/2];   /* sin table*/
+  int    brt[BLOCK_LEN_SHORT*2];    /* bit inverse table */
+} FFT_TABLE_SHORT;
+ 
+typedef struct {
+  int    sampling_rate;
+  int    len;      /* length of the table */
+  int    w_low[NPART_LONG];
+  int    w_high[NPART_LONG];
+  int    width[NPART_LONG];
+  double bval[NPART_LONG];
+  double qsthr[NPART_LONG];
+  double e_qsthr[NPART_LONG]; /* absolute threshold (energy) in each partition */  
+  double rnorm[NPART_LONG];
+  double bmax[NPART_LONG];
+} PARTITION_TABLE_LONG;
+
+typedef struct {
+  int    sampling_rate;
+  int    len;      /* length of the table */ 
+  int    w_low[NPART_SHORT];
+  int    w_high[NPART_SHORT];
+  int    width[NPART_SHORT];
+  double bval[NPART_SHORT];
+  double qsthr[NPART_SHORT];
+  double e_qsthr[NPART_SHORT]; /* absolute threshold (energy) in each partition */  
+  double rnorm[NPART_SHORT];
+  double bmax[NPART_SHORT];
+} PARTITION_TABLE_SHORT;
+
+typedef struct {
+  double fft_r[BLOCK_LEN_LONG*3];
+  double fft_f[BLOCK_LEN_LONG*3];
+  int    p_fft; /* pointer for fft_r and fft_f */
+  double nb[NPART_LONG*2];
+  double en[NPART_LONG];
+  int    p_nb; /* pointer for nb */
+  double ismr[NSFB_LONG]; /* 1/SMR in each swb */
+} PSY_STATVARIABLE_LONG;
+
+typedef struct {
+  double r_pred[BLOCK_LEN_LONG];
+  double f_pred[BLOCK_LEN_LONG];
+  double c[BLOCK_LEN_LONG];
+  double e[NPART_LONG];
+  double cw[NPART_LONG];
+  double en[NPART_LONG];
+  double cb[NPART_LONG];
+  double tb[NPART_LONG];
+  double snr[NPART_LONG];
+  double bc[NPART_LONG];
+  double pe;
+  double epart[NSFB_LONG];
+  double thr[BLOCK_LEN_LONG];
+  double npart[NSFB_LONG];
+} PSY_VARIABLE_LONG;
+
+typedef struct {
+  double fft_r[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double fft_f[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double last6_fft_r[BLOCK_LEN_SHORT];
+  double last6_fft_f[BLOCK_LEN_SHORT];
+  double last7_fft_r[BLOCK_LEN_SHORT];
+  double last7_fft_f[BLOCK_LEN_SHORT];
+  double nb[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double en[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double last7_nb[NPART_SHORT];
+  double ismr[MAX_SHORT_WINDOWS][NSFB_SHORT]; /* 1/SMR in each swb */
+} PSY_STATVARIABLE_SHORT;
+
+typedef struct {
+  double r_pred[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double f_pred[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double c[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double e[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double cw[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double en[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double cb[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double tb[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double snr[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double bc[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double epart[MAX_SHORT_WINDOWS][NSFB_SHORT];
+  double thr[MAX_SHORT_WINDOWS][BLOCK_LEN_SHORT];
+  double npart[MAX_SHORT_WINDOWS][NSFB_SHORT];
+} PSY_VARIABLE_SHORT;
+/* added by T. Araki (1997.07.10) end */
+
+typedef struct {
+  double *p_ratio;
+  int    *cb_width;
+  int    use_ms[NSFB_LONG];
+  int    no_of_cb;
+} CH_PSYCH_OUTPUT_LONG;
+
+typedef struct {
+  double *p_ratio;
+  int    *cb_width;
+  int    use_ms[NSFB_SHORT];
+  int    no_of_cb;
+} CH_PSYCH_OUTPUT_SHORT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void EncTf_psycho_acoustic_init( void );
+void psy_fill_lookahead(double *p_time_signal[], int no_of_chan);
+void EncTf_psycho_acoustic( 
+  /* input */
+  double sampling_rate,
+  int    no_of_chan,         /* no of audio channels */
+  double *p_time_signal[],
+  enum WINDOW_TYPE block_type[],
+  int qcSelect,
+  int frameLength,
+  /* output */
+  CH_PSYCH_OUTPUT_LONG p_chpo_long[],
+  CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS]
+);
+
+/* added by T. Okada( 1997.07.10 ) */
+/* Jul 10 */
+#define psy_max(x,y) ((x) > (y) ? (x) : (y))
+#define psy_min(x,y) ((x) < (y) ? (x) : (y))
+#define psy_sqr(x) ((x)*(x))
+
+
+double psy_get_absthr(double f); /* Jul 8 */
+//double sprdngf(double b1,double b2);
+double sprdngf(PARTITION_TABLE_LONG *part_tbl_long,
+			   PARTITION_TABLE_SHORT *part_tbl_short,
+			   int bb1, int bb2, int short_block);
+double sprdngf2(double b1, double b2);
+
+void psy_fft_table_init(FFT_TABLE_LONG *fft_tbl_long, 
+			FFT_TABLE_SHORT *fft_tbl_short
+			);
+
+void psy_part_table_init(double sampling_rate,
+			 PARTITION_TABLE_LONG **part_tbl_long, 
+			 PARTITION_TABLE_SHORT **part_tbl_short
+			 );
+
+void psy_calc_init(double sample[][BLOCK_LEN_LONG*2],
+		   PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		   PSY_STATVARIABLE_SHORT *psy_stvar_short
+		   ); 
+
+void psy_step1(double* p_time_signal[], 
+	       double sample[][BLOCK_LEN_LONG*2], 
+	       int ch
+	       );
+
+void psy_step2(double sample[][BLOCK_LEN_LONG*2], 
+               PSY_STATVARIABLE_LONG *psy_stvar_long, 
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       FFT_TABLE_LONG *fft_tbl_long,
+	       FFT_TABLE_SHORT *fft_tbl_short,
+	       int ch
+	       );
+
+void psy_step3(PSY_STATVARIABLE_LONG *psy_stvar_long, 
+               PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+               PSY_VARIABLE_LONG *psy_var_long, 
+               PSY_VARIABLE_SHORT *psy_var_short, 
+               int ch
+	       );
+
+void psy_step4(PSY_STATVARIABLE_LONG *psy_stvar_long,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short,
+	       int ch
+	       );
+
+void psy_step5(PARTITION_TABLE_LONG *part_tbl_long, 
+	       PARTITION_TABLE_SHORT *part_tbl_short, 
+	       PSY_STATVARIABLE_LONG *psy_stvar_long,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short,
+	       int ch
+	       );
+
+void psy_step6(PARTITION_TABLE_LONG *part_tbl_long, 
+	       PARTITION_TABLE_SHORT *part_tbl_short, 
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       );
+
+void psy_step7(PARTITION_TABLE_LONG *part_tbl_long, 
+	       PARTITION_TABLE_SHORT *part_tbl_short, 
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       );
+
+void psy_step8(PARTITION_TABLE_LONG *part_tbl_long,
+	       PARTITION_TABLE_SHORT *part_tbl_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       );
+
+void psy_step9(PARTITION_TABLE_LONG *part_tbl_long,
+	       PARTITION_TABLE_SHORT *part_tbl_short,
+	       PSY_VARIABLE_LONG *psy_var_long, 
+	       PSY_VARIABLE_SHORT *psy_var_short
+	       );
+
+void psy_step10(PARTITION_TABLE_LONG *part_tbl_long,
+		PARTITION_TABLE_SHORT *part_tbl_short,
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		PSY_VARIABLE_LONG *psy_var_long, 
+		PSY_VARIABLE_SHORT *psy_var_short,
+		int ch /* ch */
+		);
+
+void psy_step11(PARTITION_TABLE_LONG *part_tbl_long, 
+		PARTITION_TABLE_SHORT *part_tbl_short, 
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		int ch
+		);
+
+void psy_step11andahalf(PARTITION_TABLE_LONG *part_tbl_long, 
+						PARTITION_TABLE_SHORT *part_tbl_short, 
+						PSY_STATVARIABLE_LONG *psy_stvar_long, 
+						PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+						int ch);
+
+void psy_step12(PARTITION_TABLE_LONG *part_tbl_long, 
+		PARTITION_TABLE_SHORT *part_tbl_short, 
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		PSY_VARIABLE_LONG *psy_var_long, 
+		PSY_VARIABLE_SHORT *psy_var_short,
+		int ch
+		);
+
+void psy_step13(PSY_VARIABLE_LONG *psy_var_long, 
+		enum WINDOW_TYPE *block_type,
+		int ch
+		);
+
+void psy_step14(SR_INFO *p_sri,
+		PARTITION_TABLE_LONG *part_tbl_long, 
+		PARTITION_TABLE_SHORT *part_tbl_short, 
+		PSY_STATVARIABLE_LONG *psy_stvar_long, 
+		PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+		PSY_VARIABLE_LONG *psy_var_long, 
+		PSY_VARIABLE_SHORT *psy_var_short,
+		int ch);
+
+void psy_step15(int use_ms_l[49],
+				int use_ms_s[8][14],
+				SR_INFO *p_sri,
+				PSY_VARIABLE_LONG *psy_var_long, 
+				PSY_VARIABLE_SHORT *psy_var_short,
+				int ch
+				);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+++ b/pulse.c
@@ -1,0 +1,86 @@
+
+#include "aac_qc.h"
+#include "pulse.h"
+
+#define STARTSFB 16 // approx. 2kHz
+
+void PulseCoder(AACQuantInfo *quantInfo, int *quant)
+{
+	int i, j, sb, k;
+	int pulses = 0;
+	pulse pul_arr[4];
+
+#if 1
+	for (sb = STARTSFB; sb < quantInfo->nr_of_sfb; sb++)
+	{
+		for (i = quantInfo->sfb_offset[sb]; i < quantInfo->sfb_offset[sb+1]; i++)
+		{
+			if ((i != 0)&&(i<quantInfo->sfb_offset[quantInfo->nr_of_sfb]))
+			{
+				/* This is a peak */
+				if ((abs(quant[i]) > abs(quant[i-1])+4)&&(abs(quant[i]) > abs(quant[i+1])+4))
+				{
+					pulses++;
+					if (pulses == 1) {
+						j = i;
+						pul_arr[pulses-1].offset = i-quantInfo->sfb_offset[sb];
+						pul_arr[pulses-1].sfb = sb;
+						pul_arr[pulses-1].amp = min(15,(int)(abs((quant[i-1])+abs(quant[i+1]))/2+0.5));
+						if (pul_arr[pulses-1].offset >= 32) {
+							pulses = 0;
+						}
+					} else {
+						pul_arr[pulses-1].offset = i-j;
+						j = i;
+						pul_arr[pulses-1].amp = min(15,(int)((abs(quant[i-1])+abs(quant[i+1]))/2+0.5));
+						if (pul_arr[pulses-1].offset >= 32) {
+							pulses--;
+							goto end;
+						}
+					}
+				}
+				if (pulses == 4)
+					goto end;
+			}
+		}
+	}
+#endif
+
+end:
+	if (pulses) {
+		quantInfo->pulseInfo.pulse_data_present = 1;
+		quantInfo->pulseInfo.number_pulse = pulses-1;
+		quantInfo->pulseInfo.pulse_start_sfb = pul_arr[0].sfb;
+		k = quantInfo->sfb_offset[pul_arr[0].sfb];
+
+		for (i = 0; i < pulses; i++) {
+			quantInfo->pulseInfo.pulse_offset[i] = pul_arr[i].offset;
+			quantInfo->pulseInfo.pulse_amp[i] = pul_arr[i].amp;
+
+			k += pul_arr[i].offset;
+			if (quant[k] > 0)
+				quant[k] -= pul_arr[i].amp;
+			else
+				quant[k] += pul_arr[i].amp;
+		}
+	} else {
+		quantInfo->pulseInfo.pulse_data_present = 0;
+	}
+}
+
+void PulseDecoder(AACQuantInfo *quantInfo, int *quant)
+{
+	int i, offset;
+
+	if (quantInfo->pulseInfo.pulse_data_present)
+	{
+		offset = quantInfo->sfb_offset[quantInfo->pulseInfo.pulse_start_sfb];
+		for(i = 0; i < quantInfo->pulseInfo.number_pulse+1; i++) {
+			offset += quantInfo->pulseInfo.pulse_offset[i];
+			if (quant[offset] > 0)
+				quant[offset] -= quantInfo->pulseInfo.pulse_amp[i];
+			else
+				quant[offset] += quantInfo->pulseInfo.pulse_amp[i];
+		}
+	}
+}
--- /dev/null
+++ b/pulse.h
@@ -1,0 +1,30 @@
+
+#ifndef PULSE_H_
+#define PULSE_H_
+
+#include "interface.h"
+//#define LEN_NEC_NPULSE	2
+//#define LEN_NEC_ST_SFB	6
+//#define LEN_NEC_POFF	5
+//#define LEN_NEC_PAMP	4
+//#define NUM_NEC_LINES	4
+//#define NEC_OFFSET_AMP	4
+
+typedef struct
+{
+    int pulse_data_present;
+    int number_pulse;
+    int pulse_start_sfb;
+    int pulse_position[NUM_NEC_LINES];
+    int pulse_offset[NUM_NEC_LINES];
+    int pulse_amp[NUM_NEC_LINES];
+} AACPulseInfo;
+
+typedef struct {
+	int offset;
+	int sfb;
+	int amp;
+} pulse;
+
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/tables.h
@@ -1,0 +1,49 @@
+/*
+** Copyright (C) 1999 Albert L. Faber
+**  
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TABLES_H_INCLUDED
+#define TABLES_H_INCLUDED
+
+extern FLOAT8 psy_data[];
+
+#define HUFFBITS unsigned long int
+#define HTN	34
+ 
+struct huffcodetab {
+  unsigned int xlen; 	/*max. x-index+			      	*/ 
+  unsigned int linmax;	/*max number to be stored in linbits	*/
+  HUFFBITS *table;	/*pointer to array[xlen][ylen]		*/
+  unsigned char *hlen;	/*pointer to array[xlen][ylen]		*/
+};
+
+extern struct huffcodetab ht[HTN];/* global memory block		*/
+				/* array of all huffcodtable headers	*/
+				/* 0..31 Huffman code table 0..31	*/
+				/* 32,33 count1-tables			*/
+
+struct scalefac_struct
+{
+   int l[23];
+   int s[14];
+};
+extern struct scalefac_struct sfBandIndex[];  /* Table B.8 -- in loop.c */
+
+
+
+#endif
--- /dev/null
+++ b/tf_main.h
@@ -1,0 +1,142 @@
+/************************* MPEG-2 NBC Audio Decoder **************************
+ *                                                                           *
+ "This software module was originally developed by 
+ Fraunhofer Gesellschaft IIS / University of Erlangen (UER) 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/* CREATED BY :  Bernhard Grill -- June-96  */
+
+/* 28-Aug-1996  NI: added "NO_SYNCWORD" to enum TRANSPORT_STREAM */
+/* 17-Spe-1997  CL: added AAC_PROFILE enum */
+
+#ifndef _TF_MAIN_H_INCLUDED
+#define _TF_MAIN_H_INCLUDED
+
+#include "bitstream.h"
+#include "block.h"
+
+/* AAC Profile */
+enum AAC_PROFILE { MAIN, LOW, SSR };
+
+/* select different pre-/post- processing modules TK */
+enum PP_MOD_SELECT { NONE=0x0, AAC_PP=0x1 };
+
+/* select different T/F modules */
+enum TF_MOD_SELECT { VM_TF_SOURCE=0x1, MDCT_AAC=0x2, MDCT_UER=0x4, QMF_MDCT_SONY=0x8, LOW_DELAY_UNH=0x10 };
+
+/* select different Q&C modules */
+enum QC_MOD_SELECT { VM_QC_SOURCE=0x1, AAC_QC=0x2, MDCT_VALUES_16BIT=0x4, UER_QC=0x8, NTT_VQ=0x10 , AAC_PRED=0x20};
+
+/* name the audio channels */
+enum CHANN_ASS { 
+  MONO_CHAN=0,
+  LEFT_CHAN=0, 
+  RIGHT_CHAN=1,
+  MAX_CHANNELS
+};
+
+/* audio channel configuration coding */
+enum CH_CONFIG { CHC_MONO, CHC_DUAL, CHC_JOINT_DUAL, CHC_5CHAN, CHC_MODES };
+
+/* transport layer type */ /* added "NO_SYNCWORD" by NI (28 Aug. 1996) */
+enum TRANSPORT_STREAM { NO_TSTREAM, AAC_RAWDATA_TSTREAM, LENINFO_TSTREAM,
+		        NO_SYNCWORD};
+
+enum SR_CODING { SR8000, SR11025, SR12000, SR16000, SR22050, SR24000, SR32000, SR44100, SR48000, SR96000, MAX_SAMPLING_RATES };
+
+enum WINDOW_TYPE { 
+  ONLY_LONG_WINDOW, 
+  LONG_SHORT_WINDOW, 
+  ONLY_SHORT_WINDOW,
+  SHORT_LONG_WINDOW,
+  SHORT_MEDIUM_WINDOW,
+  MEDIUM_LONG_WINDOW,
+  LONG_MEDIUM_WINDOW,
+  MEDIUM_SHORT_WINDOW,
+  ONLY_MEDIUM_WINDOW,
+  
+  LONG_START_WINDOW,
+  EIGHT_SHORT_WINDOW,
+  LONG_STOP_WINDOW
+};    
+
+enum AAC_WINDOW_SEQUENCE { /* TK */
+  ONLY_LONG_SEQUENCE = ONLY_LONG_WINDOW,
+  LONG_START_SEQUENCE = LONG_SHORT_WINDOW,
+  EIGHT_SHORT_SEQUENCE = ONLY_SHORT_WINDOW,
+  LONG_STOP_SEQUENCE = SHORT_LONG_WINDOW
+};
+
+enum WIN_SWITCH_MODE {
+  STATIC_LONG,
+  STATIC_MEDIUM,
+  STATIC_SHORT,
+  LS_STARTSTOP_SEQUENCE,
+  LM_STARTSTOP_SEQUENCE,
+  MS_STARTSTOP_SEQUENCE,
+  LONG_SHORT_SEQUENCE,
+  LONG_MEDIUM_SEQUENCE,
+  MEDIUM_SHORT_SEQUENCE,
+  LONG_MEDIUM_SHORT_SEQUENCE,
+  FFT_PE_WINDOW_SWITCHING
+};
+
+#define NSFB_LONG  49
+#define NSFB_SHORT 14
+#define MAX_SHORT_IN_LONG_BLOCK 8
+
+#define MAX_SHORT_WINDOWS 8
+
+/* if static memory allocation is used, this value tells the max. nr of 
+   audio channels to be supported */
+/*#define MAX_TIME_CHANNELS (MAX_CHANNELS)*/
+#define MAX_TIME_CHANNELS 2 //6
+
+/* max. number of scale factor bands */
+#define MAX_SCFAC_BANDS ((NSFB_SHORT/*+1*/)*MAX_SHORT_IN_LONG_BLOCK)
+
+void freq2buffer(
+  double           p_in_data[], 
+  double           p_out_data[],
+  double           p_overlap[],
+  enum WINDOW_TYPE block_type,
+  int              nlong,            /* shift length for long windows   */
+  int              nmed,             /* shift length for medium windows */
+  int              nshort,           /* shift length for short windows  */
+  Window_shape     wfun_select,      /* offers the possibility to select different window functions */
+  Mdct_in	   overlap_select);    /* select imdct output *TK*	*/
+
+void buffer2freq(                    /* Input: Time signal              */
+  double           p_in_data[],      /* Output: MDCT cofficients        */
+  double           p_out_mdct[],
+  double           p_overlap[],
+  enum WINDOW_TYPE block_type,
+  Window_shape     wfun_select,      /* offers the possibility to select different window functions */
+  int              nlong,            /* shift length for long windows   */
+  int              nmed,             /* shift length for medium windows */
+  int              nshort,            /* shift length for short windows  */
+  Mdct_in        overlap_select      /* YT 970615 for Son_PP */
+);
+
+void __inline imdct(double in_data[], double out_data[], int len);
+
+#endif	/* #ifndef _TF_MAIN_H_INCLUDED */
+
--- /dev/null
+++ b/tns.c
@@ -1,0 +1,447 @@
+
+#include <math.h>
+#include <stdlib.h>
+#include "tns.h"
+#include "aacenc.h"
+
+/***********************************************/
+/* TNS Profile/Frequency Dependent Parameters  */
+/***********************************************/
+static unsigned long tnsSupportedSamplingRates[13] = 
+  {8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,0};
+
+/* Limit bands to > 1.5 kHz */
+/*static unsigned short tnsMinBandNumberLong[12] = 
+  { 26, 25, 24, 20, 23, 22, 17, 14, 13, 12, 9, 8 };
+static unsigned short tnsMinBandNumberShort[12] = 
+  { 10, 9, 8, 8, 5, 4, 3, 3, 2, 2, 1, 1 }; */
+       
+/* Limit bands to > 2.0 kHz */
+static unsigned short tnsMinBandNumberLong[12] = 
+  { 31, 30, 28, 24, 26, 25, 20, 17, 16, 15, 12, 11 };
+static unsigned short tnsMinBandNumberShort[12] = 
+  { 12, 10, 10, 8, 6, 6, 4, 3, 3, 2, 2, 2 };
+       
+/**************************************/
+/* Main/Low Profile TNS Parameters    */
+/**************************************/
+static unsigned short tnsMaxBandsLongMainLow[12] = 
+  { 39, 42, 42, 42, 46, 46, 51, 42, 40, 34, 31, 31 };
+
+static unsigned short tnsMaxBandsShortMainLow[12] = 
+  { 14, 14, 14, 14, 14, 14, 14, 14, 14, 10, 9, 9 };
+
+static unsigned short tnsMaxOrderLongMain = 20;
+static unsigned short tnsMaxOrderLongLow = 12;
+static unsigned short tnsMaxOrderShortMainLow = 7;
+
+/**************************************/
+/* SSR Profile TNS Parameters         */
+/**************************************/
+static unsigned short tnsMaxBandsLongSSR[12] = 
+  { 19, 23, 23, 23, 29, 29, 26, 26, 26, 27, 28, 28 };
+
+static unsigned short tnsMaxBandsShortSSR[12] = 
+  { 7, 8, 8, 8, 7, 7, 6, 6, 6, 7, 7, 7 };
+
+static unsigned short tnsMaxOrderLongSSR = 12;
+static unsigned short tnsMaxOrderShortSSR = 7;
+
+
+/*****************************************************/
+/* InitTns:                                          */
+/*****************************************************/
+void TnsInit(long samplingRate,enum AAC_PROFILE profile,TNS_INFO* tnsInfo) 
+{
+  int fsIndex=0;
+
+  /* Determine if sampling rate is supported */
+  while (samplingRate!=tnsSupportedSamplingRates[fsIndex]) {
+    fsIndex++;
+  }
+  
+  switch( profile ) {
+    case MAIN :
+      tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
+      tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
+      tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongMain;
+      tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
+      break;
+    case LOW :
+      tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
+      tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
+      tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongLow;
+      tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
+      break;
+    case SSR :
+      tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongSSR[fsIndex];
+      tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortSSR[fsIndex];
+      tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongSSR;
+      tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortSSR;
+      break;
+  }
+  tnsInfo->tnsMinBandNumberLong = tnsMinBandNumberLong[fsIndex];
+  tnsInfo->tnsMinBandNumberShort = tnsMinBandNumberShort[fsIndex];
+}
+
+
+/*****************************************************/
+/* TnsEncode:                                        */
+/*****************************************************/
+int TnsEncode(int numberOfBands,       /* Number of bands per window */
+	       int maxSfb,              /* max_sfb */
+	       enum WINDOW_TYPE blockType,   /* block type */
+	       int* sfbOffsetTable,     /* Scalefactor band offset table */
+	       double* spec,            /* Spectral data array */
+	       TNS_INFO* tnsInfo)       /* TNS info */
+{
+	int numberOfWindows,windowSize;
+	int startBand,stopBand,order;    /* Bands over which to apply TNS */
+	int lengthInBands;               /* Length to filter, in bands */
+	int w, error;
+	int startIndex,length;
+	double gain;
+
+	switch( blockType ) {
+	case ONLY_SHORT_WINDOW :
+		numberOfWindows = NSHORT;
+		windowSize = SN2;
+		startBand = tnsInfo->tnsMinBandNumberShort;
+		stopBand = numberOfBands; 
+		lengthInBands = stopBand-startBand;
+		order = tnsInfo->tnsMaxOrderShort;
+		startBand = min(startBand,tnsInfo->tnsMaxBandsShort);
+		stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort);
+		break;
+
+	default:
+		numberOfWindows = 1;
+		windowSize = LN2;
+		startBand = tnsInfo->tnsMinBandNumberLong;
+		stopBand = numberOfBands;
+		lengthInBands = stopBand - startBand;
+		order = tnsInfo->tnsMaxOrderLong;
+		startBand = min(startBand,tnsInfo->tnsMaxBandsLong);
+		stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong);
+		break;
+	}
+	
+	/* Make sure that start and stop bands < maxSfb */
+	/* Make sure that start and stop bands >= 0 */
+	startBand = min(startBand,maxSfb);
+	stopBand = min(stopBand,maxSfb);
+	startBand = max(startBand,0);
+	stopBand = max(stopBand,0);
+
+	tnsInfo->tnsDataPresent=0;     /* default TNS not used */
+
+#if 1
+	/* Doesn't work well on short windows. */
+	if (blockType != ONLY_SHORT_WINDOW)
+	/* Perform analysis and filtering for each window */
+	for (w=0;w<numberOfWindows;w++) {
+
+		TNS_WINDOW_DATA* windowData = &tnsInfo->windowData[w];
+		TNS_FILTER_DATA* tnsFilter = windowData->tnsFilter;
+		double* k = tnsFilter->kCoeffs;    /* reflection coeffs */
+		double* a = tnsFilter->aCoeffs;    /* prediction coeffs */
+
+		windowData->numFilters=0;
+		windowData->coefResolution = DEF_TNS_COEFF_RES;
+		startIndex = w * windowSize + sfbOffsetTable[startBand];
+		length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand];
+		gain = LevinsonDurbin(order,length,&spec[startIndex],k);
+
+		if (gain>DEF_TNS_GAIN_THRESH) {  /* Use TNS */
+			int truncatedOrder;
+
+			windowData->numFilters++;
+			tnsInfo->tnsDataPresent=1;
+			tnsFilter->direction = 0;
+			tnsFilter->coefCompress = 0;
+			tnsFilter->length = lengthInBands;
+			QuantizeReflectionCoeffs(order,DEF_TNS_COEFF_RES,k,tnsFilter->index);
+			truncatedOrder = TruncateCoeffs(order,DEF_TNS_COEFF_THRESH,k);
+			tnsFilter->order = truncatedOrder;
+			StepUp(truncatedOrder,k,a);    /* Compute predictor coefficients */
+			error = TnsInvFilter(length,&spec[startIndex],tnsFilter);      /* Filter */
+			if (error == FERROR)
+				return FERROR;
+		}
+	}
+	return FNO_ERROR;
+#endif
+}
+
+
+/*****************************************************/
+/* TnsFilter:                                        */
+/*   Filter the given spec with specified length     */
+/*   using the coefficients specified in filter.     */
+/*   Not that the order and direction are specified  */
+/*   withing the TNS_FILTER_DATA structure.          */
+/*****************************************************/
+void TnsFilter(int length,double* spec,TNS_FILTER_DATA* filter) {
+	int i,j,k=0;
+	int order=filter->order;
+	double* a=filter->aCoeffs;
+
+	/* Determine loop parameters for given direction */
+	if (filter->direction) {
+
+		/* Startup, initial state is zero */
+		for (i=length-2;i>(length-1-order);i--) {
+			k++;
+			for (j=1;j<=k;j++) {
+				spec[i]-=spec[i+j]*a[j];
+			}
+		}
+		
+		/* Now filter completely inplace */
+		for	(i=length-1-order;i>=0;i--) {
+			for (j=1;j<=order;j++) {
+				spec[i]-=spec[i+j]*a[j];
+			}
+		}
+
+
+	} else {
+
+		/* Startup, initial state is zero */
+		for (i=1;i<order;i++) {
+			for (j=1;j<=i;j++) {
+				spec[i]-=spec[i-j]*a[j];
+			}
+		}
+		
+		/* Now filter completely inplace */
+		for	(i=order;i<length;i++) {
+			for (j=1;j<=order;j++) {
+				spec[i]-=spec[i-j]*a[j];
+			}
+		}
+	}
+}
+
+
+/********************************************************/
+/* TnsInvFilter:                                        */
+/*   Inverse filter the given spec with specified       */
+/*   length using the coefficients specified in filter. */
+/*   Not that the order and direction are specified     */
+/*   withing the TNS_FILTER_DATA structure.             */
+/********************************************************/
+int TnsInvFilter(int length,double* spec,TNS_FILTER_DATA* filter) {
+	int i,j,k=0;
+	int order=filter->order;
+	double* a=filter->aCoeffs;
+	double* temp;
+
+    temp = (double *) malloc( length * sizeof (double));
+    if (!temp) {
+		return FERROR;
+//      CommonExit( 1, "TnsInvFilter: Could not allocate memory for TNS array\nExiting program...\n");
+    }
+
+	/* Determine loop parameters for given direction */
+	if (filter->direction) {
+
+		/* Startup, initial state is zero */
+		temp[length-1]=spec[length-1];
+		for (i=length-2;i>(length-1-order);i--) {
+			temp[i]=spec[i];
+			k++;
+			for (j=1;j<=k;j++) {
+				spec[i]+=temp[i+j]*a[j];
+			}
+		}
+		
+		/* Now filter the rest */
+		for	(i=length-1-order;i>=0;i--) {
+			temp[i]=spec[i];
+			for (j=1;j<=order;j++) {
+				spec[i]+=temp[i+j]*a[j];
+			}
+		}
+
+
+	} else {
+
+		/* Startup, initial state is zero */
+		temp[0]=spec[0];
+		for (i=1;i<order;i++) {
+			temp[i]=spec[i];
+			for (j=1;j<=i;j++) {
+				spec[i]+=temp[i-j]*a[j];
+			}
+		}
+		
+		/* Now filter the rest */
+		for	(i=order;i<length;i++) {
+			temp[i]=spec[i];
+			for (j=1;j<=order;j++) {
+				spec[i]+=temp[i-j]*a[j];
+			}
+		}
+	}
+	free(temp);
+	return FNO_ERROR;
+}
+
+
+
+
+
+/*****************************************************/
+/* TruncateCoeffs:                                   */
+/*   Truncate the given reflection coeffs by zeroing */
+/*   coefficients in the tail with absolute value    */
+/*   less than the specified threshold.  Return the  */
+/*   truncated filter order.                         */
+/*****************************************************/
+int TruncateCoeffs(int fOrder,double threshold,double* kArray) {
+	int i;
+
+	for (i=fOrder;i>=0;i--) {
+		kArray[i] = (fabs(kArray[i])>threshold) ? kArray[i] : 0.0;
+		if (kArray[i]!=0.0) return i;
+	}
+}
+
+/*****************************************************/
+/* QuantizeReflectionCoeffs:                         */
+/*   Quantize the given array of reflection coeffs   */
+/*   to the specified resolution in bits.            */
+/*****************************************************/
+void QuantizeReflectionCoeffs(int fOrder,
+			      int coeffRes,
+			      double* kArray,
+			      int* indexArray) {
+
+	double iqfac,iqfac_m;
+	int i;
+
+	iqfac = ((1<<(coeffRes-1))-0.5)/(PI/2);
+	iqfac_m = ((1<<(coeffRes-1))+0.5)/(PI/2);
+
+	/* Quantize and inverse quantize */
+	for (i=1;i<=fOrder;i++) {
+		indexArray[i] = (int)(0.5+(asin(kArray[i])*((kArray[i]>=0)?iqfac:iqfac_m)));
+		kArray[i] = sin((double)indexArray[i]/((indexArray[i]>=0)?iqfac:iqfac_m));
+	}
+}
+
+/*****************************************************/
+/* Autocorrelation,                                  */
+/*   Compute the autocorrelation function            */
+/*   estimate for the given data.                    */
+/*****************************************************/
+void Autocorrelation(int maxOrder,        /* Maximum autocorr order */
+		     int dataSize,		  /* Size of the data array */
+		     double* data,		  /* Data array */
+		     double* rArray) {	  /* Autocorrelation array */
+
+  int order,index;
+
+  for (order=0;order<=maxOrder;order++) {
+    rArray[order]=0.0;
+    for (index=0;index<dataSize;index++) {
+      rArray[order]+=data[index]*data[index+order];
+    }
+    dataSize--;
+  }
+}
+
+
+
+/*****************************************************/
+/* LevinsonDurbin:                                   */
+/*   Compute the reflection coefficients for the     */
+/*   given data using LevinsonDurbin recursion.      */
+/*   Return the prediction gain.                     */
+/*****************************************************/
+double LevinsonDurbin(int fOrder,          /* Filter order */
+					  int dataSize,		   /* Size of the data array */
+					  double* data,		   /* Data array */
+					  double* kArray) 	   /* Reflection coeff array */
+{
+	int order,i;
+	double signal;
+	double error, kTemp;				/* Prediction error */
+	double aArray1[TNS_MAX_ORDER+1];	/* Predictor coeff array */
+	double aArray2[TNS_MAX_ORDER+1];	/* Predictor coeff array 2 */
+	double rArray[TNS_MAX_ORDER+1];		/* Autocorrelation coeffs */
+	double* aPtr = aArray1;				/* Ptr to aArray1 */
+	double* aLastPtr = aArray2;			/* Ptr to aArray2 */
+	double* aTemp;
+
+	/* Compute autocorrelation coefficients */
+	Autocorrelation(fOrder,dataSize,data,rArray);
+	signal=rArray[0];	/* signal energy */
+
+	/* Set up pointers to current and last iteration */ 
+	/* predictor coefficients.						 */
+	aPtr = aArray1;
+	aLastPtr = aArray2;
+	/* If there is no signal energy, return */
+	if (!signal) {
+		kArray[0]=1.0;
+		for (order=1;order<=fOrder;order++) {
+			kArray[order]=0.0;
+		}
+		return 0;
+	} else {
+
+		/* Set up first iteration */
+		kArray[0]=1.0;
+		aPtr[0]=1.0;		/* Ptr to predictor coeffs, current iteration*/
+		aLastPtr[0]=1.0;	/* Ptr to predictor coeffs, last iteration */
+		error=rArray[0];
+
+		/* Now perform recursion */
+		for (order=1;order<=fOrder;order++) {
+			kTemp = aLastPtr[0]*rArray[order-0];
+			for (i=1;i<order;i++) {
+				kTemp += aLastPtr[i]*rArray[order-i];
+			}
+			kTemp = -kTemp/error;
+			kArray[order]=kTemp;
+			aPtr[order]=kTemp;
+			for (i=1;i<order;i++) {
+				aPtr[i] = aLastPtr[i] + kTemp*aLastPtr[order-i];
+			}
+			error = error * (1 - kTemp*kTemp);
+
+			/* Now make current iteration the last one */
+			aTemp=aLastPtr;
+			aLastPtr=aPtr;		/* Current becomes last */
+			aPtr=aTemp;			/* Last becomes current */
+		}
+		return signal/error;	/* return the gain */
+	}
+}
+
+
+/*****************************************************/
+/* StepUp:                                           */
+/*   Convert reflection coefficients into            */
+/*   predictor coefficients.                         */
+/*****************************************************/
+void StepUp(int fOrder,double* kArray,double* aArray) {
+
+	double aTemp[TNS_MAX_ORDER+2];
+	int i,order;
+
+	aArray[0]=1.0;
+	aTemp[0]=1.0;
+	for (order=1;order<=fOrder;order++) {
+		aArray[order]=0.0;
+		for (i=1;i<=order;i++) {
+			aTemp[i] = aArray[i] + kArray[order]*aArray[order-i];
+		}
+		for (i=1;i<=order;i++) {
+			aArray[i]=aTemp[i];
+		}
+	}
+}
+
--- /dev/null
+++ b/tns.h
@@ -1,0 +1,120 @@
+/**********************************************************************
+ 
+This software module was originally developed by
+and edited by Texas Instruments 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) 1997.
+**********************************************************************/
+/*********************************************************************
+ *
+ * tns.h  -  AAC temporal noise shaping
+ *
+ * Authors:
+ * CL    Chuck Lueck, TI <lueck@ti.com>
+ *
+ * Changes:
+ * 20-oct-97   CL   Initial revision.
+ *
+**********************************************************************/
+ 
+#ifndef _TNS_H_INCLUDED
+#define _TNS_H_INCLUDED
+ 
+#include <math.h>
+#include <stdio.h>
+#include "tf_main.h"
+#include "interface.h"
+
+/*************************/
+/* #defines              */
+/*************************/
+#define TNS_MAX_ORDER 20				   
+#define DEF_TNS_GAIN_THRESH 1.4 //new2
+#define DEF_TNS_COEFF_THRESH 0.1
+#define DEF_TNS_COEFF_RES 4
+#define DEF_TNS_RES_OFFSET 3
+#define PI C_PI
+#ifndef min
+#define min(a,b) ( (a) < (b) ? (a) : (b) )
+#endif
+#ifndef max
+#define max(a,b) ( (a) > (b) ? (a) : (b) )
+#endif
+
+/**************************/
+/* Structure definitions  */
+/**************************/
+typedef struct {
+  int order;                           /* Filter order */
+  int direction;		       /* Filtering direction */
+  int coefCompress;		       /* Are coeffs compressed? */
+  int length;                          /* Length, in bands */                     
+  double aCoeffs[TNS_MAX_ORDER+1];     /* AR Coefficients */
+  double kCoeffs[TNS_MAX_ORDER+1];     /* Reflection Coefficients */
+  int index[TNS_MAX_ORDER+1];	       /* Coefficient indices */
+} TNS_FILTER_DATA;
+
+
+typedef struct {
+  int numFilters;				/* Number of filters */
+  int coefResolution;				/* Coefficient resolution */
+  TNS_FILTER_DATA tnsFilter[1<<LEN_TNS_NFILTL];	/* TNS filters */
+} TNS_WINDOW_DATA;
+
+
+typedef struct {
+  int tnsDataPresent;
+  int tnsMinBandNumberLong;
+  int tnsMinBandNumberShort;
+  int tnsMaxBandsLong;
+  int tnsMaxBandsShort;
+  int tnsMaxOrderLong;
+  int tnsMaxOrderShort;
+  TNS_WINDOW_DATA windowData[NSHORT];	/* TNS data per window */
+} TNS_INFO;
+
+
+/*************************/
+/* Function prototypes   */
+/*************************/
+void Autocorrelation(int maxOrder,        /* Maximum autocorr order */
+		     int dataSize,		  /* Size of the data array */
+		     double* data,		  /* Data array */
+		     double* rArray);	  /* Autocorrelation array */
+
+double LevinsonDurbin(int maxOrder,       /* Maximum filter order */
+		      int dataSize,		   /* Size of the data array */
+		      double* data,		   /* Data array */
+		      double* kArray);	   /* Reflection coeff array */
+
+void StepUp(int fOrder,
+	    double* kArray,
+	    double* aArray);
+
+void QuantizeReflectionCoeffs(int fOrder,int coeffRes,double* rArray,int* indexArray);
+int TruncateCoeffs(int fOrder,double threshold,double* kArray);
+void TnsFilter(int length,double* spec,TNS_FILTER_DATA* filter);
+int TnsInvFilter(int length,double* spec,TNS_FILTER_DATA* filter);
+void TnsInit(long samplingRate,enum AAC_PROFILE profile,TNS_INFO* tnsInfo); 
+int TnsEncode(int numberOfBands,int maxSfb,enum WINDOW_TYPE blockType,int* sfbOffsetTable,double* spec,TNS_INFO* tnsInfo);
+
+#endif
+
--- /dev/null
+++ b/transfo.c
@@ -1,0 +1,284 @@
+
+#define d2PI  6.283185307179586
+
+#define SWAP(a,b) tempr=a;a=b;b=tempr   
+
+#include "all.h"
+#include "transfo.h"
+#include "util.h"
+#include <math.h>
+#include <stdlib.h>
+#ifndef PI
+#define PI 3.141592653589795
+#endif
+
+
+/*****************************
+  Fast MDCT Code
+*****************************/
+
+void MDCT (double *data, int N) {
+
+    static Float *FFTarray = 0;    /* the array for in-place FFT */
+	static int init = 1;
+    Float tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
+    Float freq = 2. * PI / N;
+    Float fac;
+    int i, n;
+	int isign = 1;
+	int b = N >> 1;
+    int a = N - b;
+
+    /* Choosing to allocate 2/N factor to Inverse Xform! */
+    fac = 2.; /* 2 from MDCT inverse  to forward */
+
+	if (init) {
+		init = 0;
+		FFTarray = NewFloat (1024);
+	}
+
+    /* prepare for recurrence relation in pre-twiddle */
+    cfreq = cos (freq);
+    sfreq = sin (freq);
+    c = cos (freq * 0.125);
+    s = sin (freq * 0.125);
+
+    for (i = 0; i < N / 4; i++) {
+		/* calculate real and imaginary parts of g(n) or G(p) */
+		
+		n = N / 2 - 1 - 2 * i;
+		if (i < b / 4) {
+			tempr = data [a / 2 + n] + data [N + a / 2 - 1 - n]; /* use second form of e(n) for n = N / 2 - 1 - 2i */
+		} else {
+			tempr = data [a / 2 + n] - data [a / 2 - 1 - n]; /* use first form of e(n) for n = N / 2 - 1 - 2i */
+		}
+		n = 2 * i;
+		if (i < a / 4) {
+			tempi = data [a / 2 + n] - data [a / 2 - 1 - n]; /* use first form of e(n) for n=2i */
+		} else {
+			tempi = data [a / 2 + n] + data [N + a / 2 - 1 - n]; /* use second form of e(n) for n=2i*/
+		}
+
+		/* calculate pre-twiddled FFT input */
+		FFTarray [2 * i] = tempr * c + tempi * s;
+		FFTarray [2 * i + 1] = tempi * c - tempr * s;
+		
+		/* use recurrence to prepare cosine and sine for next value of i */
+		cold = c;
+		c = c * cfreq - s * sfreq;
+		s = s * cfreq + cold * sfreq;
+    }
+    
+    /* Perform in-place complex FFT of length N/4 */
+    CompFFT (FFTarray, N / 4, -1);
+
+    /* prepare for recurrence relations in post-twiddle */
+    c = cos (freq * 0.125);
+    s = sin (freq * 0.125);
+    
+    /* post-twiddle FFT output and then get output data */
+    for (i = 0; i < N / 4; i++) {
+		
+		/* get post-twiddled FFT output  */
+		/* Note: fac allocates 4/N factor from IFFT to forward and inverse */
+		tempr = fac * (FFTarray [2 * i] * c + FFTarray [2 * i + 1] * s);
+		tempi = fac * (FFTarray [2 * i + 1] * c - FFTarray [2 * i] * s);
+		
+		/* fill in output values */
+		data [2 * i] = -tempr;   /* first half even */
+		data [N / 2 - 1 - 2 * i] = tempi;  /* first half odd */
+		data [N / 2 + 2 * i] = -tempi;  /* second half even */
+		data [N - 1 - 2 * i] = tempr;  /* second half odd */
+		
+		/* use recurrence to prepare cosine and sine for next value of i */
+		cold = c;
+		c = c * cfreq - s * sfreq;
+		s = s * cfreq + cold * sfreq;
+    }
+}
+
+
+void CompFFT (Float *data, int nn, int isign) {
+
+    static int i, j, k, kk;
+    static int p1, q1;
+    static int m, n, logq1;
+    static Float **intermed = 0;
+    static Float ar, ai;
+    static Float d2pn;
+    static Float ca, sa, curcos, cursin, oldcos, oldsin;
+    static Float ca1, sa1, curcos1, cursin1, oldcos1, oldsin1;
+
+
+/* Factorize n;  n = p1*q1 where q1 is a power of 2.
+    For n = 1152, p1 = 9, q1 = 128.		*/
+
+    n = nn;
+    logq1 = 0;
+
+    for (;;) {
+		m = n >> 1;  /* shift right by one*/
+		if ((m << 1) == n) {
+		    logq1++;
+		    n = m;
+			} 
+		else {
+			break;
+			}
+		}
+
+    p1 = n;
+    q1 = 1;
+    q1 <<= logq1;
+
+    d2pn = d2PI / nn;
+
+{static int oldp1 = 0, oldq1 = 0;
+
+	if ((oldp1 < p1) || (oldq1 < q1)) {
+		if (intermed) {
+			free (intermed);
+			intermed = 0;
+			}
+		if (oldp1 < p1) oldp1 = p1;
+		if (oldq1 < q1) oldq1 = q1;;
+		}
+		
+	if (!intermed)
+		intermed = NewFloatMatrix (oldp1, 2 * oldq1);
+}
+
+/* Sort the p1 sequences */
+
+    for	(i = 0; i < p1; i++) {
+		for (j = 0; j < q1; j++){
+		    intermed [i] [2 * j] = data [2 * (p1 * j + i)];
+			intermed [i] [2 * j + 1] = data [2 * (p1 * j + i) + 1];
+			}
+		}
+
+/* compute the power of two fft of the p1 sequences of length q1 */
+
+    for (i = 0; i < p1; i++) {
+/* Forward FFT in place for n complex items */
+		FFT (intermed [i], q1, isign);
+		}
+
+/* combine the FFT results into one seqquence of length N */
+
+    ca1 = cos (d2pn);
+    sa1 = sin (d2pn);
+    curcos1 = 1.;
+    cursin1 = 0.;
+
+    for (k = 0; k < nn; k++) {
+		data [2 * k] = 0.;
+		data [2 * k + 1] = 0.;
+		kk = k % q1;
+
+		ca = curcos1;
+		sa = cursin1;
+		curcos = 1.;
+		cursin = 0.;
+
+		for (j = 0; j < p1; j++) {
+			ar = curcos;
+			ai = isign * cursin;
+			data [2 * k] += intermed [j] [2 * kk] * ar - intermed [j] [2 * kk + 1] * ai;
+			data [2 * k + 1] += intermed [j] [2 * kk] * ai + intermed [j] [2 * kk + 1] * ar;
+
+		    oldcos = curcos;
+		    oldsin = cursin;
+			curcos = oldcos * ca - oldsin * sa;
+			cursin = oldcos * sa + oldsin * ca;
+			}
+		oldcos1 = curcos1;
+		oldsin1 = cursin1;
+		curcos1 = oldcos1 * ca1 - oldsin1 * sa1;
+		cursin1 = oldcos1 * sa1 + oldsin1 * ca1;
+		}
+
+}
+
+
+void FFT (Float *data, int nn, int isign)  {
+/* Varient of Numerical Recipes code from off the internet.  It takes nn
+interleaved complex input data samples in the array data and returns nn interleaved
+complex data samples in place where the output is the FFT of input if isign==1 and it
+is nn times the IFFT of the input if isign==-1. 
+(Note: it doesn't renormalize by 1/N when doing the inverse transform!!!)
+(Note: this follows physicists convention of +i, not EE of -j in forward
+transform!!!!)
+ */
+
+/* Press, Flannery, Teukolsky, Vettering "Numerical
+ * Recipes in C" tuned up ; Code works only when nn is
+ * a power of 2  */
+
+    static int n, mmax, m, j, i;
+    static Float wtemp, wr, wpr, wpi, wi, theta, wpin;
+    static Float tempr, tempi, datar, datai;
+    static Float data1r, data1i;
+
+    n = nn * 2;
+
+/* bit reversal */
+
+    j = 0;
+    for (i = 0; i < n; i += 2) {
+		if (j > i) {  /* could use j>i+1 to help compiler analysis */
+			SWAP (data [j], data [i]);
+			SWAP (data [j + 1], data [i + 1]);
+			}
+		m = nn;
+		while (m >= 2 && j >= m) {
+			j -= m;
+			m >>= 1;
+			}
+		j += m;
+		}
+
+    theta = 3.141592653589795 * .5;
+    if (isign < 0)
+		theta = -theta;
+    wpin = 0;   /* sin(+-PI) */
+    for (mmax = 2; n > mmax; mmax *= 2) {
+		wpi = wpin;
+		wpin = sin (theta);
+		wpr = 1 - wpin * wpin - wpin * wpin; /* cos(theta*2) */
+		theta *= .5;
+		wr = 1;
+		wi = 0;
+		for (m = 0; m < mmax; m += 2) {
+			j = m + mmax;
+			tempr = (Float) wr * (data1r = data [j]);
+			tempi = (Float) wi * (data1i = data [j + 1]);
+			for (i = m; i < n - mmax * 2; i += mmax * 2) {
+/* mixed precision not significantly more
+ * accurate here; if removing float casts,
+ * tempr and tempi should be double */
+				tempr -= tempi;
+				tempi = (Float) wr *data1i + (Float) wi *data1r;
+/* don't expect compiler to analyze j > i + 1 */
+				data1r = data [j + mmax * 2];
+				data1i = data [j + mmax * 2 + 1];
+				data [i] = (datar = data [i]) + tempr;
+				data [i + 1] = (datai = data [i + 1]) + tempi;
+				data [j] = datar - tempr;
+				data [j + 1] = datai - tempi;
+				tempr = (Float) wr *data1r;
+				tempi = (Float) wi *data1i;
+				j += mmax * 2;
+				}
+			tempr -= tempi;
+			tempi = (Float) wr * data1i + (Float) wi *data1r;
+			data [i] = (datar = data [i]) + tempr;
+			data [i + 1] = (datai = data [i + 1]) + tempi;
+			data [j] = datar - tempr;
+			data [j + 1] = datai - tempi;
+			wr = (wtemp = wr) * wpr - wi * wpi;
+			wi = wtemp * wpi + wi * wpr;
+			}
+		}
+}
+
--- /dev/null
+++ b/transfo.h
@@ -1,0 +1,40 @@
+/************************* 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.
+ *                                                                           *
+ ****************************************************************************/
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H 
+
+typedef	float	Float;
+#define TRANS_DATATYPE	Float /* :-) beginner like! */
+
+void Transform(TRANS_DATATYPE* data, int n, int param);
+void ITransform(TRANS_DATATYPE* date, int n, int param);
+
+void CompFFT(TRANS_DATATYPE *data, int nn, int isign);
+void FFT(TRANS_DATATYPE *data, int nn, int isign);
+
+void MDCT(double* data, int N);
+
+#endif
+
--- /dev/null
+++ b/util.c
@@ -1,0 +1,45 @@
+
+#include "all.h"
+#include "util.h"
+#include <stdlib.h>
+
+
+#ifndef MAXINT
+#undef MAXINT
+#define MAXINT	32767.
+#endif
+
+Float *NewFloat (int N) {
+/* Allocate array of N Floats */
+
+    Float *temp;
+
+    temp = (Float *) malloc( N * sizeof (Float));
+    return temp;
+}
+
+typedef Float *pFloat;
+
+Float **NewFloatMatrix (int N, int M) {
+/* Allocate NxM matrix of Floats */
+
+    Float **temp;
+    int i;
+
+/* allocate N pointers to Float arrays */
+    temp = (pFloat *) malloc( N * sizeof (pFloat));
+    if (!temp) {
+		return temp;
+		}
+
+/* Allocate a Float array M long for each of the N array pointers */
+
+    for (i = 0; i < N; i++) {
+		temp [i] = (Float *) malloc( M * sizeof (Float));
+		if (! temp [i]) {
+			return temp;
+			}
+		}
+    return temp;
+}
+
--- /dev/null
+++ b/util.h
@@ -1,0 +1,36 @@
+/************************* 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.
+ *                                                                           *
+ ****************************************************************************/
+
+/* Util.h -- header file for general utility functions */
+
+#ifndef UTIL
+#define UTIL 1
+
+Float	*NewFloat (int N);
+Float **NewFloatMatrix (int N, int M);	
+void DeleteFloatMatrix (Float **temp, int N);
+void DeleteFloat(Float *temp);
+
+#endif
+