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

📄 mpeg1dec.c

📁 Application (fix point) for playing MP3 data on embedded systems. mp3play is designed to be able to
💻 C
字号:
/*------------------------------------------------------------------------------    File    :   MPEG1DEC.c    Author  :   St閜hane TAVENARD    $VER:   MPEG1DEC.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   |20/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 I decoding functions------------------------------------------------------------------------------*/#include "defs.h"#include "bitstr.h"#include "mpegaud.h"#include "mpegtab.h"#include "mpegsub.h"#include "mpegdec.h"#include "mpeg1dec.h"static int MPEG1_decode_bitalloc( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the bit allocations of MPEG I stream   Return 0 if Ok*/{   INT16 sb;   INT16 *bal0, *bal1;   register INT16 value;   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++ ) {         value = (INT16)BSTR_read_bits( bs, 8 );         if( ((value & 0xF0) == 0xF0) || ((value & 0x0F) == 0x0F) ) return MPEGDEC_ERR_BADFRAME; // #2         *bal0++ = (value >> 4) & 0xF;         *bal1++ = value & 0xF;      }      for( ; sb<MPA_SBLIMIT; sb++ ) {         *bal0 = BSTR_read_bits( bs, 4 );         if( *bal0 == 0xF ) return MPEGDEC_ERR_BADFRAME; // #2         *bal1++ = *bal0++;      }   }   else {      for( sb=0; sb<MPA_SBLIMIT; sb++ ) {         value = BSTR_read_bits( bs, 4 );         if( value == 0x0F ) return MPEGDEC_ERR_BADFRAME; // #2         *bal0++ = value;      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG1_decode_bitalloc */#ifdef MPEGAUD_INT#define COEFF_TYPE INT32#define COEFF_BITS 15#define COEFF_MULTK( k, m ) ((coeff[ k ] * (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_MULTK( k, m ) (coeff[ k ] * (m))// Precalc of 2/(2^(k+1)-1)  k:0..15static const REAL coeff[ 16 ] = {   2.0, 0.6666666667, 0.2857142857, 0.1333333333,   0.06451612903, 0.03174603175, 0.0157480315, 7.843137255e-3,   3.913894325e-3, 1.955034213e-3, 9.770395701e-4, 4.884004884e-4,   2.441704310e-4, 1.220777635e-4, 6.103701895e-5, 3.051804379e-5};#endifstatic int MPEG1_decode_scale( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the scales of MPEG I stream   Return 0 if Ok*/{   INT16 sb;   INT16 *bal0, *bal1;   MPEGAUD_SCALE_TYPE *sca0, *sca1;   INT16 k;   BITSTREAM *bs = mps->bitstream;   sca0 = &mps->scale[ 0 ][ 0 ][ 0 ];   bal0 = &mps->bit_alloc[ 0 ][ 0 ];   if( mps->stereo ) {      bal1 = &mps->bit_alloc[ 1 ][ 0 ];      sca1 = &mps->scale[ 1 ][ 0 ][ 0 ];      for( sb=0; sb<MPA_SBLIMIT; sb++ ) {         k = *bal0++;         if( k ) *sca0++ = COEFF_MULTK( k, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );         else    *sca0++ = (MPEGAUD_SCALE_TYPE)0;         k = *bal1++;         if( k ) *sca1++ = COEFF_MULTK( k, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );         else    *sca1++ = (MPEGAUD_SCALE_TYPE)0;      }   }   else {      for( sb=0; sb<MPA_SBLIMIT; sb++ ) {         k = *bal0++;         if( k ) *sca0++ = COEFF_MULTK( k, MPT_multiple[ BSTR_read_bits( bs, 6 ) ] );         else    *sca0++ = (MPEGAUD_SCALE_TYPE)0;      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG1_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 MPEG1_read_samples( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Read the samples of MPEG I stream & dequantize   Return 0 if Ok*/{   INT16 *bal0, *bal1;   MPEGAUD_SCALE_TYPE *sca0, *sca1;   MPEGAUD_FRACT_TYPE *fra0, *fra1;   INT16 sb;   INT16 k;   INT32 s;   BITSTREAM *bs = mps->bitstream;   bal0 = &mps->bit_alloc[ 0 ][ 0 ];   sca0 = &mps->scale[ 0 ][ 0 ][ 0 ];   fra0 = &mps->fraction[ 0 ][ 0 ][ 0 ];   if( mps->stereo ) {      bal1 = &mps->bit_alloc[ 1 ][ 0 ];      sca1 = &mps->scale[ 1 ][ 0 ][ 0 ];      fra1 = &mps->fraction[ 1 ][ 0 ][ 0 ];      for( sb=0; sb<mps->jsbound; sb++ ) {         k = *bal0++;         if( k ) {            s = 1-(1<<k) + BSTR_read_bits( bs, k+1 );            *fra0++ = FRACT_MULT( *sca0, s );         }         else *fra0++ = (MPEGAUD_SCALE_TYPE)0;         sca0++;         k = *bal1++;         if( k ) {            s = 1-(1<<k) + BSTR_read_bits( bs, k+1 );            *fra1++ = FRACT_MULT( *sca1, s );         }         else *fra1++ = (MPEGAUD_SCALE_TYPE)0;         sca1++;      }      for( ; sb<MPA_SBLIMIT; sb++ ) {         k = *bal0++;         if( k ) {            s = 1-(1<<k) + BSTR_read_bits( bs, k+1 );            *fra0++ = FRACT_MULT( *sca0, s );            *fra1++ = FRACT_MULT( *sca1, s );         }         else *fra0++ = *fra1++ = (MPEGAUD_SCALE_TYPE)0;         sca0++;         sca1++;      }   }   else {      for( sb=0; sb<MPA_SBLIMIT; sb++ ) {         k = *bal0++;         if( k ) {            s = 1-(1<<k) + BSTR_read_bits( bs, k+1 );            *fra0++ = FRACT_MULT( *sca0, s );         }         else *fra0++ = (MPEGAUD_SCALE_TYPE)0;         sca0++;      }   }MPEGAUD_CHECK_DEMO;   return MPEGDEC_ERR_NONE;} /* MPEG1_read_samples */int MPEG1_reset( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Reset the decoder*/{   return MPEGDEC_ERR_NONE;} /* MPEG1_reset */INT32 MPEG1_decode_frame( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the current frame   Return # of decoded samples*/{   INT16 block;   INT16 ch;   INT16 pcm_offset = 0;   INT16 pcm_count = 0;   INT16 channels = (mps->force_mono)?1:mps->channels;   int err;MPEGAUD_CHECK_DEMO;   err = MPEG1_decode_bitalloc( mps );   if( err ) return err;   err = MPEG1_decode_scale( mps );   if( err ) return err;   for( block=0; block<MPA_SCALE_BLOCK; block++ ) {      err = MPEG1_read_samples( mps );      if( err ) return err;      for( ch=0; ch<channels; ch++ ) {         pcm_count = MPEGSUB_synthesis( mps->mpegsub, &mps->fraction[ch][0][0],                                        ch, &mps->pcm[ ch ][ pcm_offset ] );      }      pcm_offset += pcm_count;   }   return (INT32)pcm_offset;}

⌨️ 快捷键说明

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