| 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 set_get.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.c |
| |
| 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 set_get.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(). |
| |