/********************************************************************** Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved encode.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 "common.h" #include "encoder.h" #ifdef MS_DOS extern 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_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 /* /* 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 FAR buffer[2][1152]; unsigned long num_samples; int stereo, lay; { int j; short insamp[2304]; unsigned long samples_read; 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= 0) modf(filter[i][k]+0.5, &filter[i][k]); else modf(filter[i][k]-0.5, &filter[i][k]); filter[i][k] *= 1e-9; } } /************************************************************************/ /* /* 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 filter_subband(z,s) double FAR z[HAN_SIZE], s[SBLIMIT]; { double y[64]; int i,j; static char init = 0; typedef double MM[SBLIMIT][64]; static MM FAR *m; #ifdef MS_DOS long SIZE_OF_MM; SIZE_OF_MM = SBLIMIT*64; SIZE_OF_MM *= 8; if (!init) { m = (MM FAR *) mem_alloc(SIZE_OF_MM, "filter"); create_ana_filter(*m); init = 1; } #else if (!init) { m = (MM FAR *) mem_alloc(sizeof(MM), "filter"); create_ana_filter(*m); init = 1; } #endif for (i=0;i<64;i++) for (j=0, y[i] = 0;j<8;j++) y[i] += z[i+64*j]; for (i=0;iheader; 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; } /************************************************************************/ /* /* I_combine_LR (Layer I) /* II_combine_LR (Layer II) /* /* PURPOSE:Combines left and right channels into a mono channel /* /* SEMANTICS: The average of left and right subband samples is put into /* #joint_sample# /* /* Layer I and II differ in frame length and # subbands used /* /************************************************************************/ void I_combine_LR(sb_sample, joint_sample) double FAR sb_sample[2][3][SCALE_BLOCK][SBLIMIT]; double FAR joint_sample[3][SCALE_BLOCK][SBLIMIT]; { /* make a filtered mono for joint stereo */ int sb, smp; for(sb = 0; sb s[i]) s[i] = mod(sb_sample[k][0][j][i]); for (i=0;i=0;j--) /* $A 6/16/92 */ if (s[i] <= multiple[j]) { scalar[k][0][i] = j; break; } } } /******************************** Layer II ******************************/ void II_scale_factor_calc(sb_sample,scalar,stereo,sblimit) double FAR sb_sample[][3][SCALE_BLOCK][SBLIMIT]; unsigned int scalar[][3][SBLIMIT]; int stereo,sblimit; { int i,j, k,t; double s[SBLIMIT]; for (k=0;k s[i]) s[i] = mod(sb_sample[k][t][j][i]); for (i=0;i=0;j--) /* $A 6/16/92 */ if (s[i] <= multiple[j]) { scalar[k][t][i] = j; break; } for (i=sblimit;istereo; int sblimit = fr_ps->sblimit; for (k=0;k scalar[k][j][i]) max = scalar[k][j][i]; for (i=sblimit;istereo; int sblimit = fr_ps->sblimit; for (k=0;kstereo; int sblimit = fr_ps->sblimit; int dscf[2]; int class[2],i,j,k; static int pattern[5][5] = {0x123, 0x122, 0x122, 0x133, 0x123, 0x113, 0x111, 0x111, 0x444, 0x113, 0x111, 0x111, 0x111, 0x333, 0x113, 0x222, 0x222, 0x222, 0x333, 0x123, 0x123, 0x122, 0x122, 0x133, 0x123}; for (k=0;k -3 && dscf[j] <0) class[j] = 1; else if (dscf[j] == 0) class[j] = 2; else if (dscf[j] > 0 && dscf[j] < 3) class[j] = 3; else class[j] = 4; } switch (pattern[class[0]][class[1]]) { case 0x123 : scfsi[k][i] = 0; break; case 0x122 : scfsi[k][i] = 3; scalar[k][2][i] = scalar[k][1][i]; break; case 0x133 : scfsi[k][i] = 3; scalar[k][1][i] = scalar[k][2][i]; break; case 0x113 : scfsi[k][i] = 1; scalar[k][1][i] = scalar[k][0][i]; break; case 0x111 : scfsi[k][i] = 2; scalar[k][1][i] = scalar[k][2][i] = scalar[k][0][i]; break; case 0x222 : scfsi[k][i] = 2; scalar[k][0][i] = scalar[k][2][i] = scalar[k][1][i]; break; case 0x333 : scfsi[k][i] = 2; scalar[k][0][i] = scalar[k][1][i] = scalar[k][2][i]; break; case 0x444 : scfsi[k][i] = 2; if (scalar[k][0][i] > scalar[k][2][i]) scalar[k][0][i] = scalar[k][2][i]; scalar[k][1][i] = scalar[k][2][i] = scalar[k][0][i]; } } } /************************************************************************ /* /* I_encode_scale (Layer I) /* II_encode_scale (Layer II) /* /* PURPOSE:The encoded scalar factor information is arranged and /* queued into the output fifo to be transmitted. /* /* For Layer II, the three scale factors associated with /* a given subband and channel are transmitted in accordance /* with the scfsi, which is transmitted first. /* /************************************************************************/ void I_encode_scale(scalar, bit_alloc, fr_ps, bs) unsigned int scalar[2][3][SBLIMIT]; unsigned int bit_alloc[2][SBLIMIT]; frame_params *fr_ps; Bit_stream_struc *bs; { int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; int i,j; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; int i,j,k; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; int req_bits = 0; /* initial b_anc (header) allocation bits */ req_bits = 32 + 4 * ( (jsbound * stereo) + (SBLIMIT-jsbound) ); for(i=0; i= NOISY_MIN_MNR) break; /* we found enough bits */ if(stereo == 2 && i >= jsbound) /* check other JS channel */ for(;k<14; ++k) if( (-perm_smr[1-j][i] + snr[k]) >= NOISY_MIN_MNR) break; if(k>0) req_bits += (k+1)*SCALE_BLOCK + 6*((i>=jsbound)?stereo:1); } return req_bits; } /***************************** Layer II ********************************/ int II_bits_for_nonoise(perm_smr, scfsi, fr_ps) double FAR perm_smr[2][SBLIMIT]; unsigned int scfsi[2][SBLIMIT]; frame_params *fr_ps; { int sb,ch,ba; int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; int req_bits = 0, bbal = 0, berr = 0, banc = 32; int maxAlloc, sel_bits, sc_bits, smp_bits; static int sfsPerScfsi[] = { 3,2,1,2 }; /* lookup # sfs per scfsi */ /* added 92-08-11 shn */ if (fr_ps->header->error_protection) berr=16; else berr=0; for (sb=0; sb0)?1:0)]) >= NOISY_MIN_MNR) break; /* we found enough bits */ if(stereo == 2 && sb >= jsbound) /* check other JS channel */ for(;ba0)?1:0)]) >= NOISY_MIN_MNR) break; if(ba>0) { smp_bits = SCALE_BLOCK * ((*alloc)[sb][ba].group * (*alloc)[sb][ba].bits); /* scale factor bits required for subband */ sel_bits = 2; sc_bits = 6 * sfsPerScfsi[scfsi[ch][sb]]; if(stereo == 2 && sb >= jsbound) { /* each new js sb has L+R scfsis */ sel_bits += 2; sc_bits += 6 * sfsPerScfsi[scfsi[1-ch][sb]]; } req_bits += smp_bits+sel_bits+sc_bits; } } return req_bits; } /************************************************************************ /* /* I_main_bit_allocation (Layer I) /* II_main_bit_allocation (Layer II) /* /* PURPOSE:For joint stereo mode, determines which of the 4 joint /* stereo modes is needed. Then calls *_a_bit_allocation(), which /* allocates bits for each of the subbands until there are no more bits /* left, or the MNR is at the noise/no_noise threshold. /* /* SEMANTICS: /* /* For joint stereo mode, joint stereo is changed to stereo if /* there are enough bits to encode stereo at or better than the /* no-noise threshold (NOISY_MIN_MNR). Otherwise, the system /* iteratively allocates less bits by using joint stereo until one /* of the following occurs: /* - there are no more noisy subbands (MNR >= NOISY_MIN_MNR) /* - mode_ext has been reduced to 0, which means that all but the /* lowest 4 subbands have been converted from stereo to joint /* stereo, and no more subbands may be converted /* /* This function calls *_bits_for_nonoise() and *_a_bit_allocation(). /* /************************************************************************/ void I_main_bit_allocation(perm_smr, bit_alloc, adb, fr_ps) double FAR perm_smr[2][SBLIMIT]; unsigned int bit_alloc[2][SBLIMIT]; int *adb; frame_params *fr_ps; { int noisy_sbs; int mode, mode_ext, lay, i; int rq_db, av_db = *adb; static int init = 0; if(init == 0) { /* rearrange snr for layer I */ snr[2] = snr[3]; for (i=3;i<16;i++) snr[i] = snr[i+2]; init = 1; } if((mode = fr_ps->actual_mode) == MPG_MD_JOINT_STEREO) { fr_ps->header->mode = MPG_MD_STEREO; fr_ps->header->mode_ext = 0; fr_ps->jsbound = fr_ps->sblimit; if(rq_db = I_bits_for_nonoise(perm_smr, fr_ps) > *adb) { fr_ps->header->mode = MPG_MD_JOINT_STEREO; mode_ext = 4; /* 3 is least severe reduction */ lay = fr_ps->header->lay; do { --mode_ext; fr_ps->jsbound = js_bound(lay, mode_ext); rq_db = I_bits_for_nonoise(perm_smr, fr_ps); } while( (rq_db > *adb) && (mode_ext > 0)); fr_ps->header->mode_ext = mode_ext; } /* well we either eliminated noisy sbs or mode_ext == 0 */ } noisy_sbs = I_a_bit_allocation(perm_smr, bit_alloc, adb, fr_ps); } /***************************** Layer II ********************************/ void II_main_bit_allocation(perm_smr, scfsi, bit_alloc, adb, fr_ps) double FAR perm_smr[2][SBLIMIT]; unsigned int scfsi[2][SBLIMIT]; unsigned int bit_alloc[2][SBLIMIT]; int *adb; frame_params *fr_ps; { int noisy_sbs, nn; int mode, mode_ext, lay; int rq_db, av_db = *adb; if((mode = fr_ps->actual_mode) == MPG_MD_JOINT_STEREO) { fr_ps->header->mode = MPG_MD_STEREO; fr_ps->header->mode_ext = 0; fr_ps->jsbound = fr_ps->sblimit; if((rq_db=II_bits_for_nonoise(perm_smr, scfsi, fr_ps)) > *adb) { fr_ps->header->mode = MPG_MD_JOINT_STEREO; mode_ext = 4; /* 3 is least severe reduction */ lay = fr_ps->header->lay; do { --mode_ext; fr_ps->jsbound = js_bound(lay, mode_ext); rq_db = II_bits_for_nonoise(perm_smr, scfsi, fr_ps); } while( (rq_db > *adb) && (mode_ext > 0)); fr_ps->header->mode_ext = mode_ext; } /* well we either eliminated noisy sbs or mode_ext == 0 */ } noisy_sbs = II_a_bit_allocation(perm_smr, scfsi, bit_alloc, adb, fr_ps); } /************************************************************************ /* /* I_a_bit_allocation (Layer I) /* II_a_bit_allocation (Layer II) /* /* PURPOSE:Adds bits to the subbands with the lowest mask-to-noise /* ratios, until the maximum number of bits for the subband has /* been allocated. /* /* SEMANTICS: /* 1. Find the subband and channel with the smallest MNR (#min_sb#, /* and #min_ch#) /* 2. Calculate the increase in bits needed if we increase the bit /* allocation to the next higher level /* 3. If there are enough bits available for increasing the resolution /* in #min_sb#, #min_ch#, and the subband has not yet reached its /* maximum allocation, update the bit allocation, MNR, and bits /* available accordingly /* 4. Repeat until there are no more bits left, or no more available /* subbands. (A subband is still available until the maximum /* number of bits for the subband has been allocated, or there /* aren't enough bits to go to the next higher resolution in the /* subband.) /* /************************************************************************/ int I_a_bit_allocation(perm_smr, bit_alloc, adb, fr_ps) /* return noisy sbs */ double FAR perm_smr[2][SBLIMIT]; unsigned int bit_alloc[2][SBLIMIT]; int *adb; frame_params *fr_ps; { int i, k, smpl_bits, scale_bits, min_sb, min_ch, oth_ch; int bspl, bscf, ad, noisy_sbs, done = 0, bbal ; double mnr[2][SBLIMIT], small; char used[2][SBLIMIT]; int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; static char init= 0; static int banc=32, berr=0; if (!init) { init = 1; if (fr_ps->header->error_protection) berr = 16; /* added 92-08-11 shn */ } bbal = 4 * ( (jsbound * stereo) + (SBLIMIT-jsbound) ); *adb -= bbal + berr + banc; ad= *adb; for (i=0;i mnr[k][i]) { small = mnr[k][i]; min_sb = i; min_ch = k; } if(min_sb > -1) { /* there was something to find */ /* first step of bit allocation is biggest */ if (used[min_ch][min_sb]) { smpl_bits = SCALE_BLOCK; scale_bits = 0; } else { smpl_bits = 24; scale_bits = 6; } if(min_sb >= jsbound) scale_bits *= stereo; /* check to see enough bits were available for */ /* increasing resolution in the minimum band */ if (ad >= bspl + bscf + scale_bits + smpl_bits) { bspl += smpl_bits; /* bit for subband sample */ bscf += scale_bits; /* bit for scale factor */ bit_alloc[min_ch][min_sb]++; used[min_ch][min_sb] = 1; /* subband has bits */ mnr[min_ch][min_sb] = -perm_smr[min_ch][min_sb] + snr[bit_alloc[min_ch][min_sb]]; /* Check if subband has been fully allocated max bits */ if (bit_alloc[min_ch][min_sb] == 14 ) used[min_ch][min_sb] = 2; } else /* no room to improve this band */ used[min_ch][min_sb] = 2; /* for allocation anymore */ if(stereo == 2 && min_sb >= jsbound) { oth_ch = 1-min_ch; /* joint-st : fix other ch */ bit_alloc[oth_ch][min_sb] = bit_alloc[min_ch][min_sb]; used[oth_ch][min_sb] = used[min_ch][min_sb]; mnr[oth_ch][min_sb] = -perm_smr[oth_ch][min_sb] + snr[bit_alloc[oth_ch][min_sb]]; } } } while(min_sb>-1); /* i.e. still some sub-bands to find */ /* Calculate the number of bits left, add on to pointed var */ ad -= bspl+bscf; *adb = ad; /* see how many channels are noisy */ noisy_sbs = 0; small = mnr[0][0]; for(k=0; k mnr[k][i]) small = mnr[k][i]; } } return noisy_sbs; } /***************************** Layer II ********************************/ int II_a_bit_allocation(perm_smr, scfsi, bit_alloc, adb, fr_ps) double FAR perm_smr[2][SBLIMIT]; unsigned int scfsi[2][SBLIMIT]; unsigned int bit_alloc[2][SBLIMIT]; int *adb; frame_params *fr_ps; { int i, min_ch, min_sb, oth_ch, k, increment, scale, seli, ba; int bspl, bscf, bsel, ad, noisy_sbs, bbal=0; double mnr[2][SBLIMIT], small; char used[2][SBLIMIT]; int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; static char init= 0; static int banc=32, berr=0; static int sfsPerScfsi[] = { 3,2,1,2 }; /* lookup # sfs per scfsi */ if (!init) { init = 1; if (fr_ps->header->error_protection) berr=16; /* added 92-08-11 shn */ } for (i=0; i mnr[k][i]) { small = mnr[k][i]; min_sb = i; min_ch = k; } if(min_sb > -1) { /* there was something to find */ /* find increase in bit allocation in subband [min] */ increment = SCALE_BLOCK * ((*alloc)[min_sb][bit_alloc[min_ch][min_sb]+1].group * (*alloc)[min_sb][bit_alloc[min_ch][min_sb]+1].bits); if (used[min_ch][min_sb]) increment -= SCALE_BLOCK * ((*alloc)[min_sb][bit_alloc[min_ch][min_sb]].group* (*alloc)[min_sb][bit_alloc[min_ch][min_sb]].bits); /* scale factor bits required for subband [min] */ oth_ch = 1 - min_ch; /* above js bound, need both chans */ if (used[min_ch][min_sb]) scale = seli = 0; else { /* this channel had no bits or scfs before */ seli = 2; scale = 6 * sfsPerScfsi[scfsi[min_ch][min_sb]]; if(stereo == 2 && min_sb >= jsbound) { /* each new js sb has L+R scfsis */ seli += 2; scale += 6 * sfsPerScfsi[scfsi[oth_ch][min_sb]]; } } /* check to see enough bits were available for */ /* increasing resolution in the minimum band */ if (ad >= bspl + bscf + bsel + seli + scale + increment) { ba = ++bit_alloc[min_ch][min_sb]; /* next up alloc */ bspl += increment; /* bits for subband sample */ bscf += scale; /* bits for scale factor */ bsel += seli; /* bits for scfsi code */ used[min_ch][min_sb] = 1; /* subband has bits */ mnr[min_ch][min_sb] = -perm_smr[min_ch][min_sb] + snr[(*alloc)[min_sb][ba].quant+1]; /* Check if subband has been fully allocated max bits */ if (ba >= (1<<(*alloc)[min_sb][0].bits)-1) used[min_ch][min_sb] = 2; } else used[min_ch][min_sb] = 2; /* can't increase this alloc */ if(min_sb >= jsbound && stereo == 2) { /* above jsbound, alloc applies L+R */ ba = bit_alloc[oth_ch][min_sb] = bit_alloc[min_ch][min_sb]; used[oth_ch][min_sb] = used[min_ch][min_sb]; mnr[oth_ch][min_sb] = -perm_smr[oth_ch][min_sb] + snr[(*alloc)[min_sb][ba].quant+1]; } } } while(min_sb > -1); /* until could find no channel */ /* Calculate the number of bits left */ ad -= bspl+bscf+bsel; *adb = ad; for (i=sblimit;i mnr[k][i]) small = mnr[k][i]; if(mnr[k][i] < NOISY_MIN_MNR) ++noisy_sbs; /* noise is not masked */ } } return noisy_sbs; } /************************************************************************ /* /* I_subband_quantization (Layer I) /* II_subband_quantization (Layer II) /* /* PURPOSE:Quantizes subband samples to appropriate number of bits /* /* SEMANTICS: Subband samples are divided by their scalefactors, which /* makes the quantization more efficient. The scaled samples are /* quantized by the function a*x+b, where a and b are functions of /* the number of quantization levels. The result is then truncated /* to the appropriate number of bits and the MSB is inverted. /* /* Note that for fractional 2's complement, inverting the MSB for a /* negative number x is equivalent to adding 1 to it. /* /************************************************************************/ static double a[17] = { 0.750000000, 0.625000000, 0.875000000, 0.562500000, 0.937500000, 0.968750000, 0.984375000, 0.992187500, 0.996093750, 0.998046875, 0.999023438, 0.999511719, 0.999755859, 0.999877930, 0.999938965, 0.999969482, 0.999984741 }; static double b[17] = { -0.250000000, -0.375000000, -0.125000000, -0.437500000, -0.062500000, -0.031250000, -0.015625000, -0.007812500, -0.003906250, -0.001953125, -0.000976563, -0.000488281, -0.000244141, -0.000122070, -0.000061035, -0.000030518, -0.000015259 }; void I_subband_quantization(scalar, sb_samples, j_scale, j_samps, bit_alloc, sbband, fr_ps) unsigned int scalar[2][3][SBLIMIT]; double FAR sb_samples[2][3][SCALE_BLOCK][SBLIMIT]; unsigned int j_scale[3][SBLIMIT]; double FAR j_samps[3][SCALE_BLOCK][SBLIMIT]; /* L+R for j-stereo if necess */ unsigned int bit_alloc[2][SBLIMIT]; unsigned int FAR sbband[2][3][SCALE_BLOCK][SBLIMIT]; frame_params *fr_ps; { int i, j, k, n, sig; int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; double d; static char init = 0; if (!init) { init = 1; /* rearrange quantization coef to correspond to layer I table */ a[1] = a[2]; b[1] = b[2]; for (i=2;i<15;i++) { a[i] = a[i+2]; b[i] = b[i+2]; } } for (j=0;j=jsbound) /* use the joint data passed in */ d = j_samps[0][j][i] / multiple[j_scale[0][i]]; else d = sb_samples[k][0][j][i] / multiple[scalar[k][0][i]]; /* scale and quantize floating point sample */ n = bit_alloc[k][i]; d = d * a[n-1] + b[n-1]; /* extract MSB N-1 bits from the floating point sample */ if (d >= 0) sig = 1; else { sig = 0; d += 1.0; } sbband[k][0][j][i] = (unsigned int) (d * (double) (1L<stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; unsigned int stps; double d; al_table *alloc = fr_ps->alloc; for (s=0;s<3;s++) for (j=0;j=jsbound) /* use j-stereo samples */ d = j_samps[s][j][i] / multiple[j_scale[s][i]]; else d = sb_samples[k][s][j][i] / multiple[scalar[k][s][i]]; if (mod(d) > 1.0) printf("Not scaled properly %d %d %d %d\n",k,s,j,i); qnt = (*alloc)[i][bit_alloc[k][i]].quant; d = d * a[qnt] + b[qnt]; /* extract MSB N-1 bits from the floating point sample */ if (d >= 0) sig = 1; else { sig = 0; d += 1.0; } n = 0; #ifndef MS_DOS stps = (*alloc)[i][bit_alloc[k][i]].steps; while ((1L<stereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; for(j=0;jstereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; for (s=0;s<3;s++) for (j=0;j