www.pudn.com > bladeenc-0.90.0-src.zip > codec.c
/* (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#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; }