?? encode.c
字號(hào):
/********************************************************************** * ISO MPEG Audio Subgroup Software Simulation Group (1996) * ISO 13818-3 MPEG-2 Audio Encoder - Lower Sampling Frequency Extension * * $Id: encode.c,v 1.1 1996/02/14 04:04:23 rowlands Exp $ * * $Log: encode.c,v $ * Revision 1.1 1996/02/14 04:04:23 rowlands * Initial revision * * Received from Mike Coleman **********************************************************************//********************************************************************** * 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 * * efilter to enfilter * * ewindow to enwindow * * integrated "quantizer", "scalefactor",* * and "transmission" files * * update routine "window_subband" * * 3/31/91 Bill Aspromonte replaced read_filter by * * create_an_filter * * 5/10/91 W. Joseph Carter Ported to Macintosh and Unix. * * Incorporated Jean-Georges Fritsch's * * "bitstream.c" package. * * Incorporated Bill Aspromonte's * * filterbank coefficient matrix * * calculation routines and added * * roundoff to coincide with specs. * * Modified to strictly adhere to * * encoded bitstream specs, including * * "Berlin changes". * * 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. * * 19jun91 dpwe (Aware) moved "alloc_*" reader to common.c * * Globals sblimit, alloc replaced by new* * struct 'frame_params' passed as arg. * * Added JOINT STEREO coding, layers I,II* * Affects: *_bit_allocation, * * subband_quantization, encode_bit_alloc* * sample_encoding * * 6/10/91 Earle Jennings modified II_subband_quantization to * * resolve type cast problem for MS_DOS * * 6/11/91 Earle Jennings modified to avoid overflow on MS_DOS * * in routine filter_subband * * 7/10/91 Earle Jennings port to MsDos from MacIntosh version * * 8/ 8/91 Jens Spille Change for MS-C6.00 * *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 function encode_CRC * *11/ 8/91 Kathy Wang Documentation of code * * All variablenames are referred to * * with surrounding pound (#) signs * * 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. * * 6/16/92 Shaun Astarabadi Changed I_scale_factor_calc() and * * II_scale_factor_calc() to use scale * * factor 0 thru 62 only and not to * * encode index 63 into the bit stream. * * 7/27/92 Mike Li (re-)Port to MS-DOS * * 9/22/92 jddevine@aware.com Fixed _scale_factor_calc() defs * * 3/31/93 Giogio Dimino changed II_a_bit_allocation() from: * * if( ad > ...) to if(ad >= ...) * * 8/05/93 TEST changed I_a_bit_allocation() from: * * if( ad > ...) to if(ad >= ...) * * 8/02/95 mc@fivebats.com Changed audio file reading code to * * read samples big-endian * *10/15/95 mc@fivebats.com Modified get_audio() for layer3-LSF * **********************************************************************/ #include "common.h"#include "encoder.h"#ifdef MS_DOSextern unsigned _stklen = 16384;#endif/*=======================================================================\| || This segment contains all the core routines of the encoder, || except for the psychoacoustic models. || || The user can select either one of the two psychoacoustic || models. Model I is a simple tonal and noise masking threshold || generator, and Model II is a more sophisticated cochlear masking || threshold generator. Model I is recommended for lower complexity || applications whereas Model II gives better subjective quality at low || bit rates. || || Layers I and II of mono, stereo, and joint stereo modes are supported.|| Routines associated with a given layer are prefixed by "I_" for layer || 1 and "II_" for layer 2. |\=======================================================================*/ /************************************************************************** read_samples()** PURPOSE: reads the PCM samples from a file to the buffer** SEMANTICS:* Reads #samples_read# number of shorts from #musicin# filepointer* into #sample_buffer[]#. Returns the number of samples read.*************************************************************************/unsigned long read_samples(musicin, sample_buffer, num_samples, frame_size)FILE *musicin;short sample_buffer[2304];unsigned long num_samples, frame_size;{ unsigned long samples_read; static unsigned long samples_to_read; static char init = TRUE; if (init) { samples_to_read = num_samples; init = FALSE; } if (samples_to_read >= frame_size) samples_read = frame_size; else samples_read = samples_to_read; if ((samples_read = fread(sample_buffer, sizeof(short), (int)samples_read, musicin)) == 0) printf("Hit end of audio data\n"); /* Samples are big-endian. If this is a little-endian machine we must swap */ if ( NativeByteOrder == order_unknown ) { NativeByteOrder = DetermineByteOrder(); if ( NativeByteOrder == order_unknown ) { fprintf( stderr, "byte order not determined\n" ); exit( 1 ); } } if ( NativeByteOrder == order_littleEndian ) SwapBytesInWords( sample_buffer, samples_read ); samples_to_read -= samples_read; if (samples_read < frame_size && samples_read > 0) { printf("Insufficient PCM input for one frame - fillout with zeros\n"); for (; samples_read < frame_size; sample_buffer[samples_read++] = 0); samples_to_read = 0; } return(samples_read);}/************************************************************************** get_audio()** PURPOSE: reads a frame of audio data from a file to the buffer,* aligns the data for future processing, and separates the* left and right channels**************************************************************************/ unsigned long get_audio( musicin, buffer, num_samples, stereo, info )FILE *musicin;short FAR buffer[2][1152];unsigned long num_samples;int stereo;layer *info;{ int j; short insamp[2304]; unsigned long samples_read; int lay; lay = info->lay; if ( (lay == 3) && (info->version == 0) ) { if ( stereo == 2 ) { samples_read = read_samples( musicin, insamp, num_samples, (unsigned long) 1152 ); for ( j = 0; j < 576; j++ ) { buffer[0][j] = insamp[2 * j]; buffer[1][j] = insamp[2 * j + 1]; } } else { samples_read = read_samples( musicin, insamp, num_samples, (unsigned long) 576 ); for ( j = 0; j < 576; j++ ) { buffer[0][j] = insamp[j]; buffer[1][j] = 0; } } } else { if (lay == 1){ if(stereo == 2){ /* layer 1, stereo */ samples_read = read_samples(musicin, insamp, num_samples, (unsigned long) 768); for(j=0;j<448;j++) { if(j<64) { buffer[0][j] = buffer[0][j+384]; buffer[1][j] = buffer[1][j+384]; } else { buffer[0][j] = insamp[2*j-128]; buffer[1][j] = insamp[2*j-127]; } } } else { /* layer 1, mono */ samples_read = read_samples(musicin, insamp, num_samples, (unsigned long) 384); for(j=0;j<448;j++){ if(j<64) { buffer[0][j] = buffer[0][j+384]; buffer[1][j] = 0; } else { buffer[0][j] = insamp[j-64]; buffer[1][j] = 0; } } } } else { if(stereo == 2){ /* layer 2 (or 3), stereo */ samples_read = read_samples(musicin, insamp, num_samples, (unsigned long) 2304); for(j=0;j<1152;j++) { buffer[0][j] = insamp[2*j]; buffer[1][j] = insamp[2*j+1]; } } else { /* layer 2 (or 3), mono */ samples_read = read_samples(musicin, insamp, num_samples, (unsigned long) 1152); for(j=0;j<1152;j++){ buffer[0][j] = insamp[j]; buffer[1][j] = 0; } } } } return(samples_read);} /************************************************************************** read_ana_window()** PURPOSE: Reads encoder window file "enwindow" into array #ana_win#*************************************************************************/ void read_ana_window(ana_win)double FAR ana_win[HAN_SIZE];{ int i,j[4]; FILE *fp; double f[4]; char t[150]; if (!(fp = OpenTableFile("enwindow") ) ) { printf("Please check analysis window table 'enwindow'\n"); exit(1); } for (i=0;i<512;i+=4) { fgets(t, 150, fp); sscanf(t,"C[%d] = %lf C[%d] = %lf C[%d] = %lf C[%d] = %lf\n", j, f,j+1,f+1,j+2,f+2,j+3,f+3); if (i==j[0]) { ana_win[i] = f[0]; ana_win[i+1] = f[1]; ana_win[i+2] = f[2]; ana_win[i+3] = f[3]; } else { printf("Check index in analysis window table\n"); exit(1); } fgets(t,150,fp); } fclose(fp);}/************************************************************************** window_subband()** PURPOSE: Overlapping window on PCM samples** SEMANTICS:* 32 16-bit pcm samples are scaled to fractional 2's complement and* concatenated to the end of the window buffer #x#. The updated window* buffer #x# is then windowed by the analysis window #c# to produce the* windowed sample #z#*************************************************************************/ void window_subband(buffer, z, k)short FAR **buffer;double FAR z[HAN_SIZE];int k;{ typedef double FAR XX[2][HAN_SIZE]; static XX FAR *x; int i, j; static off[2] = {0,0}; static char init = 0; static double FAR *c; if (!init) { c = (double FAR *) mem_alloc(sizeof(double) * HAN_SIZE, "window"); read_ana_window(c); x = (XX FAR *) mem_alloc(sizeof(XX),"x"); for (i=0;i<2;i++) for (j=0;j<HAN_SIZE;j++) (*x)[i][j] = 0; init = 1; } /* replace 32 oldest samples with 32 new samples */ for (i=0;i<32;i++) (*x)[k][31-i+off[k]] = (double) *(*buffer)++/SCALE; /* shift samples into proper window positions */ for (i=0;i<HAN_SIZE;i++) z[i] = (*x)[k][(i+off[k])&HAN_SIZE-1] * c[i]; off[k] += 480; /*offset is modulo (HAN_SIZE-1)*/ off[k] &= HAN_SIZE-1;} /************************************************************************** create_ana_filter()** PURPOSE: Calculates the analysis filter bank coefficients** SEMANTICS:* Calculates the analysis filterbank coefficients and rounds to the* 9th decimal place accuracy of the filterbank tables in the ISO* document. The coefficients are stored in #filter#************************************************************************/ void create_ana_filter(filter)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -