/********************************************************************** Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved decode.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.9 * * changes made since last update: * * date programmers comment * * 2/25/91 Douglas Wong, start of version 1.0 records * * Davis Pan * * 3/06/91 Douglas Wong rename: setup.h to dedef.h * * dfilter to defilter * * dwindow to dewindow * * integrated "quantizer", "scalefactor" * * combined window_samples routine into * * filter samples * * 3/31/91 Bill Aspromonte replaced read_filter by * * create_syn_filter and introduced a * * new Sub-Band Synthesis routine called * * SubBandSynthesis() * * 5/10/91 Vish (PRISM) Ported to Macintosh and Unix. * * Changed "out_fifo()" so that last * * unfilled block is also written out. * * "create_syn_filter()" was modified so * * that calculation precision is same as * * in specification tables. * * Changed "decode_scale()" to reflect * * specifications. * * Removed all routines used by * * "synchronize_buffer()". This is now * * replaced by "seek_sync()". * * Incorporated Jean-Georges Fritsch's * * "bitstream.c" package. * * Deleted "reconstruct_sample()". * * 27jun91 dpwe (Aware) Passed outFile and &sampFrames as * * args to out_fifo() - were global. * * Moved "alloc_*" reader to common.c. * * alloc, sblimit, stereo passed via new * * 'frame_params struct (were globals). * * Added JOINT STEREO decoding, lyrs I&II* * Affects: decode_bitalloc,buffer_samps * * Plus a few other cleanups. * * 6/10/91 Earle Jennings conditional expansion added in * * II_dequantize_sample to handle range * * problems in MSDOS 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 functions are * * buffer_CRC and recover_CRC_error. * * 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. * * 7/27/92 Juan Pineda Bug fix in SubBandSynthesis() * **********************************************************************/ #include "common.h" #include "decoder.h" /*************************************************************** /* /* This module contains the core of the decoder ie all the /* computational routines. (Layer I and II only) /* Functions are common to both layer unless /* otherwise specified. /* /***************************************************************/ /***************************************************************** /* /* The following routines decode the system information /* /****************************************************************/ /************ Layer I, Layer II & Layer III ******************/ void decode_info(bs, fr_ps) Bit_stream_struc *bs; frame_params *fr_ps; { layer *hdr = fr_ps->header; hdr->version = get1bit(bs); hdr->lay = 4-getbits(bs,2); hdr->error_protection = !get1bit(bs); /* error protect. TRUE/FALSE */ hdr->bitrate_index = getbits(bs,4); hdr->sampling_frequency = getbits(bs,2); hdr->padding = get1bit(bs); hdr->extension = get1bit(bs); hdr->mode = getbits(bs,2); hdr->mode_ext = getbits(bs,2); hdr->copyright = get1bit(bs); hdr->original = get1bit(bs); hdr->emphasis = getbits(bs,2); } /******************************************************************* /* /* The bit allocation information is decoded. Layer I /* has 4 bit per subband whereas Layer II is Ws and bit rate /* dependent. /* /********************************************************************/ /**************************** Layer II *************/ void II_decode_bitalloc(bs, bit_alloc, fr_ps) Bit_stream_struc *bs; unsigned int bit_alloc[2][SBLIMIT]; frame_params *fr_ps; { int i,j; int stereo = fr_ps->stereo; 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; int b; for (i=0;istereo; int sblimit = fr_ps->sblimit; for (i=0;istereo; int sblimit = fr_ps->sblimit; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; unsigned int s; for (i=0;istereo; int sblimit = fr_ps->sblimit; int jsbound = fr_ps->jsbound; al_table *alloc = fr_ps->alloc; for (i=0;i= jsbound) /* joint stereo : copy L to R */ for (k=0;k<3;k++) sample[1][k][i] = sample[0][k][i]; } for (i=sblimit;istereo; int sblimit = fr_ps->sblimit; al_table *alloc = fr_ps->alloc; for (i=0;i> x-1) & 1) == 1) fraction[k][j][i] = 0.0; else fraction[k][j][i] = -1.0; /* Form a 2's complement sample */ fraction[k][j][i] += (double) (sample[k][j][i] & ((1<stereo; int sblimit = fr_ps->sblimit; for (i=0;i> nb-1) & 1) == 1) fraction[k][0][i] = 0.0; else fraction[k][0][i] = -1.0; fraction[k][0][i] += (double) (sample[k][0][i] & ((1<stereo; int sblimit = fr_ps->sblimit; for (i=0;istereo; int sblimit = fr_ps->sblimit; for (i=0;i= 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; } } /*************************************************************** /* /* Window the restored sample /* /***************************************************************/ /* read in synthesis window */ void read_syn_window(window) double FAR window[HAN_SIZE]; { int i,j[4]; FILE *fp; double f[4]; char t[150]; if (!(fp = OpenTableFile("dewindow") )) { printf("Please check synthesis window table 'dewindow'\n"); exit(1); } for (i=0;i<512;i+=4) { fgets(t, 150, fp); sscanf(t,"D[%d] = %lf D[%d] = %lf D[%d] = %lf D[%d] = %lf\n", j, f,j+1,f+1,j+2,f+2,j+3,f+3); if (i==j[0]) { window[i] = f[0]; window[i+1] = f[1]; window[i+2] = f[2]; window[i+3] = f[3]; } else { printf("Check index in synthesis window table\n"); exit(1); } fgets(t,150,fp); } fclose(fp); } int SubBandSynthesis (bandPtr, channel, samples) double *bandPtr; int channel; short *samples; { register int i,j,k; register double *bufOffsetPtr, sum; static int init = 1; typedef double NN[64][32]; static NN FAR *filter; typedef double BB[2][2*HAN_SIZE]; static BB FAR *buf; static int bufOffset = 64; static double FAR *window; int clip = 0; /* count & return how many samples clipped */ if (init) { buf = (BB FAR *) mem_alloc(sizeof(BB),"BB"); filter = (NN FAR *) mem_alloc(sizeof(NN), "NN"); create_syn_filter(*filter); window = (double FAR *) mem_alloc(sizeof(double) * HAN_SIZE, "WIN"); read_syn_window(window); bufOffset = 64; init = 0; } if (channel == 0) bufOffset = (bufOffset - 64) & 0x3ff; bufOffsetPtr = &((*buf)[channel][bufOffset]); for (i=0; i<64; i++) { sum = 0; for (k=0; k<32; k++) sum += bandPtr[k] * (*filter)[i][k]; bufOffsetPtr[i] = sum; } /* S(i,j) = D(j+32i) * U(j+32i+((i+1)>>1)*64) */ /* samples(i,j) = MWindow(j+32i) * bufPtr(j+32i+((i+1)>>1)*64) */ for (j=0; j<32; j++) { sum = 0; for (i=0; i<16; i++) { k = j + (i<<5); sum += window[k] * (*buf) [channel] [( (k + ( ((i+1)>>1) <<6) ) + bufOffset) & 0x3ff]; } /* {long foo = (sum > 0) ? sum * SCALE + 0.5 : sum * SCALE - 0.5; */ {long foo = sum * SCALE; if (foo >= (long) SCALE) {samples[j] = SCALE-1; ++clip;} else if (foo < (long) -SCALE) {samples[j] = -SCALE; ++clip;} else samples[j] = foo; } } return(clip); } void out_fifo(pcm_sample, num, fr_ps, done, outFile, psampFrames) short FAR pcm_sample[2][3][SBLIMIT]; int num; frame_params *fr_ps; int done; FILE *outFile; unsigned long *psampFrames; { int i,j,l; int stereo = fr_ps->stereo; int sblimit = fr_ps->sblimit; static short int outsamp[1600]; static long k = 0; if (!done) for (i=0;istereo; int num, done, i; int samplesPerFrame, samplesPerSlot; layer *hdr = fr_ps->header; long offset; short *temp; num = 3; if (hdr->lay == 1) num = 1; samplesPerSlot = SBLIMIT * num * stereo; samplesPerFrame = samplesPerSlot * 32; if (error_count == 1) { /* replicate previous error_free frame */ done = 1; /* flush out fifo */ out_fifo(pcm_sample, num, fr_ps, done, outFile, psampFrames); /* go back to the beginning of the previous frame */ offset = sizeof(short int) * samplesPerFrame; fseek(outFile, -offset, SEEK_CUR); done = 0; for (i = 0; i < SCALE_BLOCK; i++) { fread(pcm_sample, 2, samplesPerSlot, outFile); out_fifo(pcm_sample, num, fr_ps, done, outFile, psampFrames); } } else{ /* mute the frame */ temp = (short*) pcm_sample; done = 0; for (i = 0; i < 2*3*SBLIMIT; i++) *temp++ = MUTE; /* MUTE value is in decoder.h */ for (i = 0; i < SCALE_BLOCK; i++) out_fifo(pcm_sample, num, fr_ps, done, outFile, psampFrames); } }