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

📄 mp3onlydec.c

📁 uclinux下s3c4510B CPU播放mp3 C程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------    File    :   MPEGDEC.C    Author  :   St閜hane TAVENARD    (C) Copyright 1997-1998 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   |19/02/1997| Initial revision                                     ST    1   |31/03/1997| First Aminet release                                 ST    2   |06/04/1997| Take care of MPEG2.5                                 ST    3   |24/04/1997| Added MPEGDEC_seek, MPEGDEC_time                     ST    4   |27/04/1997| Added freq_max in MPEGDEC_CTRL                       ST    5   |18/05/1997| Added tolerance in header sync, CTRL of first sync   ST    6   |22/05/1997| Added check_mpeg in MPEGDEC_CTRL                     ST    6   |22/05/1997| Added bitstream buffer size config in MPEGDEC_CTRL   ST    7   |23/05/1997| Added MPEGDEC_ERR_xxx                                ST    8   |27/05/1997| Added MPEGIMDCT                                      ST    9   |07/06/1997| Added synchronize                                    ST    10  |16/06/1997| Added need_sync                                      ST    11  |17/06/1997| Corrected MPEGDEC_seek                               ST    12  |03/07/1997| Corrected synchronization when error protection      ST    13  |06/07/1997| Use different setting for layer I & II and layer III ST    14  |15/07/1997| Added dec_quality                                    ST    15  |20/09/1997| Added MPEGDEC_find_sync                              ST    16  |26/03/1998| Modify synchronize for variable bitrates             ST    17  |16/06/1998| Enhanced synchronize for to keep first good frame    ST    18  |21/06/1998| Added MPEGDEC_scale                                  ST    19  |01/09/1999| Spawnd MP3 only version frmo mp3dec.c                RS    ------------------------------------------------------------------------    MPEG 3 only Audio decoder ...    -----------------------------------------------------------------------------*/#include "defs.h"#include "mpegaud.h"#include "mpeg3dec.h"#include "mpegdec.h"#include "mpegtab.h"#ifdef USE_RC4#include "rc4.h"#endif#define MPEGDEC_BITSTREAM_BUFFER_SIZE 16384 // #6 Now default buffer size#ifdef MPEGAUD_DEMOstatic frame_count = 0;#endifstatic int MPEGDEC_decode_header( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Decode the current Header   Return 0 if Ok*/{   MPA_HEADER *mph = &mps->header;   INT16 bitrate_per_channel;   INT16 table;   mps->bitrate = MPT_bitrate[ mph->ID ][ mph->layer -1 ][ mph->bitrate_index ];   if( mph->mode == MPA_MODE_MONO ) {      mps->stereo = FALSE;      mps->channels = 1;      bitrate_per_channel = mps->bitrate;   }   else {      mps->stereo = TRUE;      mps->channels = 2;      bitrate_per_channel = mps->bitrate>>1;   }   mps->sfreq = MPT_freq[ mph->ID ][ mph->sampling_frequency ];   if( !mps->sfreq ) return MPEGDEC_ERR_BADFRAME;   if( mph->half_freq ) mps->sfreq >>= 1; // #2   if( mph->layer == 2 ) {      if( mph->ID == MPA_ID_1 ) {         if( ( (mph->sampling_frequency == MPA_SAMP_48000) &&               (bitrate_per_channel >= 56) ) ||             ( (bitrate_per_channel >= 56) &&               (bitrate_per_channel <= 80) ) ) table = 0;         else if( (mph->sampling_frequency != MPA_SAMP_48000) &&                  (bitrate_per_channel >= 96) ) table = 1;         else if( (mph->sampling_frequency != MPA_SAMP_32000) &&                  (bitrate_per_channel <= 48) ) table = 2;         else table = 3;      }      else {         table = 4;      }      mps->sblimit = MPT_sblimit[ table ];      if( table != mps->current_table ) {         switch( table ) {            case 0: mps->alloc = MPT_alloc_0; break;            case 1: mps->alloc = MPT_alloc_1; break;            case 2: mps->alloc = MPT_alloc_2; break;            case 3: mps->alloc = MPT_alloc_3; break;            default: mps->alloc = MPT_alloc_4; break;         }         mps->current_table = table;// *** WARNING ***// Reset when sblimit changed (because some MPEG layer I inside layer II)         // reset fraction's         memset( mps->fraction, 0, MPA_MAX_CHANNELS * MPA_GROUPS * MPA_SBLIMIT * sizeof(MPEGAUD_FRACT_TYPE) );      }   }   else {      mps->sblimit = MPA_SBLIMIT;   }   if( mph->mode == MPA_MODE_JOINT_STEREO ) {      mps->jsbound = MPT_jsbound[ mph->layer - 1 ][ mph->mode_extension ];   }   else {      mps->jsbound = mps->sblimit;   }   return MPEGDEC_ERR_NONE;} /* MPEGDEC_decode_header */static int MPEGDEC_read_header( MPA_STREAM *mps, BOOL check )/*--------------------------------------------------------------------------   Read the next MPEG AUDIO Header   #5: check: check if it's an mpeg audio stream, ie begin with a sync word   Return MPEGDEC_ERR_EOF if end of stream reached.*/{   register UINT32 value;   register UINT32 header;   BITSTREAM *bs;   MPA_HEADER *mph;   UINT8 old_first; // #5   // #5   // We check: Sync is either 0xFFF or 0xFFE (MPEG 2.5)   //           Layer is not 4 (coded value is 0x0)   //           Bitrate index is not 0xF (forbidden)   //           Bitrate index is not 0x0 (free not supported)   //           Frequency index is not 0x3 (reserved)#define SYNC_VALID( v ) ( ((v & 0xFFE00000) == 0xFFE00000) &&\                          ((v & 0x00060000) != 0x00000000) &&\                          ((v & 0xF000) != 0xF000) &&\                          ((v & 0xF000) != 0x0000) &&\                          ((v & 0x0C00) != 0xC000) )   bs = mps->bitstream;   if( BSTR_end( bs ) ) return MPEGDEC_ERR_EOF;   mph = &mps->header;   // Header is: <Sync:12><ID:1><Lay:2><Prot:1>   //            <Rate:4><Freq:2><Pad:1><Priv:1>   //            <Mode:2><Ext:2><Copy:1><Orig:1><Emph:2>   // Total: 32 bits   // with <Sync> = 0xFFF for MPEG 1,2 <Sync> = 0xFFE for MPEG 2.5   // <Rate> can't be 0xF, so use it to skip leading 0xFF   // Seek to sync word   old_first = bs->bits; // #5: This could be the last byte read (not always !)   // Read first 24 bits   value = BSTR_read_byte( bs );   value <<= 8;   value |= BSTR_read_byte( bs );   value <<= 8;   value |= BSTR_read_byte( bs );   // Check if first sync is valid   value <<= 8;   if( SYNC_VALID( value ) ) { // Ok, first sync is valid      value |= BSTR_read_byte( bs );   }   else { // first sync not valid -> try to use previous byte (#5 tolerance !)      int loops = 16384; // #17      if( check ) return MPEGDEC_ERR_BADFRAME; // Not an MPEG Stream !      value >>= 8;      value |= old_first << 24; // use previous byte      while( !SYNC_VALID( value ) ) {         value <<= 8;         value |= BSTR_read_byte( bs );         if( BSTR_end( bs ) ) return MPEGDEC_ERR_EOF;         if( loops-- <=0 ) return MPEGDEC_ERR_BADFRAME; // #17      }   }   mph->header_pos = BSTR_pos( bs ) - 4; // #17 (header is 4 bytes long)   mph->half_freq = (value & 0x00100000) ? FALSE:TRUE; // #2   header = value;   mph->emphasis = header & 0x0003; header >>= 2;   mph->original = header & 0x0001; header >>= 1;   mph->copyright = header & 0x0001; header >>= 1;   mph->mode_extension = header & 0x0003; header >>= 2;   mph->mode = header & 0x0003; header >>= 2;   mph->private_bit = header & 0x0001; header >>= 1;   mph->padding_bit = header & 0x0001; header >>= 1;   mph->sampling_frequency = header & 0x0003; header >>= 2;   mph->bitrate_index = header & 0x000F; header >>= 4;   mph->protection_bit = (header & 0x0001) ? FALSE:TRUE; header >>= 1;   mph->layer = 4 - (header & 0x0003); header >>= 2;   mph->ID = header & 0x0001;   // Check for correct values   if( mph->bitrate_index == 0xF ) return MPEGDEC_ERR_BADFRAME; // Already checked in sync search   if( mph->sampling_frequency == 0x3 ) return MPEGDEC_ERR_BADFRAME;   if( mph->layer == 4 ) return MPEGDEC_ERR_BADFRAME;   if( mph->protection_bit ) mph->crc_check = BSTR_read_bits( bs, 16 );   return MPEGDEC_decode_header( mps );} /* MPEGDEC_read_header *//* #15 Begin */INT32 MPEGDEC_find_sync( INT8 *buffer, INT32 buffer_size )/*--------------------------------------------------------------------------   Find an mpeg synchronization pattern in a buffer   This function can be use to check if a file contains MPEG audio stream   Inputs: buffer = stream buffer to analyze           buffer_size = need to know top of buffer (must be >= 4)   Return the the sync position (>=0) or MPEGDEC_ERR_NO_SYNC if not found*/{   register INT32 index = 0;   register UINT32 value = 0;   register UINT8 *b;   b = (UINT8 *)buffer;   while( index < buffer_size ) {      value <<= 8;      value |= (UINT32)(*b++);      if( (index >= 3) && SYNC_VALID( value ) ) return (index - 3);      index++;   }   return MPEGDEC_ERR_NO_SYNC;}/* #15 End *//* #9 Begin */static int synchronize( MPA_STREAM *mps )/*--------------------------------------------------------------------------   Synchronize the bitstream   Return 0 if ok*/{#define MAX_TRIES 9   INT16 try = MAX_TRIES;   int status;   INT32 slots;   while( try-- ) {      status = MPEGDEC_read_header( mps, FALSE );      if( status == MPEGDEC_ERR_EOF ) return status;      if( status == MPEGDEC_ERR_NONE ) { // Header found         int bitrate, sfreq, layer, id;         MPA_HEADER *mph = &mps->header;         id = mph->ID;         layer = mph->layer;         sfreq = mps->sfreq;         bitrate = mps->bitrate;         // Calculate the number of slots between 2 headers         if( layer == 1 ) slots = 48000;         else slots = 144000;         if( (layer == 3) && (id == MPA_ID_2) ) slots >>= 1;         slots *= bitrate;         slots /= sfreq;         if( mph->padding_bit ) slots++;         // Now skip slots-4 bytes         if( mph->protection_bit ) slots -= 6; // #12         else slots -= 4;         while( slots-- ) BSTR_read_byte( mps->bitstream );         // Now check if header ok and same id, norm, (bitrate) and freq         status = MPEGDEC_read_header( mps, TRUE );         if( status == MPEGDEC_ERR_NONE ) {            if( (mph->ID == id) && (mph->layer == layer) &&//                (mps->sfreq == sfreq) && (mps->bitrate == bitrate) ) {                (mps->sfreq == sfreq) ) { // #16               // #17 Begin               int err;               err = BSTR_seek( mps->bitstream, mph->header_pos );               if( err ) return MPEGDEC_ERR_BADFRAME;               err = MPEGDEC_read_header( mps, TRUE );               return err;//               return MPEGDEC_ERR_NONE;               // #17 End            }         }         else if( status == MPEGDEC_ERR_EOF ) return status;      }   }   return MPEGDEC_ERR_BADFRAME;}/* #9 End */static void fill_info( MPEGDEC_STREAM *mpds )/*--------------------------------------------------------------------------   Fill the current MPEG Audio stream information*/{   MPA_STREAM *mps;   mps = (MPA_STREAM *)mpds->handle;   mpds->norm          = (mps->header.ID == MPA_ID_1)?1:2;   mpds->layer         = mps->header.layer;   mpds->mode          = mps->header.mode;   mpds->bitrate       = mps->bitrate;   mpds->frequency     = mps->sfreq;   mpds->channels      = mps->channels;   if( mps->bitrate ) mpds->ms_duration = mps->stream_size / (mps->bitrate>>3);   else mpds->ms_duration = 0;   mpds->private_bit   = (INT16)mps->header.private_bit;   mpds->copyright     = (INT16)mps->header.copyright;   mpds->original      = (INT16)mps->header.original;   mpds->dec_frequency = mps->sfreq / mps->freq_div;   mpds->dec_channels  = (mps->force_mono)?1:mpds->channels;   mpds->dec_quality   = mps->quality; // #14} /* fill_info */// #18 Beginint MPEGDEC_scale( MPEGDEC_STREAM *mpds, INT32 scale_percent ) {/*--------------------------------------------------------------------------   Set the output scale for the current stream   Inputs:  mpds = mpeg audio stream ptr returned by MPEGDEC_open            scale_percent = scale factor in % to apply to the decoded output                            100 is the nominal value   Return 0 if Ok, MPEGDEC_ERR_BADVALUE if invalid scale

⌨️ 快捷键说明

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