⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg3dec.c

📁 Application (fix point) for playing MP3 data on embedded systems. mp3play is designed to be able to
💻 C
字号:
/*------------------------------------------------------------------------------    File    :   MPEG3DEC.c    Author  :   St閜hane TAVENARD    $VER:   MPEG3DEC.c  1.1  (24/05/1999)    (C) Copyright 1997-1999 St閜hane TAVENARD        All Rights Reserved  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.   This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.   You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    #Rev|   Date   |                      Comment    ----|----------|--------------------------------------------------------    0   |15/03/1997| Initial revision                                     ST    1   |31/03/1997| First aminet release                                 ST    2   |13/05/1997| Fixed bug in imdct_number                            ST    3   |23/05/1997| Added MPEGDEC_ERR_xxx                                ST    4   |27/05/1997| Added MPEGIMDCT                                      ST    5   |05/06/1997| FPU Optimized version                                ST    6   |07/06/1997| Use now BSTR_read_bytes & HUFF_fill_bytes            ST    7   |08/07/1997| Optimized dequantization for INT arithmetic          ST    8   |13/07/1997| Optimized mono_forced decoding                       ST    9   |14/07/1997| Optimized stereo function with nul bands             ST    10  |14/07/1997| Added MPEG3_get_nul_pos, optimized dequantization    ST    11  |24/05/1999| Suppressed all static vars to allow multi-decoding   ST    ------------------------------------------------------------------------    MPEG layer III decoding functions------------------------------------------------------------------------------*/#include <stdio.h>#include "defs.h"#include "bitstr.h"#include "mpegaud.h"#include "mpegtab.h"#include "mpegsub.h"#include "mpegimdc.h" // #4#if defined(ASM_OPTIMIZE) || defined(COLDFIRE_ASM_2)#ifdef MPEGAUD_INT#include "mpegsubb.h"#else#include "mpegsubf.h" // #5#endif#endif#include "mpegdec.h"#include "mpeg3dec.h"#include <math.h>#ifdef USE_RC4#include "rc4.h"#endifstatic int MPEG3_main_data_slots( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Return the main data slots of current MPEG III frame*/{   INT32 slots;   MPA_HEADER *h = &mps->header;   slots = ( 144000 * mps->bitrate ) / mps->sfreq;   if( h->ID == MPA_ID_1 ) { // MPEG1      if( mps->stereo ) slots -= 36;      else slots -= 21;   } else { // MPEG2      slots >>= 1;      if( mps->stereo ) slots -= 21;      else slots -= 13;   }   if( h->padding_bit ) slots++;   if( h->protection_bit ) slots -= 2;   return slots;} /* MPEG3_main_data_slots */static int MPEG3_decode_side_info( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the sideo info of MPEG III stream   Return 0 if Ok*/{   BITSTREAM *bs = mps->bitstream;   MPA_SIDE_INFO *si = &mps->side_info;   UINT16 ch, i, gr;   UINT16 gr_max, scf;   if( mps->header.ID == MPA_ID_1 ) { // MPEG1      gr_max = MPA_MAX_GRANULES;      scf = 4;      si->main_data_begin = BSTR_read_bits( bs, 9 );      if( mps->stereo ) si->private_bits = BSTR_read_bits( bs, 3 );      else si->private_bits = BSTR_read_bits( bs, 5 );      for( ch=0; ch<mps->channels; ch++ ) {         for( i=0; i<4; i++ ) si->ch[ ch ].scfsi[ i ] = BSTR_read_bit( bs );      }   }   else { // MPEG2 - LSF      gr_max = 1;      scf = 9;      si->main_data_begin = BSTR_read_bits( bs, 8 );      if( mps->stereo ) si->private_bits = BSTR_read_bits( bs, 2 );      else si->private_bits = BSTR_read_bits( bs, 1 );   }MPEGAUD_CHECK_DEMO;   for( gr=0; gr<gr_max; gr++ ) {      for( ch=0; ch<mps->channels; ch++ ) {         MPA_GRANULE_INFO *gi = &si->ch[ ch ].gr[ gr ];         gi->part2_3_length    = BSTR_read_bits( bs, 12 );         gi->big_values        = BSTR_read_bits( bs, 9 );         gi->global_gain       = BSTR_read_bits( bs, 8 );         gi->scalefac_compress = BSTR_read_bits( bs, scf );         gi->window_switching_flag = BSTR_read_bit( bs );#if 0	 printf("gi->part2_3_length: %08x\n", gi->part2_3_length);	 printf("gi->big_values: %08x\n", gi->big_values);	 printf("gi->global_gain: %08x\n", gi->global_gain);	 printf("gi->scalefac_compress: %08x\n", gi->scalefac_compress);	 printf("gi->window_switching_flag: %08x\n", gi->window_switching_flag);#endif         if( gi->window_switching_flag ) {            gi->block_type = BSTR_read_bits( bs, 2 );            gi->mixed_block_flag = BSTR_read_bit( bs );            for( i=0; i<2; i++ ) gi->table_select[ i ] = BSTR_read_bits( bs, 5 );            for( i=0; i<3; i++ ) gi->subblock_gain[ i ] = BSTR_read_bits( bs, 3 );            // Implicit regionX_count parameters setting            if( (gi->block_type == 2) && (!gi->mixed_block_flag) ) gi->region0_count = 8;            else gi->region0_count = 7;            gi->region1_count = 20 - gi->region0_count;         }         else {            for( i=0; i<3; i++ ) gi->table_select[ i ] = BSTR_read_bits( bs, 5 );            gi->region0_count = BSTR_read_bits( bs, 4 );            gi->region1_count = BSTR_read_bits( bs, 3 );            gi->block_type = 0;         }         if( mps->header.ID == MPA_ID_1 ) gi->preflag = BSTR_read_bit( bs );         gi->scalefac_scale = BSTR_read_bit( bs );         gi->count1table_select = BSTR_read_bit( bs );      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG3_decode_side_info */static const INT16 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}};static int MPEG3_decode_scale1( MPA_STREAM *mps, INT16 gr, INT16 ch )/*--------------------------------------------------------------------------   Decode the scales of MPEG1-III stream   Return 0 if Ok*/{   INT16 sfb, win;   MPA_GRANULE_INFO *gi = &mps->side_info.ch[ ch ].gr[ gr ];   MPA_SCALE_FAC3 *sf = &mps->scale_fac3[ ch ];   HUFFMAN *h = mps->huffman;   INT16 slen1 = slen[ 0 ][ gi->scalefac_compress ];   INT16 slen2 = slen[ 1 ][ gi->scalefac_compress ];   if( (gi->window_switching_flag) && (gi->block_type == 2) ) {      if( gi->mixed_block_flag ) { // Mixed block         for( sfb=0; sfb<8; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 );         for( sfb=3; sfb<6; sfb++ )            for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen1 );         for( sfb=6; sfb<12; sfb++ )            for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen2 );         sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0;      }      else { // Short blocks         for( sfb=0; sfb<6; sfb++ )            for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen1 );         for( sfb=6; sfb<12; sfb++ )            for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen2 );         sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0;      }   }   else { // Long blocks 0, 1 or 3      if( (mps->side_info.ch[ ch ].scfsi[ 0 ] == 0) || (gr == 0) ) {         for( sfb = 0; sfb < 6; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 );      }      if( (mps->side_info.ch[ ch ].scfsi[ 1 ] == 0) || (gr == 0) ) {         for( sfb = 6; sfb < 11; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 );      }      if( (mps->side_info.ch[ ch ].scfsi[ 2 ] == 0) || (gr == 0) ) {         for( sfb = 11; sfb < 16; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen2 );      }      if( (mps->side_info.ch[ ch ].scfsi[ 3 ] == 0) || (gr == 0) ) {         for( sfb = 16; sfb < 21; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen2 );      }      sf->l[ 21 ] = sf->l[ 22 ] = 0;   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG3_decode_scale1 */static const INT16 sfb_bt[ 6 ][ 3 ][ 4 ] = {   { {6,  5,  5, 5}, {9,  9,  9,  9}, {6,  9,  9,  9} },   { {6,  5,  7, 3}, {9,  9,  12, 6}, {6,  9,  12, 6} },   { {11, 10, 0, 0}, {18, 18, 0,  0}, {15, 18, 0,  0} },   { {7,  7,  7, 0}, {12, 12, 12, 0}, {6,  15, 12, 0} },   { {6,  6,  6, 3}, {12, 9,  9,  6}, {6,  12, 9,  6} },   { {8,  8,  5, 0}, {15, 12, 9,  0}, {6,  18, 9,  0} }};static int MPEG3_decode_scale2( MPA_STREAM *mps, INT16 gr, INT16 ch )/*--------------------------------------------------------------------------   Decode the scales of MPEG2-III stream   Return 0 if Ok*/{   INT16 i, j, k, sfb, win;   MPA_GRANULE_INFO *gi = &mps->side_info.ch[ ch ].gr[ gr ];   MPA_SCALE_FAC3 *sf = &mps->scale_fac3[ ch ];   HUFFMAN *h = mps->huffman;   INT16 block_type_number, block_number;   INT16 slen[ 4 ];   INT16 sfb_nb, len;   INT16 scalefac[ 36 ]; /* #11 suppressed static */   INT16 is_max[ 36 ]; /* #11 suppressed static *///memset( sf, 0, sizeof( MPA_SCALE_FAC3 ) );   block_type_number = 0;   if( gi->block_type == 2 ) block_type_number = (gi->mixed_block_flag)?2:1;MPEGAUD_CHECK_DEMO;   if( ( (mps->header.mode_extension == 1) || (mps->header.mode_extension == 3) ) &&       ( ch == 1 ) ) {      INT16 int_scalefac_comp = gi->scalefac_compress >> 1;      if( int_scalefac_comp < 180 ) {         slen[ 0 ] = int_scalefac_comp  / 36 ;         slen[ 1 ] = (INT16)(int_scalefac_comp % 36) / 6;         slen[ 2 ] = (INT16)(int_scalefac_comp % 36) % 6;         slen[ 3 ] = 0;         gi->preflag = 0;         block_number = 3;      }      else if( int_scalefac_comp < 244 ) {         slen[ 0 ] = ((INT16)(int_scalefac_comp - 180) % 64) >> 4;         slen[ 1 ] = ((INT16)(int_scalefac_comp - 180) % 16) >> 2;         slen[ 2 ] =  (INT16)(int_scalefac_comp - 180) % 4;         slen[ 3 ] = 0;         gi->preflag = 0;         block_number = 4;      }      else {         slen[ 0 ] = (INT16)(int_scalefac_comp - 244) / 3;         slen[ 1 ] = (INT16)(int_scalefac_comp - 244) % 3;         slen[ 2 ] = 0 ;         slen[ 3 ] = 0;         gi->preflag = 0;         block_number = 5;      }   }   else {      INT16 scalefac_comp = gi->scalefac_compress;      if( scalefac_comp < 400 ) {         slen[ 0 ] = (INT16)(scalefac_comp >> 4) / 5;         slen[ 1 ] = (INT16)(scalefac_comp >> 4) % 5;         slen[ 2 ] = (INT16)(scalefac_comp % 16) >> 2;         slen[ 3 ] = (INT16)(scalefac_comp % 4);         gi->preflag = 0;         block_number = 0;      }      else if( scalefac_comp  < 500 ) {         slen[ 0 ] = ((INT16)(scalefac_comp - 400) >> 2) / 5;         slen[ 1 ] = ((INT16)(scalefac_comp - 400) >> 2) % 5;         slen[ 2 ] =  (INT16)(scalefac_comp - 400) % 4;         slen[ 3 ] = 0;         gi->preflag = 0;         block_number = 1;      }      else {         slen[ 0 ] = (INT16)(scalefac_comp - 500) / 3;         slen[ 1 ] = (INT16)(scalefac_comp - 500) % 3;         slen[ 2 ] = 0;         slen[ 3 ] = 0;         gi->preflag = 1;         block_number = 2;      }   }   k = 0;   for( i=0; i<4; i++ ) {      sfb_nb = sfb_bt[ block_number ][ block_type_number ][ i ];      len = slen[ i ];      if( len ) {         for( j=0; j<sfb_nb; j++ ) {            scalefac[ k ] = HUFF_read_bits( h, len );            is_max[ k++ ] = (1<<len) - 1;         }      }      else {         for( j=0; j<sfb_nb; j++ ) {            scalefac[ k ] = 0;            is_max[ k++ ] = 0;         }      }   }   while( k < 36 ) scalefac[ k++ ] = 0;   k = 0;MPEGAUD_CHECK_DEMO;   if( (gi->window_switching_flag) && (gi->block_type == 2) ) {      if( gi->mixed_block_flag ) { // Mixed block// *** WARNING// *** WARNING  sfb<8 seems to be inexact, sfb<6 seems to be ok (? NO, conform to ISO/IEC)// *** WARNING         for( sfb=0; sfb<6; sfb++ ) {            sf->l[ sfb ] = scalefac[ k ];            mps->is_max_l[ sfb ] = is_max[ k++ ];         }         for( sfb=3; sfb<12; sfb++ ) {            for( win=0; win<3; win++ ) {               sf->s[ win ][ sfb ] = scalefac[ k ];               mps->is_max_s[ win ][ sfb ] = is_max[ k++ ];            }         }         sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0;      }      else { // Short blocks         for( sfb=0; sfb<12; sfb++ ) {            for( win=0; win<3; win++ ) {               sf->s[ win ][ sfb ] = scalefac[ k ];               mps->is_max_s[ win ][ sfb ] = is_max[ k++ ];            }         }         sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0;      }   }   else { // Long blocks 0, 1 or 3      for( sfb=0; sfb<21; sfb++ ) {         sf->l[ sfb ] = scalefac[ k ];         mps->is_max_l[ sfb ] = is_max[ k++ ];      }      sf->l[ 21 ] = sf->l[ 22 ] = 0;   }   return MPEGDEC_ERR_NONE;} /* MPEG3_decode_scale2 */// Note: o

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -