home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Sound
/
LAME
/
Source
/
encode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-31
|
9KB
|
347 lines
/**********************************************************************
* ISO MPEG Audio Subgroup Software Simulation Group (1996)
* ISO 13818-3 MPEG-2 Audio Encoder - Lower Sampling Frequency Extension
*
* $Id: encode.c,v 1.2 1998/10/05 17:06:47 larsi Exp $
*
* $Log: encode.c,v $
* Revision 1.2 1998/10/05 17:06:47 larsi
* *** empty log message ***
*
* Revision 1.1.1.1 1998/10/05 14:47:17 larsi
*
* Revision 1.1 1996/02/14 04:04:23 rowlands
* Initial revision
*
* Received from Mike Coleman
**********************************************************************/
#include "common.h"
#include "encoder.h"
/************************************************************************
*
* 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;
extern int swapbytes; /* if TRUE then force swapping of byte order */
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 (!iswav && ( NativeByteOrder == order_littleEndian ))
SwapBytesInWords( sample_buffer, samples_read );
if (swapbytes==TRUE)
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, bufferL,bufferR, num_samples, stereo, info )
FILE *musicin;
/*
short FAR buffer[2][1152];
*/
short FAR bufferL[1152],bufferR[1152];
unsigned long num_samples;
int stereo;
layer *info;
{
int j;
short insamp[3176];
unsigned long samples_read;
int lay;
extern int autoconvert;
lay = info->lay;
/* pad with zeros in case we hit EOF */
memset((char *) insamp, 0, sizeof(insamp));
if ( (lay == 3) && (info->version == 0) ) /* ie MPEG-2 LSF */
{
if ( stereo == 2 )
{
samples_read = read_samples( musicin, insamp, num_samples,
(unsigned long) 1152 );
for ( j = 0; j < 576; j++ )
{
bufferL[j] = insamp[2 * j];
bufferR[j] = insamp[2 * j + 1];
}
}
else
{
samples_read = read_samples( musicin, insamp, num_samples,
(unsigned long) 576 );
for ( j = 0; j < 576; j++ )
{
bufferL[j] = insamp[j];
bufferR[j] = 0;
}
}
}
else
/* MPEG 1 */
{
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++) {
bufferL[j] = insamp[2*j];
bufferR[j] = insamp[2*j+1];
}
}
else { /* layer 2 (or 3), mono */
if (autoconvert==TRUE) { /* downconvert from a stereo file into a mono buffer */
samples_read = read_samples(musicin, insamp, num_samples,
(unsigned long) 2304);
for(j=0;j<1152;j++){
bufferL[j] = insamp[2*j];
bufferR[j] = 0;
}
}
else {
samples_read = read_samples(musicin, insamp, num_samples,
(unsigned long) 1152);
for(j=0;j<1152;j++){
bufferL[j] = insamp[j];
bufferR[j] = 0;
}
}
}
}
return(samples_read);
}
/************************************************************************
*
* 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#
*
************************************************************************/
extern double enwindow[];
void window_subband(buffer, z, k)
short **buffer;
double z[HAN_SIZE];
int k;
{
typedef double FAR XX[2][HAN_SIZE];
static XX FAR *x;
double *xk;
int i;
static int off[2] = {0,0};
static char init = 0;
if (!init) {
x = (XX FAR *) mem_alloc(sizeof(XX),"x");
memset(x, 0, 2*HAN_SIZE);
init = 1;
}
xk=(*x)[k];
/* replace 32 oldest samples with 32 new samples */
for (i=0;i<32;i++) /*(*x)[k]*/xk[31-i+off[k]] = (double) *(*buffer)++/SCALE;
/* shift samples into proper window positions */
for (i=0;i<HAN_SIZE;i++) z[i] = xk[(i+off[k])&(HAN_SIZE-1)] * enwindow[i];
off[k] += 480; /*offset is modulo (HAN_SIZE-1)*/
off[k] &= HAN_SIZE-1;
}
/************************************************************************
*
* filter_subband()
*
* PURPOSE: Calculates the analysis filter bank coefficients
*
* SEMANTICS:
* The windowed samples #z# is filtered by the digital filter matrix #m#
* to produce the subband samples #s#. This done by first selectively
* picking out values from the windowed samples, and then multiplying
* them by the filter matrix, producing 32 subband samples.
*
************************************************************************/
void
create_dct_matrix( filter )
double filter[16][32];
{
register int i,k;
for (i=0; i<16; i++)
for (k=0; k<32; k++) {
filter[i][k] = cos((double)((2*i+1)*k*PI64));
}
}
void
IDCT32( xin, xout )
double *xin, *xout;
{
int i,j;
double s0, s1;
typedef double MM[16][32];
static MM FAR * m = 0;
if( m==0 ) {
m = (MM FAR *)mem_alloc(sizeof(MM),"filter");
create_dct_matrix( *m );
}
for( i=0; i<16; i++ ) {
s0 = s1 = 0.0;
for( j=0; j<32; j+=2 ) {
s0 += (*m)[i][j]*xin[j+0];
s1 += (*m)[i][j+1]*xin[j+1];
}
xout[i] = s0+s1;
xout[31-i] = s0-s1;
}
}
void filter_subband(z,s)
double FAR z[HAN_SIZE], s[SBLIMIT];
{
double y[64],yprime[32];
int i;
double *zi;
zi = z;
for( i=0; i<64; i++ ) {
y[ i ] = *zi + zi[ 64 ] + zi[ 128 ] + zi[ 192 ] +
zi[ 256 ] + zi[ 320 ] + zi[ 384 ] + zi[ 448 ];
zi++;
}
{
yprime[0] = y[16];
for( i=1; i<=16; i++ ) yprime[i] = y[i+16]+y[16-i];
for( i=17; i<=31; i++ ) yprime[i] = y[i+16]-y[80-i];
IDCT32( yprime, s );
}
}
/************************************************************************
* encode_info()
*
* PURPOSE: Puts the syncword and header information on the output
* bitstream.
*
************************************************************************/
void encode_info(fr_ps,bs)
frame_params *fr_ps;
Bit_stream_struc *bs;
{
layer *info = fr_ps->header;
putbits(bs,0xfff,12); /* syncword 12 bits */
put1bit(bs,info->version); /* ID 1 bit */
putbits(bs,4-info->lay,2); /* layer 2 bits */
put1bit(bs,!info->error_protection); /* bit set => no err prot */
putbits(bs,info->bitrate_index,4);
putbits(bs,info->sampling_frequency,2);
put1bit(bs,info->padding);
put1bit(bs,info->extension); /* private_bit */
putbits(bs,info->mode,2);
putbits(bs,info->mode_ext,2);
put1bit(bs,info->copyright);
put1bit(bs,info->original);
putbits(bs,info->emphasis,2);
}
/************************************************************************
*
* mod()
*
* PURPOSE: Returns the absolute value of its argument
*
************************************************************************/
double mod(a)
double a;
{
return (a > 0) ? a : -a;
}
/************************************************************************
*
* encode_CRC
*
************************************************************************/
void encode_CRC(crc, bs)
unsigned int crc;
Bit_stream_struc *bs;
{
putbits(bs, crc, 16);
}