codec.c
上传用户:bjsgzm
上传日期:2007-01-08
资源大小:256k
文件大小:8k
- /*
- (c) Copyright 1998, 1999 - Tord Jansson
- =======================================
- This file is part of the BladeEnc MP3 Encoder, based on
- ISO's reference code for MPEG Layer 3 compression, and might
- contain smaller or larger sections that are directly taken
- from ISO's reference code.
- All changes to the ISO reference code herein are either
- copyrighted by Tord Jansson (tord.jansson@swipnet.se)
- or sublicensed to Tord Jansson by a third party.
- BladeEnc is free software; you can redistribute this file
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- */
- #include <stdlib.h>
- #include "common.h"
- #include "encoder.h"
- #include "l3psy.h"
- #include "mdct.h"
- #include "loop.h"
- #include "l3bitstream.h"
- #include "formatbitstream2.h"
- #include "codec.h"
- extern int fInit_mdct_sub;
- extern int fInit_mdct;
- extern int fInit_fft;
- extern int fInit_iteration_loop;
- extern int fInit_huffman_read_flag;
- extern void fixStatic_reservoir();
- /************************************************************************/
- #define SAMPLES_PER_FRAME 1152
- typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT];
- typedef double JSBS[3][SCALE_BLOCK][SBLIMIT];
- static SBS *sb_sample;
- static L3SBS *l3_sb_sample;
- static JSBS *j_sample;
- static layer info;
- static short buffer[2][1152];
- static float snr32[32];
- static short sam[2][1344];
- static int whole_SpF, extra_slot;
- static double frac_SpF, slot_lag;
- static int stereo, error_protection;
- static CodecInitOut sOut;
- frame_params fr_ps;
- char * pEncodedOutput;
- int outputBit;
- /*____ codecInit() ____________________________________________________________*/
- CodecInitOut * codecInit( CodecInitIn * psIn )
- {
- int j;
- volatile double avg_slots_per_frame;
- /* Read psIn */
- switch (psIn->frequency)
- {
- case 48000:
- info.sampling_frequency = 1;
- break;
- case 44100:
- info.sampling_frequency = 0;
- break;
- case 32000:
- info.sampling_frequency = 2;
- break;
- default:
- return FALSE;
- }
- switch( psIn->mode)
- {
- case 0:
- info.mode = MPG_MD_STEREO;
- info.mode_ext = 0;
- break;
- case 2:
- info.mode = MPG_MD_DUAL_CHANNEL;
- info.mode_ext = 0;
- break;
- case 3:
- info.mode = MPG_MD_MONO;
- info.mode_ext = 0;
- break;
- default:
- return FALSE;
- }
- j = 0;
- while ( j < 15 )
- {
- if ( bitratex[1][j] == psIn->bitrate )
- break;
- j++;
- }
- info.bitrate_index = j;
- info.version = 1; /* Default: MPEG-1 */
- info.emphasis = psIn->emphasis;
- info.extension = psIn->fPrivate;
- info.copyright = psIn->fCopyright;
- info.original = psIn->fOriginal;
- info.error_protection = psIn->fCRC;
-
-
- /*_______ Static-fix _______________*/
- fInit_mdct_sub = 0;
- fInit_mdct = 0;
- fInit_fft = 0;
- fInit_iteration_loop = 0;
- fInit_huffman_read_flag = 0;
- fixStatic_loop();
- fixStatic_reservoir();
- /*___________________________________*/
- psycho_anal_init( psIn->frequency );
- initWindowFilterSubband();
- initFormatBitstream();
- /* Most large variables are declared dynamically to ensure
- compatibility with smaller machines */
-
- sb_sample = (SBS *) mem_alloc(sizeof(SBS), "sb_sample");
- l3_sb_sample = (L3SBS *) mem_alloc(sizeof(SBS), "l3_sb_sample");
- j_sample = (JSBS *) mem_alloc(sizeof(JSBS), "j_sample");
- /* clear buffers */
- memset((char *) buffer, 0, sizeof(buffer));
- memset((char *) snr32, 0, sizeof(snr32));
- memset((char *) sam, 0, sizeof(sam));
- fr_ps.header = &info;
- fr_ps.tab_num = -1; /* no table loaded */
- fr_ps.alloc = NULL;
- fr_ps.actual_mode = info.mode;
- fr_ps.stereo = (info.mode == MPG_MD_MONO) ? 1 : 2;
- fr_ps.sblimit = SBLIMIT;
- fr_ps.jsbound = SBLIMIT;
-
- stereo = fr_ps.stereo;
- error_protection = info.error_protection;
- avg_slots_per_frame = ((double)SAMPLES_PER_FRAME /
- s_freq[1][info.sampling_frequency]) *
- ((double)bitratex[1][info.bitrate_index] / 8.0);
- whole_SpF = (int) avg_slots_per_frame;
- frac_SpF = avg_slots_per_frame - (double)whole_SpF;
- slot_lag = -frac_SpF;
-
- if (frac_SpF == 0)
- info.padding = 0;
- genNoisePowTab();
- /*________________________*/
- if( stereo != 2 )
- sOut.nSamples = SAMPLES_PER_FRAME;
- else
- sOut.nSamples = SAMPLES_PER_FRAME*2;
- sOut.bufferSize = 2048;
- return &sOut; /* How many samples we want in each chunk... */
- }
- void rebuffer_audio( short buffer[2][1152], short * insamp, unsigned int samples_read, int stereo );
- /*____ codecEncodeChunk() _____________________________________________________*/
- unsigned int codecEncodeChunk( int nSamples, short * pSamples, char * pDest )
- {
- static double xr[2][2][576];
- static double xr_dec[2][2][576];
- static double pe[2][2];
- static int l3_enc[2][2][576];
- static III_psy_ratio ratio;
- static III_side_info_t l3_side;
- static III_scalefac_t scalefac;
- int gr, ch;
- int mean_bits, sideinfo_len;
- int bitsPerFrame;
- int j;
- /*
- static int fFirst = TRUE;
- if( fFirst == TRUE )
- {
- memset( (char *) &xr, 0, sizeof( xr ) );
- memset( (char *) &xr_dec, 0, sizeof( xr_dec ) );
- memset( (char *) &pe, 0, sizeof( pe ) );
- memset( (char *) &l3_enc, 0, sizeof( l3_enc ) );
- memset( (char *) &ratio, 0, sizeof( ratio ) );
- memset( (char *) &l3_side, 0, sizeof( l3_side ) );
- memset( (char *) &scalefac, 0, sizeof( scalefac ) );
- fFirst = FALSE;
- }
- */
- pEncodedOutput = pDest;
- outputBit = 8;
- pEncodedOutput[0] = 0;
- rebuffer_audio( buffer, pSamples, nSamples, stereo );
- if (frac_SpF != 0)
- {
- if (slot_lag > (frac_SpF-1.0) )
- {
- slot_lag -= frac_SpF;
- extra_slot = 0;
- info.padding = 0;
- }
- else
- {
- extra_slot = 1;
- info.padding = 1;
- slot_lag += (1-frac_SpF);
- }
- }
-
-
- bitsPerFrame = 8 * whole_SpF + (info.padding * 8);
- /* determine the mean bitrate for main data */
- sideinfo_len = 32;
- if ( stereo == 1 )
- sideinfo_len += 136;
- else
- sideinfo_len += 256;
- if ( info.error_protection )
- sideinfo_len += 16;
- mean_bits = (bitsPerFrame - sideinfo_len) / 2;
- /* psychoacoustic model */
- for ( gr = 0; gr < 2; gr++ )
- for ( ch = 0; ch < stereo; ch++ )
- {
- psycho_anal( &buffer[ch][gr*576], &sam[ch][0], ch, 3, snr32, &ratio.l[gr][ch][0],
- &ratio.s[gr][ch][0], &pe[gr][ch], &l3_side.gr[gr].ch[ch].tt );
- }
- /* polyphase filtering */
- for( gr = 0; gr < 2; gr++ )
- for ( ch = 0; ch < stereo; ch++ )
- for ( j = 0; j < 18; j++ )
- windowFilterSubband( &buffer[ch][gr*18*32+32*j], ch, &(*l3_sb_sample)[ch][gr+1][j][0] );
- /* apply mdct to the polyphase outputs */
- mdct_sub( l3_sb_sample, xr, stereo, &l3_side, 2 );
- /* bit and noise allocation */
- iteration_loop( pe, xr, &ratio, &l3_side, l3_enc, mean_bits,
- stereo, xr_dec, &scalefac, &fr_ps, 0, bitsPerFrame );
- /* write the frame to the bitstream */
- III_format_bitstream( bitsPerFrame, &fr_ps, l3_enc, &l3_side, &scalefac,
- xr, NULL, 0 );
-
- return pEncodedOutput - pDest;
- }
- /*____ codecExit() ____________________________________________________________*/
- unsigned int codecExit( char * pDest )
- {
- pEncodedOutput = pDest;
- outputBit = 8;
- pEncodedOutput[0] = 0;
- free( sb_sample );
- free( l3_sb_sample );
- free( j_sample );
- psycho_anal_exit();
- exitFormatBitstream();
- III_FlushBitstream();
- return pEncodedOutput - pDest;
- }