Blame HACKING

Packit 47f805
First, see the file STYLEGUIDE
Packit 47f805
Packit 47f805
************************************************************************
Packit 47f805
TESTING
Packit 47f805
=======
Packit 47f805
Packit 47f805
If you make changes, please test.  There is a python script in the test/ 
Packit 47f805
directory which will compare two versions of lame using a bunch of CBR 
Packit 47f805
and ABR options. To run this script, copy your favorite (and short!) wav 
Packit 47f805
file to the lame/test directory, and run:
Packit 47f805
Packit 47f805
% cd lame/test
Packit 47f805
% ./lametest.py [-w]  CBRABR.op castanets.wav lame_orig lame_new
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
************************************************************************
Packit 47f805
LAME API
Packit 47f805
========
Packit 47f805
Packit 47f805
For a general outline of the code, see the file API.  
Packit 47f805
Also, frontend/main.c is a simple front end to libmp3lame.a
Packit 47f805
Packit 47f805
The guts of the code are called from lame_encode_buffer().
Packit 47f805
Packit 47f805
lame_encode_buffer() handles buffering and resampling, and
Packit 47f805
then calls lame_encode_frame() for each frame.  lame_encode_frame()
Packit 47f805
looks like this:
Packit 47f805
Packit 47f805
lame_encode_frame_mp3():
Packit 47f805
   l3psycho_anal()        compute masking thresholds
Packit 47f805
   mdct_sub()             compute MDCT coefficients
Packit 47f805
   iteration_loop()       choose scalefactors (via iteration)
Packit 47f805
                          which determine noise shapping, and 
Packit 47f805
                          choose best huffman tables for lossless compression
Packit 47f805
   format_bitstream       format the bitstream.  when data+headers are complete,
Packit 47f805
                          output to internal bit buffer.
Packit 47f805
   copy_buffer()          copy internal bit buffer into user's mp3 buffer
Packit 47f805
Packit 47f805
************************************************************************
Packit 47f805
ADDING NEW OPTIONS
Packit 47f805
==================
Packit 47f805
Packit 47f805
control variable goes in lame_global_flags struct.
Packit 47f805
Assume the variable is called 'new_variable'.
Packit 47f805
Packit 47f805
You also need to write (in set_get.c):
Packit 47f805
Packit 47f805
lame_set_new_variable()
Packit 47f805
lame_get_new_variable()
Packit 47f805
Packit 47f805
And then document the variable in the file USAGE as well as the
Packit 47f805
output of "lame --longhelp"
Packit 47f805
Packit 47f805
And add a "--option" style command line option to enable this variable
Packit 47f805
in parse.c
Packit 47f805
Packit 47f805
Note: for experimental features that you need to call from the frontend
Packit 47f805
but that should not be part of the official API, see the section at
Packit 47f805
the end of set_get.c.  These functions should *NOT* be prototyped in
Packit 47f805
lame.h (since that would indicate to the world that they are part
Packit 47f805
of the API). 
Packit 47f805
Packit 47f805
Packit 47f805
************************************************************************
Packit 47f805
THREADSAFE:
Packit 47f805
===========
Packit 47f805
Packit 47f805
Lame should now be thread safe and re-entrant. The only problem seems to 
Packit 47f805
be some OS's allocate small stacks (< 128K) to threads launched by 
Packit 47f805
applications, and this is not enough for LAME.  Fix is to increase the 
Packit 47f805
stack space, or move some of our automatic variables onto the heap with
Packit 47f805
by using bug-proof malloc()'s and free().
Packit 47f805
Packit 47f805
Packit 47f805
************************************************************************
Packit 47f805
Global Variables:
Packit 47f805
=================
Packit 47f805
Packit 47f805
There are two types of global variables.  All data in both structs is 
Packit 47f805
initialized to zero.
Packit 47f805
Packit 47f805
1. lame_global_flags *gfp
Packit 47f805
Packit 47f805
These are input parameters which are set by the calling program, and some 
Packit 47f805
information which the calling program may be interested in.
Packit 47f805
Packit 47f805
This struct instantiated by the call to lame_init().  
Packit 47f805
Packit 47f805
Packit 47f805
2. lame_internal_flags *gfc
Packit 47f805
Packit 47f805
Most global variables go here.
Packit 47f805
Packit 47f805
All internal data not set by the user.  All 'static' data from
Packit 47f805
old non-reentrant code should be moved here.
Packit 47f805
Packit 47f805
Defined in util.h.  Data for which the size is known
Packit 47f805
in advance should be explicitly declaired (for example,
Packit 47f805
float xr[576]);  Data which needs to be malloc'd is
Packit 47f805
handled by:  
Packit 47f805
Packit 47f805
1.  in lame_init_params(), malloc the data
Packit 47f805
2.  be sure to free the data in freegfc()
Packit 47f805
Packit 47f805
Packit 47f805
If the data to be malloc'd is large and only used in
Packit 47f805
certain conditions (like resampling), use the following:  
Packit 47f805
this has the disadvantage that it is hard to catch and return error
Packit 47f805
flags all the way back up the call stack.
Packit 47f805
Packit 47f805
1. Add an initialization variable to the gfc struct: lame_init_resample
Packit 47f805
2. In the resample routine, there should be some code like this:
Packit 47f805
Packit 47f805
   if (0==gfc->lame_init_resample) {
Packit 47f805
       gfc->lame_init_resample=1;
Packit 47f805
      /* initialization code: malloc() data, etc */
Packit 47f805
   }
Packit 47f805
Packit 47f805
3. The data should be free'd in the routine freegfc().
Packit 47f805