📄 encode.c
字号:
/**********************************************************************Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reservedencode.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 3.9t * * 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 * * 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 >= ...) * **********************************************************************/#include "config.h"#include <stdlib.h>#include <unistd.h>#include "common.h"#include "encoder.h"extern int freq_in;extern int freq_out;extern int chans_in;extern int chans_out;extern int audio_bits;extern unsigned long audio_bytes;static unsigned long nseconds = 0;static int num_out = -1;static int buff_pos;static int big_endian;static unsigned char *in_buff;static short *buf1, *buf2, *out_buff;static double freq_quot;static void read_and_resample(void){ int n, nbps, num_in, is; double s, fs; /* Read 1 second of audio from stdin */ nbps = chans_in*audio_bits/8; /* Bytes per sample in */ if(num_out<0) { /* Initialize, read first sample to the end of the buffer */ n = fread(in_buff+freq_in*nbps,1,nbps,stdin); if(n!=nbps) { mjpeg_error_exit1("Error reading wave data"); } } /* Copy last sample in input buffer to front, read exactly 1 second */ memcpy(in_buff,in_buff+freq_in*nbps,nbps); n = fread(in_buff+nbps,1,freq_in*nbps,stdin); num_in = n/nbps + 1; /* Step 1: Make little endian shorts from input */ if(audio_bits==8) { for(n=0;n<num_in*chans_in;n++) buf1[n] = (in_buff[n]-128)<<8; } else if(big_endian) { swab(in_buff,buf1,num_in*nbps); } /* Step 2: Make mono from stereo or vice versa if wanted */ if(chans_in==2 && chans_out==1) { for(n=0;n<num_in;n++) buf2[n] = (buf1[2*n]+buf1[2*n+1]) >> 1; } if(chans_in==1 && chans_out==2) { for(n=0;n<num_in;n++) buf2[2*n] = buf2[2*n+1] = buf1[n]; } /* Step 3: Change sampling frequency if necessary */ num_out = ((int64_t)num_in-1)*(int64_t)freq_out/(int64_t)freq_in; if(freq_in != freq_out) { for(n=0;n<num_out;n++) { s = n*freq_quot; is = s; fs = s - is; if(chans_out==2) { out_buff[2*n ] = (1.0-fs)*buf2[2*is ] + fs*buf2[2*is+2]; out_buff[2*n+1] = (1.0-fs)*buf2[2*is+1] + fs*buf2[2*is+3]; } else { out_buff[n] = (1.0-fs)*buf2[is] + fs*buf2[is+1]; } } } num_out *= chans_out; nseconds++; mjpeg_debug("%4ld seconds done",nseconds);}static int get_samples(short *abuff, int num, int stereo){ int n; if(num_out<0) { /* Initialize */ unsigned int fred; char *pfred; fred = 2 | (1 << (sizeof(int)*8-8)); pfred = (char *)&fred; if(*pfred == 1) { big_endian = 1; mjpeg_info("System is big endian"); } else if(*pfred == 2) { big_endian = 0; mjpeg_info("System is little endian"); } else { mjpeg_error("Can not determine if system is big/lttle endian"); mjpeg_error_exit1("Are you running on a Cray - or what?"); } freq_quot = (double)freq_in/(double)freq_out; in_buff = (unsigned char *) malloc((freq_in+1)*chans_in*audio_bits/8); if(!in_buff) mjpeg_error_exit1("Malloc failed"); if( audio_bits==8 || (audio_bits==16 && big_endian) ) { buf1 = (short *)malloc((freq_in+1)*chans_in*sizeof(short)); if(!buf1) mjpeg_error_exit1("Malloc failed"); } else buf1 = (short *)in_buff; if(chans_in!=chans_out) { buf2 = (short *)malloc((freq_in+1)*chans_out*sizeof(short)); if(!buf2) mjpeg_error("Malloc failed"); } else buf2 = buf1; if(freq_in!=freq_out) { out_buff = (short *)malloc(freq_out*chans_out*sizeof(short)); if(!out_buff) mjpeg_error("Malloc failed"); } else out_buff = buf2; /* Read first buffer with samples */ read_and_resample(); buff_pos = 0; } while(num) { if(buff_pos == num_out) { read_and_resample(); buff_pos = 0; if(num_out==0) return 0; } n = num; if(buff_pos+n>num_out) n = num_out-buff_pos; memcpy(abuff,out_buff+buff_pos,n*sizeof(short)); abuff += n; buff_pos += n; num -= n; } return 1;}/*=======================================================================\| || 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. |\=======================================================================*/ /************************************************************************ * * 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 * * SEMANTICS: * Calls read_samples() to read a frame of audio data from filepointer * #musicin# to #insampl[]#. The data is shifted to make sure the data * is centered for the 1024pt window to be used by the psychoacoustic model, * and to compensate for the 256 sample delay from the filter bank. For * stereo, the channels are also demultiplexed into #buffer[0][]# and * #buffer[1][]# * ************************************************************************/ unsigned long get_audio(musicin, buffer, num_samples, stereo, lay)FILE *musicin;short buffer[2][1152];unsigned long num_samples;int stereo, lay;{ int j, res; short insamp[2304]; if (lay == 1){ if(stereo == 2){ /* layer 1, stereo */ res = get_samples(insamp, 384*2, stereo); 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 */ res = get_samples(insamp, 384, stereo); 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 */ res = get_samples(insamp, 1152*2, stereo); 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 */ res = get_samples(insamp, 1152, stereo); for(j=0;j<1152;j++){ buffer[0][j] = insamp[j]; buffer[1][j] = 0; } } } return res;}/************************************************************************ * * 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -