www.pudn.com > avi 到 mpeg 的转换程序及源代码.zip > AVI2MP2.C


/* avi2mp2.c - originally musicin.c */ 
 
/********************************************************************** 
Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved 
musicin.c 
**********************************************************************/ 
/********************************************************************** 
 * MPEG/audio coding/decoding software, work in progress              * 
 *   NOT for public distribution until verified and approved by the   * 
 *   MPEG/audio committee.  For further information, please contact   * 
 *   Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com             * 
 *                                                                    * 
 * VERSION 4.0                                                        * 
 *   changes made since last update:                                  * 
 *   date   programmers         comment                               * 
 * 3/01/91  Douglas Wong,       start of version 1.1 records          * 
 *          Davis Pan                                                 * 
 * 3/06/91  Douglas Wong,       rename: setup.h to endef.h            * 
 *                              removed extraneous variables          * 
 * 3/21/91  J.Georges Fritsch   introduction of the bit-stream        * 
 *                              package. This package allows you      * 
 *                              to generate the bit-stream in a       * 
 *                              binary or ascii format                * 
 * 3/31/91  Bill Aspromonte     replaced the read of the SB matrix    * 
 *                              by an "code generated" one            * 
 * 5/10/91  W. Joseph Carter    Ported to Macintosh and Unix.         * 
 *                              Incorporated Jean-Georges Fritsch's   * 
 *                              "bitstream.c" package.                * 
 *                              Modified to strictly adhere to        * 
 *                              encoded bitstream specs, including    * 
 *                              "Berlin changes".                     * 
 *                              Modified user interface dialog & code * 
 *                              to accept any input & output          * 
 *                              filenames desired.  Also added        * 
 *                              de-emphasis prompt and final bail-out * 
 *                              opportunity before encoding.          * 
 *                              Added AIFF PCM sound file reading     * 
 *                              capability.                           * 
 *                              Modified PCM sound file handling to   * 
 *                              process all incoming samples and fill * 
 *                              out last encoded frame with zeros     * 
 *                              (silence) if needed.                  * 
 *                              Located and fixed numerous software   * 
 *                              bugs and table data errors.           * 
 * 27jun91  dpwe (Aware Inc)    Used new frame_params struct.         * 
 *                              Clear all automatic arrays.           * 
 *                              Changed some variable names,          * 
 *                              simplified some code.                 * 
 *                              Track number of bits actually sent.   * 
 *                              Fixed padding slot, stereo bitrate    * 
 *                              Added joint-stereo : scales L+R.      * 
 * 6/12/91  Earle Jennings      added fix for MS_DOS in obtain_param  * 
 * 6/13/91  Earle Jennings      added stack length adjustment before  * 
 *                              main for MS_DOS                       * 
 * 7/10/91  Earle Jennings      conversion of all float to FLOAT      * 
 *                              port to MsDos from MacIntosh completed* 
 * 8/ 8/91  Jens Spille         Change for MS-C6.00                   * 
 * 8/22/91  Jens Spille         new obtain_parameters()               * 
 *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           * 
 *          Don H. Lee,                                               * 
 *          Peter W. Farrett                                          * 
 *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   * 
 *                              newly introduced functions are        * 
 *                              I_CRC_calc, II_CRC_calc and encode_CRC* 
 *                              Additions and revisions are marked    * 
 *                              with "dhl" for clarity                * 
 *11/11/91 Katherine Wang       Documentation of code.                * 
 *                                (variables in documentation are     * 
 *                                surround by the # symbol, and an '*'* 
 *                                denotes layer I or II versions)     * 
 * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   * 
 *                              important fixes involved changing     * 
 *                              16-bit ints to long or unsigned in    * 
 *                              bit alloc routines for quant of 65535 * 
 *                              and passing proper function args.     * 
 *                              Removed "Other Joint Stereo" option   * 
 *                              and made bitrate be total channel     * 
 *                              bitrate, irrespective of the mode.    * 
 *                              Fixed many small bugs & reorganized.  * 
 * 2/25/92  Masahiro Iwadare    made code cleaner and more consistent * 
 * 8/07/92  Mike Coleman        make exit() codes return error status * 
 *                              made slight changes for portability   * 
 *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  * 
 * 8/25/92  Shaun Astarabadi    Replaced rint() function with explicit* 
 *                              rounding for portability with MSDOS.  * 
 * 9/22/92  jddevine@aware.com  Fixed _scale_factor_calc() calls.     * 
 *10/19/92  Masahiro Iwadare    added info->mode and info->mode_ext   * 
 *                              updates for AIFF format files         * 
 * 3/10/93  Kevin Peterson      In parse_args, only set non default   * 
 *                              bit rate if specified in arg list.    * 
 *                              Use return value from aiff_read_hdrs  * 
 *                              to fseek to start of sound data       * 
 * 7/26/93  Davis Pan           fixed bug in printing info->mode_ext  * 
 *                              value for joint stereo condition      * 
 * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        * 
 *         Daniel Lauzon, and                                         * 
 *         Bill Truerniet                                             * 
 **********************************************************************/ 
