www.pudn.com > mp3_source.rar > decode.c
#include#include #include "common.h" #include "decode.h" #include "huffman.h" void decode_info(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); } void III_get_side_info(Bit_stream_struc *bs, III_side_info_t *si, frame_params *fr_ps) { int ch, gr, i; int stereo = fr_ps->stereo; si->main_data_begin = getbits(bs, 9); if (stereo == 1) si->private_bits = getbits(bs,5); else si->private_bits = getbits(bs,3); for (ch=0; ch ch[ch].scfsi[i] = get1bit(bs); for (gr=0; gr<2; gr++) { for (ch=0; ch ch[ch].gr[gr].part2_3_length = getbits(bs, 12); si->ch[ch].gr[gr].big_values = getbits(bs, 9); si->ch[ch].gr[gr].global_gain = getbits(bs, 8); si->ch[ch].gr[gr].scalefac_compress = getbits(bs, 4); si->ch[ch].gr[gr].window_switching_flag = get1bit(bs); if (si->ch[ch].gr[gr].window_switching_flag) { si->ch[ch].gr[gr].block_type = getbits(bs, 2); si->ch[ch].gr[gr].mixed_block_flag = get1bit(bs); for (i=0; i<2; i++) si->ch[ch].gr[gr].table_select[i] = getbits(bs, 5); for (i=0; i<3; i++) si->ch[ch].gr[gr].subblock_gain[i] = getbits(bs, 3); /* Set region_count parameters since they are implicit in this case. */ if (si->ch[ch].gr[gr].block_type == 0) { printf("Side info bad: block_type == 0 in split block.\n"); exit(0); } else if (si->ch[ch].gr[gr].block_type == 2 && si->ch[ch].gr[gr].mixed_block_flag == 0) si->ch[ch].gr[gr].region0_count = 8; /* MI 9; */ else si->ch[ch].gr[gr].region0_count = 7; /* MI 8; */ si->ch[ch].gr[gr].region1_count = 20 - si->ch[ch].gr[gr].region0_count; } else { for (i=0; i<3; i++) si->ch[ch].gr[gr].table_select[i] = getbits(bs, 5); si->ch[ch].gr[gr].region0_count = getbits(bs, 4); si->ch[ch].gr[gr].region1_count = getbits(bs, 3); si->ch[ch].gr[gr].block_type = 0; } si->ch[ch].gr[gr].preflag = get1bit(bs); si->ch[ch].gr[gr].scalefac_scale = get1bit(bs); si->ch[ch].gr[gr].count1table_select = get1bit(bs); } } } struct { int l[5]; int s[3]; } sfbtable = { {0, 6, 11, 16, 21}, {0, 6, 12} }; int slen[2][16]={ {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} }; struct { int l[23]; int s[14]; } sfBandIndex[3]= { {{0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}, {0,4,8,12,16,22,30,40,52,66,84,106,136,192}}, {{0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}, {0,4,8,12,16,22,28,38,50,64,80,100,126,192}}, {{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}, {0,4,8,12,16,22,30,42,58,78,104,138,180,192}} }; void III_get_scale_factors(III_scalefac_t *scalefac, III_side_info_t *si, int gr, int ch, frame_params *fr_ps) { int sfb, i, window; struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]); if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { /* MIXED */ /* NEW - ag 11/25 */ for (sfb = 0; sfb < 8; sfb++) (*scalefac)[ch].l[sfb] = hgetbits( slen[0][gr_info->scalefac_compress]); for (sfb = 3; sfb < 6; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[0][gr_info->scalefac_compress]); for (sfb = 6; sfb < 12; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[1][gr_info->scalefac_compress]); for (sfb=12,window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = 0; } else { /* SHORT*/ for (i=0; i<2; i++) for (sfb = sfbtable.s[i]; sfb < sfbtable.s[i+1]; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[i][gr_info->scalefac_compress]); for (sfb=12,window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = 0; } } else { /* LONG types 0,1,3 */ for (i=0; i<4; i++) { if ((si->ch[ch].scfsi[i] == 0) || (gr == 0)) for (sfb = sfbtable.l[i]; sfb < sfbtable.l[i+1]; sfb++) (*scalefac)[ch].l[sfb] = hgetbits( slen[(i<2)?0:1][gr_info->scalefac_compress]); } (*scalefac)[ch].l[22] = 0; } } /* Already declared in huffman.c struct huffcodetab ht[HTN]; */ int huffman_initialized = FALSE; void initialize_huffman() { FILE *fi; if (huffman_initialized) return; if (!(fi = OpenTableFile("huffdec.txt") )) { printf("Please check huffman table 'huffdec.txt'\n"); exit(1); } if (fi==NULL) { fprintf(stderr,"decoder table open error\n"); exit(3); } if (read_decoder_table(fi) != HTN) { fprintf(stderr,"decoder table read error\n"); exit(4); } huffman_initialized = TRUE; } void III_hufman_decode(long int is[SBLIMIT][SSLIMIT], III_side_info_t *si, int ch, int gr, int part2_start, frame_params *fr_ps) { int i, x, y; int v, w; struct huffcodetab *h; int region1Start; int region2Start; int bt = (*si).ch[ch].gr[gr].window_switching_flag && ((*si).ch[ch].gr[gr].block_type == 2); initialize_huffman(); /* Find region boundary for short block case. */ if ( ((*si).ch[ch].gr[gr].window_switching_flag) && ((*si).ch[ch].gr[gr].block_type == 2) ) { /* Region2. */ region1Start = 36; /* sfb[9/3]*3=36 */ region2Start = 576; /* No Region2 for short block case. */ } else { /* Find region boundary for long block case. */ region1Start = sfBandIndex[fr_ps->header->sampling_frequency] .l[(*si).ch[ch].gr[gr].region0_count + 1]; /* MI */ region2Start = sfBandIndex[fr_ps->header->sampling_frequency] .l[(*si).ch[ch].gr[gr].region0_count + (*si).ch[ch].gr[gr].region1_count + 2]; /* MI */ } /* Read bigvalues area. */ for (i=0; i<(*si).ch[ch].gr[gr].big_values*2; i+=2) { if (i part2_start + (*si).ch[ch].gr[gr].part2_3_length) { i -=4; rewindNbits(hsstell()-part2_start - (*si).ch[ch].gr[gr].part2_3_length); } /* Dismiss stuffing Bits */ if ( hsstell() < part2_start + (*si).ch[ch].gr[gr].part2_3_length ) hgetbits( part2_start + (*si).ch[ch].gr[gr].part2_3_length - hsstell()); /* Zero out rest. */ for (; i header->sampling_frequency; int stereo = fr_ps->stereo; int next_cb_boundary, cb_begin, cb_width, sign; /* choose correct scalefactor band per block type, initalize boundary */ if (gr_info->window_switching_flag && (gr_info->block_type == 2) ) if (gr_info->mixed_block_flag) next_cb_boundary=sfBandIndex[sfreq].l[1]; /* LONG blocks: 0,1,3 */ else { next_cb_boundary=sfBandIndex[sfreq].s[1]*3; /* pure SHORT block */ cb_width = sfBandIndex[sfreq].s[1]; cb_begin = 0; } else next_cb_boundary=sfBandIndex[sfreq].l[1]; /* LONG blocks: 0,1,3 */ /* apply formula per block type */ for (sb=0 ; sb < SBLIMIT ; sb++) { for (ss=0 ; ss < SSLIMIT ; ss++) { if ( (sb*18)+ss == next_cb_boundary) { /* Adjust critical band boundary */ if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { if (((sb*18)+ss) == sfBandIndex[sfreq].l[8]) { next_cb_boundary=sfBandIndex[sfreq].s[4]*3; cb = 3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } else if (((sb*18)+ss) < sfBandIndex[sfreq].l[8]) next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1]; else { next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1]*3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } } else { next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1]*3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } } else /* long blocks */ next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1]; } /* Compute overall (global) scaling. */ xr[sb][ss] = pow( 2.0 , (0.25 * (gr_info->global_gain - 210.0))); /* Do long/short dependent scaling operations. */ if (gr_info->window_switching_flag && ( ((gr_info->block_type == 2) && (gr_info->mixed_block_flag == 0)) || ((gr_info->block_type == 2) && gr_info->mixed_block_flag && (sb >= 2)) )) { xr[sb][ss] *= pow(2.0, 0.25 * -8.0 * gr_info->subblock_gain[(((sb*18)+ss) - cb_begin)/cb_width]); xr[sb][ss] *= pow(2.0, 0.25 * -2.0 * (1.0+gr_info->scalefac_scale) * (*scalefac)[ch].s[(((sb*18)+ss) - cb_begin)/cb_width][cb]); } else { /* LONG block types 0,1,3 & 1st 2 subbands of switched blocks */ xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info->scalefac_scale) * ((*scalefac)[ch].l[cb] + gr_info->preflag * pretab[cb])); } /* Scale quantized value. */ sign = (is[sb][ss]<0) ? 1 : 0; xr[sb][ss] *= pow( (double) abs(is[sb][ss]), ((double)4.0/3.0) ); if (sign) xr[sb][ss] = -xr[sb][ss]; } } } void III_reorder(double xr[SBLIMIT][SSLIMIT], double ro[SBLIMIT][SSLIMIT], struct gr_info_s *gr_info, frame_params *fr_ps) { int sfreq=fr_ps->header->sampling_frequency; int sfb, sfb_start, sfb_lines; int sb, ss, window, freq, src_line, des_line; for(sb=0;sb window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { /* NO REORDER FOR LOW 2 SUBBANDS */ for (sb=0 ; sb < 2 ; sb++) for (ss=0 ; ss < SSLIMIT ; ss++) { ro[sb][ss] = xr[sb][ss]; } /* REORDERING FOR REST SWITCHED SHORT */ for(sfb=3,sfb_start=sfBandIndex[sfreq].s[3], sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start; sfb < 13; sfb++,sfb_start=sfBandIndex[sfreq].s[sfb], (sfb_lines=sfBandIndex[sfreq].s[sfb+1] - sfb_start)) for(window=0; window<3; window++) for(freq=0;freq header->sampling_frequency; int stereo = fr_ps->stereo; int ms_stereo = (fr_ps->header->mode == MPG_MD_JOINT_STEREO) && (fr_ps->header->mode_ext & 0x2); int i_stereo = (fr_ps->header->mode == MPG_MD_JOINT_STEREO) && (fr_ps->header->mode_ext & 0x1); int sfb; int i,j,sb,ss,ch,is_pos[576]; double is_ratio[576]; /* intialization */ for ( i=0; i<576; i++ ) is_pos[i] = 7; if ((stereo == 2) && i_stereo ) { if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if( gr_info->mixed_block_flag ) { int max_sfb = 0; for ( j=0; j<3; j++ ) { int sfbcnt; sfbcnt = 2; for( sfb=12; sfb >=3; sfb-- ) { int lines; lines = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + (j+1) * lines - 1; while ( lines > 0 ) { if ( xr[1][i/SSLIMIT][i%SSLIMIT] != 0.0 ) { sfbcnt = sfb; sfb = -10; lines = -10; } lines--; i--; } } sfb = sfbcnt + 1; if ( sfb > max_sfb ) max_sfb = sfb; while( sfb<12 ) { sb = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + j * sb; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].s[j][sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } sfb++; } sb = sfBandIndex[sfreq].s[11]-sfBandIndex[sfreq].s[10]; sfb = 3*sfBandIndex[sfreq].s[10] + j * sb; sb = sfBandIndex[sfreq].s[12]-sfBandIndex[sfreq].s[11]; i = 3*sfBandIndex[sfreq].s[11] + j * sb; for ( ; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } if ( max_sfb <= 3 ) { i = 2; ss = 17; sb = -1; while ( i >= 0 ) { if ( xr[1][i][ss] != 0.0 ) { sb = i*18+ss; i = -1; } else { ss--; if ( ss < 0 ) { i--; ss = 17; } } } i = 0; while ( sfBandIndex[sfreq].l[i] <= sb ) i++; sfb = i; i = sfBandIndex[sfreq].l[i]; for ( ; sfb<8; sfb++ ) { sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb]; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].l[sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } } } } else { for ( j=0; j<3; j++ ) { int sfbcnt; sfbcnt = -1; for( sfb=12; sfb >=0; sfb-- ) { int lines; lines = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + (j+1) * lines - 1; while ( lines > 0 ) { if ( xr[1][i/SSLIMIT][i%SSLIMIT] != 0.0 ) { sfbcnt = sfb; sfb = -10; lines = -10; } lines--; i--; } } sfb = sfbcnt + 1; while( sfb<12 ) { sb = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + j * sb; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].s[j][sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } sfb++; } sb = sfBandIndex[sfreq].s[11]-sfBandIndex[sfreq].s[10]; sfb = 3*sfBandIndex[sfreq].s[10] + j * sb; sb = sfBandIndex[sfreq].s[12]-sfBandIndex[sfreq].s[11]; i = 3*sfBandIndex[sfreq].s[11] + j * sb; for ( ; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } } } else { i = 31; ss = 17; sb = 0; while ( i >= 0 ) { if ( xr[1][i][ss] != 0.0 ) { sb = i*18+ss; i = -1; } else { ss--; if ( ss < 0 ) { i--; ss = 17; } } } i = 0; while ( sfBandIndex[sfreq].l[i] <= sb ) i++; sfb = i; i = sfBandIndex[sfreq].l[i]; for ( ; sfb<21; sfb++ ) { sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb]; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].l[sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } } sfb = sfBandIndex[sfreq].l[20]; for ( sb = 576 - sfBandIndex[sfreq].l[21]; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } } for(ch=0;ch<2;ch++) for(sb=0;sb window_switching_flag && (gr_info->block_type == 2) && !gr_info->mixed_block_flag ) return; if ( gr_info->window_switching_flag && gr_info->mixed_block_flag && (gr_info->block_type == 2)) sblim = 1; else sblim = SBLIMIT-1; /* 31 alias-reduction operations between each pair of sub-bands */ /* with 8 butterflies between each pair */ for(sb=0;sb window_switching_flag && gr_info->mixed_block_flag && (sb < 2)) ? 0 : gr_info->block_type; inv_mdct( fsIn, rawout, bt); /* overlap addition */ for(ss=0; ss = 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(double window[HAN_SIZE]) { int i,j[4]; FILE *fp; double f[4]; char t[150]; if (!(fp = OpenTableFile("dewindow.txt") )) { printf("Please check synthesis window table 'dewindow.txt'\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 (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 *filter; typedef double BB[2][2*HAN_SIZE]; static BB *buf; static int bufOffset[2] = {64,64}; static double *window; int clip = 0; /* count & return how many samples clipped */ if (init) { buf = (BB *) mem_alloc(sizeof(BB),"BB"); filter = (NN *) mem_alloc(sizeof(NN), "NN"); create_syn_filter(*filter); window = (double *) mem_alloc(sizeof(double) * HAN_SIZE, "WIN"); read_syn_window(window); init = 0; } /* if (channel == 0) */ bufOffset[channel] = (bufOffset[channel] - 64) & 0x3ff; bufOffsetPtr = &((*buf)[channel][bufOffset[channel]]); 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[channel]) & 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(short pcm_sample[2][SSLIMIT][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;i bitrate_index]) / s_freq[fr_ps.header->sampling_frequency]; if (fr_ps.header->padding) nSlots++; nSlots -= 4; if (fr_ps.header->error_protection) nSlots -= 2; if (fr_ps.stereo == 1) nSlots -= 17; else nSlots -=32; return(nSlots); }