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

📄 mpeg2dec.c

📁 uclinux下s3c4510B CPU播放mp3 C程序
💻 C
字号:
/*------------------------------------------------------------------------------    File    :   MPEG2DEC.c    Author  :   St閜hane TAVENARD    $VER:   MPEG2DEC.c  0.3  (23/05/1997)    (C) Copyright 1997-1997 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   |23/02/1997| Initial revision                                     ST    1   |31/03/1997| First Aminet release                                 ST    2   |24/04/1997| Check forbidden values                               ST    3   |23/05/1997| Added MPEGDEC_ERR_xxx                                ST    ------------------------------------------------------------------------    MPEG layer II decoding functions------------------------------------------------------------------------------*/#include "defs.h"#include "bitstr.h"#include "mpegaud.h"#include "mpegtab.h"#include "mpegsub.h"#include "mpegdec.h"#include "mpeg2dec.h"static int MPEG2_decode_bitalloc( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the bit allocations of MPEG II stream   Return 0 if Ok*/{   INT16 sb;   INT16 *bal0, *bal1;   INT16 bits;   register INT16 ba;   BITSTREAM *bs = mps->bitstream;   bal0 = &mps->bit_alloc[ 0 ][ 0 ];   if( mps->stereo ) {      bal1 = &mps->bit_alloc[ 1 ][ 0 ];      for( sb=0; sb<mps->jsbound; sb++ ) {         bits = mps->alloc[ sb ][ 0 ];         ba = (INT16)BSTR_read_bits( bs, bits );         if( ba ) {  // #2            ba = mps->alloc[ sb ][ ba ];            if( !ba ) return MPEGDEC_ERR_BADFRAME;            *bal0++ = ba;         }         else *bal0++ = 0;         ba = (INT16)BSTR_read_bits( bs, bits );         if( ba ) {  // #2            ba = mps->alloc[ sb ][ ba ];            if( !ba ) return MPEGDEC_ERR_BADFRAME;            *bal1++ = ba;         }         else *bal1++ = 0;      }      for( ; sb<mps->sblimit; sb++ ) {         bits = mps->alloc[ sb ][ 0 ];         ba = (INT16)BSTR_read_bits( bs, bits );         if( ba ) {  // #2            ba = mps->alloc[ sb ][ ba ];            if( !ba ) return MPEGDEC_ERR_BADFRAME;            *bal0 = ba;         }         else *bal0 = 0;         *bal1++ = *bal0++;      }   }   else {      for( sb=0; sb<mps->sblimit; sb++ ) {         ba = (INT16)BSTR_read_bits( bs, mps->alloc[ sb ][ 0 ] );         if( ba ) {  // #2            ba = mps->alloc[ sb ][ ba ];            if( !ba ) return MPEGDEC_ERR_BADFRAME;            *bal0++ = ba;         }         else *bal0++ = 0;      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG2_decode_bitalloc */#ifdef MPEGAUD_INT#define COEFF_TYPE INT32#define COEFF_BITS 15#define COEFF_MULT( c, m ) (((c) * (m))>>(COEFF_BITS+MPEGTAB_MULT_BITS-MPEGAUD_SCALE_BITS))// Precalc of 2*2^COEFF_BITS/(2^(k+1)-1)  k:0..15// Rounded to lower valuestatic const COEFF_TYPE coeff[ 16 ] = {   0, 21845, 9362, 4369, 2114, 1040, 516, 257,   128, 64, 32, 16, 8, 4, 2, 1};#else#define COEFF_MULT( c, m ) ((c) * (m))// Precalc of 2/(2^(k+1)-1)  k:0..15static const REAL coeff[ 16 ] = {   (REAL)2.0,            (REAL)0.6666666667,   (REAL)0.2857142857,   (REAL)0.1333333333,   (REAL)0.06451612903,  (REAL)0.03174603175,  (REAL)0.0157480315,   (REAL)7.843137255e-3,   (REAL)3.913894325e-3, (REAL)1.955034213e-3, (REAL)9.770395701e-4, (REAL)4.884004884e-4,   (REAL)2.441704310e-4, (REAL)1.220777635e-4, (REAL)6.103701895e-5, (REAL)3.051804379e-5};#endifstatic int MPEG2_decode_scale( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the scales of MPEG II stream   Return 0 if Ok*/{   INT16 sb, ch, ba;   INT16 *bal0, *bal1;   INT16 *scf0, *scf1;   MPEGAUD_SCALE_TYPE *sca;   MPEGAUD_SCALE_TYPE sc, co;   BITSTREAM *bs = mps->bitstream;   bal0 = &mps->bit_alloc[ 0 ][ 0 ];   scf0 = &mps->scfsi[ 0 ][ 0 ];   if( mps->stereo ) {      bal1 = &mps->bit_alloc[ 1 ][ 0 ];      scf1 = &mps->scfsi[ 1 ][ 0 ];      for( sb=0; sb<mps->sblimit; sb++ ) {         if( *bal0++ ) *scf0++ = (INT16)BSTR_read_bits( bs, 2 );         else          *scf0++ = 0;         if( *bal1++ ) *scf1++ = (INT16)BSTR_read_bits( bs, 2 );         else          *scf1++ = 0;      }   }   else {      for( sb=0; sb<mps->sblimit; sb++ ) {         if( *bal0++ ) *scf0++ = (INT16)BSTR_read_bits( bs, 2 );         else          *scf0++ = 0;      }   }MPEGAUD_CHECK_DEMO;   for( sb=0; sb<mps->sblimit; sb++ ) {      sca = &mps->scale[ 0 ][ 0 ][ sb ];      for( ch=0; ch<mps->channels; ch++ ) {         ba = mps->bit_alloc[ ch ][ sb ];         if( ba ) {            switch( ba & 0x30 ) {               case 0x00: // No grouping                  co = coeff[ ba ];                  break;#ifdef MPEGAUD_INT               case 0x10: // Grouping 3/3/3                  co = 21845;                  break;               case 0x20: // Grouping 5/5/5                  co = 13107;                  break;               default:   // Grouping 9/9/9                  co = 7281;                  break;#else               case 0x10: // Grouping 3/3/3                  co = (MPEGAUD_SCALE_TYPE)(2.0/3.0);                  break;               case 0x20: // Grouping 5/5/5                  co = (MPEGAUD_SCALE_TYPE)(2.0/5.0);                  break;               default:   // Grouping 9/9/9                  co = (MPEGAUD_SCALE_TYPE)(2.0/9.0);                  break;#endif            }            switch( mps->scfsi[ ch ][ sb ] ) {                case 0 : // All three scale factors transmitted                    *sca = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    sca += MPA_SBLIMIT;                    *sca = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    sca += MPA_SBLIMIT;                    *sca = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    sca += MPA_SBLIMIT;                    break;                case 1 : // Scale factor 1 & 3 transmitted                    sc = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    *sca = sc; sca += MPA_SBLIMIT;                    *sca = sc; sca += MPA_SBLIMIT;                    *sca = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    sca += MPA_SBLIMIT;                    break;                case 3 : // Scale factor 1 & 2 transmitted                    *sca = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    sca += MPA_SBLIMIT;                    sc = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    *sca = sc; sca += MPA_SBLIMIT;                    *sca = sc; sca += MPA_SBLIMIT;                    break;                case 2 : // Only one scale factor transmitted                    sc = COEFF_MULT( co, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );                    *sca = sc; sca += MPA_SBLIMIT;                    *sca = sc; sca += MPA_SBLIMIT;                    *sca = sc; sca += MPA_SBLIMIT;                    break;                default :                    break;            }         }         else {            *sca = (MPEGAUD_SCALE_TYPE)0; sca += MPA_SBLIMIT;            *sca = (MPEGAUD_SCALE_TYPE)0; sca += MPA_SBLIMIT;            *sca = (MPEGAUD_SCALE_TYPE)0; sca += MPA_SBLIMIT;         }      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG2_decode_scale */#ifdef MPEGAUD_INT#define FRACT_MULT( sc, sa ) (((sc) * (sa))>>(MPEGAUD_SCALE_BITS-MPEGAUD_FRACT_BITS))#else#define FRACT_MULT( sc, sa ) ((sc) * (sa))#endifstatic int MPEG2_read_samples( MPA_STREAM *mps, INT16 scb )/*--------------------------------------------------------------------------   Read the samples of MPEG II stream & dequantize   Return 0 if Ok*/{   static UINT16 c3[ 32 ];   static UINT16 c5[ 128 ];   static UINT16 c9[ 1024 ];   static BOOL init = FALSE;   INT16 sb, ch;   INT16 ba, k;   UINT16 c;   INT32 k2, s0, s1, s2;   MPEGAUD_SCALE_TYPE m;   MPEGAUD_FRACT_TYPE *fra;   BITSTREAM *bs = mps->bitstream;   if( !init ) {      init = TRUE;      for( k=0; k<32; k++ ) {         c = k;         c3[ k ] = (UINT16)(c % 3);         c3[ k ] |= ((c /= 3) % 3)<<2;         c3[ k ] |= ((c /= 3) % 3)<<4;      }      for( k=0; k<128; k++ ) {         c = k;         c5[ k ] = (UINT16)(c % 5);         c5[ k ] |= ((c /= 5) % 5)<<4;         c5[ k ] |= ((c /= 5) % 5)<<8;      }      for( k=0; k<1024; k++ ) {         c = k;         c9[ k ] = (UINT16)(c % 9);         c9[ k ] |= ((c /= 9) % 9)<<4;         c9[ k ] |= ((c /= 9) % 9)<<8;      }   }MPEGAUD_CHECK_DEMO;   scb >>= 2;   for( sb=0; sb<mps->sblimit; sb++ ) {      fra = &mps->fraction[ 0 ][ 0 ][ sb ];      for( ch=0; ch<mps->channels; ch++ ) {MPEGAUD_CHECK_DEMO;         ba = mps->bit_alloc[ ch ][ sb ];         m = mps->scale[ ch ][ scb ][ sb ];         if( ba ) {            k = (INT16)(ba & 0x0F);            c = (UINT16)BSTR_read_bits( bs, k+1 );            switch( ba & 0x30 ) {                case 0x00: // No grouping                   k2 = 1 - (1<<k);                   s0 = k2 + c;                   s1 = k2 + BSTR_read_bits( bs, k+1 );                   s2 = k2 + BSTR_read_bits( bs, k+1 );                   break;                case 0x10:                   c = c3[ c ];                   s0 = (c & 0x03) - 1;                   s1 = ((c>>2) & 0x03) - 1;                   s2 = ((c>>4) & 0x03) - 1;                   break;                case 0x20:                   c = c5[ c ];                   s0 = (c & 0x000F) - 2;                   s1 = ((c>>4) & 0x000F) - 2;                   s2 = ((c>>8) & 0x000F) - 2;                   break;               default:                   c = c9[ c ];                   s0 = (c & 0x000F) - 4;                   s1 = ((c>>4) & 0x000F) - 4;                   s2 = ((c>>8) & 0x000F) - 4;                   break;            }            *fra = FRACT_MULT( m, s0 ); fra += MPA_SBLIMIT;            *fra = FRACT_MULT( m, s1 ); fra += MPA_SBLIMIT;            *fra = FRACT_MULT( m, s2 ); fra += MPA_SBLIMIT;            if( sb >= mps->jsbound && (mps->stereo) ) {               m = mps->scale[ 1 ][ scb ][ sb ];               *fra = FRACT_MULT( m, s0 ); fra += MPA_SBLIMIT;               *fra = FRACT_MULT( m, s1 ); fra += MPA_SBLIMIT;               *fra = FRACT_MULT( m, s2 ); // fra += MPA_SBLIMIT; Remove becoz of break !               break;            }         }         else {            *fra = (MPEGAUD_FRACT_TYPE)0; fra += MPA_SBLIMIT;            *fra = (MPEGAUD_FRACT_TYPE)0; fra += MPA_SBLIMIT;            *fra = (MPEGAUD_FRACT_TYPE)0; fra += MPA_SBLIMIT;            if( sb >= mps->jsbound && (mps->stereo) ) {               *fra = (MPEGAUD_FRACT_TYPE)0; fra += MPA_SBLIMIT;               *fra = (MPEGAUD_FRACT_TYPE)0; fra += MPA_SBLIMIT;               *fra = (MPEGAUD_FRACT_TYPE)0; // fra += MPA_SBLIMIT; Remove becoz of break !               break;            }         }      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG2_read_samples */int MPEG2_reset( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Reset the decoder*/{   if( !mps ) return MPEGDEC_ERR_MEM;   return MPEGDEC_ERR_NONE;} /* MPEG2_reset */INT32 MPEG2_decode_frame( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the current frame   Return # of decoded samples*/{   INT16 scb;   INT16 ch, gr;   INT16 pcm_offset = 0;   INT16 pcm_count = 0;   INT16 channels = (INT16)((mps->force_mono)?1:mps->channels);   int err;MPEGAUD_CHECK_DEMO;   err = MPEG2_decode_bitalloc( mps );   if( err ) return err;   err = MPEG2_decode_scale( mps );   if( err ) return err;   for( scb=0; scb<MPA_SCALE_BLOCK; scb++ ) {      err = MPEG2_read_samples( mps, scb );      if( err ) return err;      for( gr=0; gr<MPA_GROUPS; gr++ ) {         for( ch=0; ch<channels; ch++ ) {            pcm_count = MPEGSUB_synthesis( mps->mpegsub, &mps->fraction[ch][gr][0],                                           ch, &mps->pcm[ ch ][ pcm_offset ] );         }         pcm_offset += pcm_count;      }   }   return (INT32)pcm_offset;} /* MPEG2_decode_frame */

⌨️ 快捷键说明

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