/* 
 * 4/4/97 - John Schlichther 
 * 
 * extensively altered to create avi2mpg1 - avi to mpeg-1 encoder 
 * 
 * Since avi file, and the avi subsystem are platform dependant, cross 
 * platform compatibility removed, many optional features disabled or 
 * removed, code generally trimmed to a minimum. 
 * 
 *  7/15/97 - John Schlichther - added support for 8 and 16 bit audio at  
 *                               11.025, 22.05, and 44.1 KHz sample rates 
 */ 
 
 
 
#include  
#include "common.h" 
#include "encoder.h" 
#include "global.h" 
 
/* Global variable definitions for "avi2mp2.c" */ 
 
Bit_stream_struc   bs; 
char             programName[] = "avi2mpg1"; 
int	channels; 
 
FILE *hOutput; 
unsigned long length, last_sample = 0; 
 
 
/* Implementations */ 
 
 
/************************************************************************ 
/* 
/* set_parms 
/* 
/* PURPOSE:  Sets encoding parameters to the specifications of the 
/* command line.  Default settings are used for parameters 
/* not specified in the command line. 
/* 
/************************************************************************/ 
  
void set_parms(fr_ps, num_samples, tempfile) 
frame_params  *fr_ps; 
unsigned long *num_samples; 
char * tempfile; 
{ 
   layer *info = fr_ps->header; 
   int   err = 0, i = 0; 
    
   /* preset defaults */ 
   info->lay = audio_layer_parm; 
  
   if(pWavFormat.nChannels == 1) 
   { 
	    info->mode = MPG_MD_MONO; 
		info->mode_ext = 0; 
   } 
   else 
   { 
		if(joint_stereo_parm == 1) 
		{ 
			info->mode = MPG_MD_JOINT_STEREO; 
		} 
		else 
		{ 
			info->mode = MPG_MD_STEREO; 
			info->mode_ext = 0; 
		} 
   } 
 
   if((info->sampling_frequency = SmpFrqIndex((long)(1000*DFLT_SFQ))) < 0) 
   { 
      fprintf(stderr, "%s: bad sfrq default %.2f\n", programName, DFLT_SFQ); 
      abort(); 
   } 
   if((info->bitrate_index = BitrateIndex(info->lay, audio_bitrate_parm)) < 0) 
   { 
      fprintf(stderr, "%s: bad default bitrate %u\n", programName, DFLT_BRT); 
      abort(); 
   } 
  
 switch(DFLT_EMP) 
   { 
      case 'n': info->emphasis = 0; break; 
      case '5': info->emphasis = 1; break; 
      case 'c': info->emphasis = 3; break; 
      default:  
	 fprintf(stderr, "%s: Bad emph dflt %c\n", programName, DFLT_EMP); 
	 abort(); 
   } 
  
   info->copyright = 0; info->original = 0; info->error_protection = FALSE; 
  
	length = sizeof(pWavFormat); 
 
	channels = pWavFormat.nChannels; // store for later 
 
	if ((pWavFormat.nSamplesPerSec != 11025)&&(pWavFormat.nSamplesPerSec != 22050)&&(pWavFormat.nSamplesPerSec != 44100)) 
	{ 
		fprintf(stderr, "Samples per Sec = %i\n", pWavFormat.nSamplesPerSec); 
		fprintf(stderr, "input avi audio sample rate must = 11.025, 22.05, or 44.1 kHz!"); 
		exit(1); 
	} 
 
	if ((pWavFormat.wBitsPerSample != 8)&&(pWavFormat.wBitsPerSample != 16)) 
	{ 
		fprintf(stderr, "Bits per Sample = %i\n", pWavFormat.wBitsPerSample); 
		fprintf(stderr, "input avi audio must be 8 or 16 bit!"); 
		exit(1); 
	} 
 
     
   open_bit_stream_w(&bs, tempfile, BUFFER_SIZE); 
 
   if(pWavFormat.nChannels == 2) 
	   *num_samples = pAudioStreamInfo.dwLength * 2; 
   else 
	   *num_samples = pAudioStreamInfo.dwLength; 
 
   if(pWavFormat.nSamplesPerSec == 22050) 
	   *num_samples = *num_samples * 2; 
 
   if(pWavFormat.nSamplesPerSec == 11025) 
	   *num_samples = *num_samples * 4; 
 
} 
 
  
/************************************************************************ 
/* 
/* avi2mp2 
/* 
/* PURPOSE:  MPEG I Encoder supporting layers 1 and 2, and 
/* psychoacoustic model 2 (AT&T) 
/* 
/* SEMANTICS:  One overlapping frame of audio of up to 2 channels are 
/* processed at a time in the following order: 
/* (associated routines are in parentheses) 
/* 
/* 1.  Filter sliding window of data to get 32 subband 
/* samples per channel. 
/* (window_subband,filter_subband) 
/* 
/* 2.  If joint stereo mode, combine left and right channels 
/* for subbands above #jsbound#. 
/* (*_combine_LR) 
/* 
/* 3.  Calculate scalefactors for the frame, and if layer 2, 
/* also calculate scalefactor select information. 
/* (*_scale_factor_calc) 
/* 
/* 4.  Calculate psychoacoustic masking levels using selected 
/* psychoacoustic model. 
/* (*_Psycho_One, psycho_anal) 
/* 
/* 5.  Perform iterative bit allocation for subbands with low 
/* mask_to_noise ratios using masking levels from step 4. 
/* (*_main_bit_allocation) 
/* 
/* 6.  If error protection flag is active, add redundancy for 
/* error protection. 
/* (*_CRC_calc) 
/* 
/* 7.  Pack bit allocation, scalefactors, and scalefactor select 
/* information (layer 2) onto bitstream. 
/* (*_encode_bit_alloc,*_encode_scale,II_transmission_pattern) 
/* 
/* 8.  Quantize subbands and pack them into bitstream 
/* (*_subband_quantization, *_sample_encoding) 
/* 
/************************************************************************/ 
 
avi2mp2(tempfile) 
char * tempfile; 
{ 
typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT]; 
    SBS        *sb_sample; 
typedef double JSBS[3][SCALE_BLOCK][SBLIMIT]; 
    JSBS        *j_sample; 
typedef double INN[2][HAN_SIZE]; 
    INN          *win_que; 
typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT]; 
    SUB         *subband; 
  
    frame_params fr_ps; 
    layer info; 
    short **win_buf; 
static short buffer[2][1152]; 
static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT]; 
static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT]; 
static double ltmin[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT]; 
    FLOAT snr32[32]; 
    short sam[2][1056]; 
    int whole_SpF, extra_slot = 0; 
    double avg_slots_per_frame, frac_SpF, slot_lag; 
    int stereo, error_protection; 
static unsigned int crc; 
    int i, j, k, adb; 
    unsigned long bitsPerSlot, samplesPerFrame, frameNum = 0; 
    unsigned long frameBits, sentBits = 0; 
    unsigned long num_samples; 
 
    /* Most large variables are declared dynamically to ensure 
       compatibility with smaller machines */ 
 
    sb_sample = (SBS *) mem_alloc(sizeof(SBS), "sb_sample"); 
    j_sample = (JSBS *) mem_alloc(sizeof(JSBS), "j_sample"); 
    win_que = (INN *) mem_alloc(sizeof(INN), "Win_que"); 
    subband = (SUB *) mem_alloc(sizeof(SUB),"subband"); 
    win_buf = (short **) mem_alloc(sizeof(short *)*2, "win_buf"); 
  
    /* clear buffers */ 
    memset((char *) buffer, 0, sizeof(buffer)); 
    memset((char *) bit_alloc, 0, sizeof(bit_alloc)); 
    memset((char *) scalar, 0, sizeof(scalar)); 
    memset((char *) j_scale, 0, sizeof(j_scale)); 
    memset((char *) scfsi, 0, sizeof(scfsi)); 
    memset((char *) ltmin, 0, sizeof(ltmin)); 
    memset((char *) lgmin, 0, sizeof(lgmin)); 
    memset((char *) max_sc, 0, sizeof(max_sc)); 
    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; 
    info.version = MPEG_AUDIO_ID; 
 
    set_parms(&fr_ps, &num_samples, tempfile); 
 
	hdr_to_frps(&fr_ps); 
    stereo = fr_ps.stereo; 
    error_protection = info.error_protection; 
  
    if (info.lay == 1) { bitsPerSlot = 32; samplesPerFrame = 384;  } 
    else               { bitsPerSlot = 8;  samplesPerFrame = 1152; } 
    /* Figure average number of 'slots' per frame. */ 
    /* Bitrate means TOTAL for both channels, not per side. */ 
    avg_slots_per_frame = ((double)samplesPerFrame / 
			   s_freq[info.sampling_frequency]) * 
			  ((double)bitrate[info.lay-1][info.bitrate_index] / 
			   (double)bitsPerSlot); 
    whole_SpF = (int) avg_slots_per_frame; 
    //printf("slots/frame = %d\n",whole_SpF); 
    frac_SpF  = avg_slots_per_frame - (double)whole_SpF; 
    slot_lag  = -frac_SpF; 
    //fprintf(stderr, "frac SpF=%.3f, tot bitrate=%d kbps, s freq=%.1f kHz\n", 
	//   frac_SpF, bitrate[info.lay-1][info.bitrate_index], 
	//   s_freq[info.sampling_frequency]); 
  
    if (frac_SpF != 0) 
       //printf("Fractional number of slots, padding required\n"); 
	   {} 
    else 
		info.padding = 0; 
  
    while (get_audio(buffer, num_samples, stereo, info.lay) > 0) { 
 
       //fprintf(stderr, "\raudio frame %u", frameNum++); fflush(stderr); 
		fprintf(stderr, "\r%5.1f%% complete", ((float)(num_samples-bytes_processed)/(float)num_samples)*100.0); 
       win_buf[0] = &buffer[0][0]; 
       win_buf[1] = &buffer[1][0]; 
       if (frac_SpF != 0) { 
	  if (slot_lag > (frac_SpF-1.0) ) { 
	     slot_lag -= frac_SpF; 
	     extra_slot = 0; 
	     info.padding = 0; 
	     /*  printf("No padding for this frame\n"); */ 
	  } 
	  else { 
	     extra_slot = 1; 
	     info.padding = 1; 
	     slot_lag += (1-frac_SpF); 
	     /*  printf("Padding for this frame\n");    */ 
	  } 
       } 
       adb = (whole_SpF+extra_slot) * bitsPerSlot; 
 
       switch (info.lay) 
	   { 
  
/***************************** Layer I **********************************/ 
  
	   case 1 : 
	      for (j=0;j