First, see the file STYLEGUIDE

************************************************************************
TESTING
=======
If you make changes, please test.  There is a python
script in the test/ directory which will compare two versions
of lame using a bunch of CBR and ABR options. To run this
script, copy your favorite (and short!) wav file to the
lame/test directory, and run:

% cd lame/test
% ./lametest.py [-w]  CBRABR.op castanets.wav lame_orig lame_new






************************************************************************
LAME API

For a general outline of the code, see the file API.  
Also, frontend/main.c is a simple front end to libmp3lame.a

The guts of the code are called from lame_encode_buffer().

lame_encode_buffer() handles buffering and resampling, and
then calls lame_encode_frame() for each frame.  lame_encode_frame()
looks like this:

lame_encode_frame_mp3():
   l3psycho_anal()        compute masking thresholds
   mdct_sub()             compute MDCT coefficients
   iteration_loop()       choose scalefactors (via iteration)
                          which determine noise shapping, and 
                          choose best huffman tables for lossless compression

   format_bitstream       format the bitstream.  when data+headers are complete,
                          output to internal bit buffer.
   copy_buffer()          copy internal bit buffer into user's mp3 buffer

************************************************************************
ADDING NEW OPTIONS

control variable goes in lame_global_flags sturct.
Assume the variable is called 'new_variable'.

You also need to write (in get_set.c):

lame_set_new_variable()
lame_get_new_variable()

And then document the variable in the file USAGE as well as the
output of "lame --longhelp"

And add a "--option" style command line option to enable this variable
in parse.m

Note: for experimental features that you need to call from the frontend
but that should not be part of the official API, see the section at
the end of get_set.c.  These functions should *NOT* be prototyped in
lame.h (since that would indicate to the world that they are part
of the API). 


************************************************************************

THREADSAFE:

Lame should now be thread safe and re-entrant. 
The only problem seems to be some OS's allocate small
stacks (< 128K) to threads launched by applictions, and this
is not enough for LAME.  Fix is to increase the stack space,
or move some of our automatic variables onto the heap with
by using bug-prove malloc()'s and free().



************************************************************************
Global Variables:

There are two types of global variables.  All data in
both strucs is initialized to zero.

1. lame_global_flags *gfp

These are input paramters which are set by the calling program,
and some information which the calling program may be interested in.

This struct instantiated by the call to lame_init().  


2. lame_internal_flags *gfc

Most global variables go here.

All internal data not set by the user.  All 'static' data from
old non-reentrant code should be moved here.

Defined in util.h.  Data for which the size is known
in advace should be explicitly declaired (for example,
float xr[576]);  Data which needs to be malloc'd is
handled by:  

1.  in lame_init_params(), malloc the data
2.  be sure to free the data in freegfc()


If the data to be malloc'd is large and only used in
certain conditions (like resampling), use the following:  
this has the disadvantage that it is hard to catch and return error
flags all the way back up the call stack.

1. Add an initialization variable to the gfc struct: lame_init_resample
2. In the resample routine, there should be some code like this:

   if (0==gfc->lame_init_resample) {
       gfc->lame_init_resample=1;
      /* initialization code: malloc() data, etc */
   }

3. The data should be free'd in the routine freegfc().






















 


