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

📄 mpegdec.c

📁 Application (fix point) for playing MP3 data on embedded systems. mp3play is designed to be able to
💻 C
📖 第 1 页 / 共 2 页
字号:
// #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*/   MPA_STREAM *mps;   mps = (MPA_STREAM *)mpds->handle;   if( MPEGSUB_scale( mps->mpegsub, scale_percent ) ) return MPEGDEC_ERR_BADVALUE;   return MPEGDEC_ERR_NONE;}// #18 EndINT32 MPEGDEC_decode_frame( MPEGDEC_STREAM *mpds,                            INT16 *pcm[ MPEGDEC_MAX_CHANNELS ] )/*--------------------------------------------------------------------------   Decode the current MPEG Audio frame   Input:  mpds =  mpeg audio stream ptr returned by MPEGDEC_open   Output: pcm[] = 16-bit samples                   pcm[ 0 ] is mono or left voice or channel 1                   pcm[ 1 ] is right or channel 2   Return the number of samples   Note: pcm[]'s be at least arrays of MPEGDEC_PCM_SIZE         number of samples can be 0 if current frame is skipped, in case         of error in crc or not enough data for decoding (layer III)         number of samples = 0 does not indicate end of stream !*/{   MPA_STREAM *mps;   INT32 count;   int err;   mps = (MPA_STREAM *)mpds->handle;   mps->pcm[ 0 ] = pcm[ 0 ];   mps->pcm[ 1 ] = pcm[ 1 ];   if( mps->need_sync ) { // #10      err = synchronize( mps );      if( err ) return err;      mps->need_sync = FALSE;   }   else {      err = MPEGDEC_read_header( mps, FALSE ); // #5 FALSE: don't fail if MPEG Audio sync not at first      if( err ) return err;   }#ifdef MPEGAUD_DEMO   MPEGAUD_CHECK_DEMO_FRAME( frame_count );   frame_count++;#endif//fill_info( mpds );   switch( mps->header.layer ) {      case 1:         count = MPEG1_decode_frame( mps );         break;      case 2:         count = MPEG2_decode_frame( mps );         break;      case 3:         count = MPEG3_decode_frame( mps );         break;      default:         count = 0;   }   mps->frame++;   return count;} /* MPEGDEC_decode_frame */static int decoder_reset( MPEGDEC_STREAM *mpds )/*--------------------------------------------------------------------------   Reset the decoder   Inputs:  mpds = mpeg audio stream ptr returned by MPEGDEC_open*/{   int err;   MPA_STREAM *mps;   if( !mpds ) return MPEGDEC_ERR_EOF;   mps = (MPA_STREAM *)mpds->handle;   // Reset all layer's decoders   err = MPEG1_reset( mps );   if( err ) return err;   err = MPEG2_reset( mps );   if( err ) return err;   err = MPEG3_reset( mps );   if( err ) return err;   // Reset subband buffers & offsets   err = MPEGSUB_reset( mps->mpegsub );   if( err ) return err; // #8   err = MPEGIMDCT_reset( mps->mpegimdct ); // #8   return err;} /* decoder_reset */int MPEGDEC_seek( MPEGDEC_STREAM *mpds, UINT32 ms_time_position )/*--------------------------------------------------------------------------   Seek into an MPEG Audio stream   Inputs:  mpds = mpeg audio stream ptr returned by MPEGDEC_open            ms_time_position = absolute time position in ms*/{   int err = -1;   MPA_STREAM *mps;   if( !mpds ) return MPEGDEC_ERR_EOF;   mps = (MPA_STREAM *)mpds->handle;   if( mps ) {      BITSTREAM *bs = mps->bitstream;      REAL exact_seek;      REAL slots;      INT32 seek_pos;      INT32 frame_bytes;      INT32 frame; // #11      exact_seek = ((REAL)mps->bitrate * (REAL)ms_time_position) * 0.125;      // Calculate nearest # of frames      if( mps->header.layer == 1 ) frame_bytes = 48000; // 384/8*1000      else if( (mps->header.layer == 3) && (mps->header.ID == MPA_ID_2) ) frame_bytes = 72000;      else frame_bytes = 144000;      slots = (REAL)(frame_bytes * mps->bitrate) / (REAL)mps->sfreq;      frame = (INT32)( exact_seek / slots );      // Calcultate seek pos in multiple of frames      seek_pos = (INT32)((REAL)frame * slots);      // Here sub 1 to be sure to get header      seek_pos--;      if( seek_pos < 0 ) seek_pos = 0;      seek_pos += mps->bitstream_start_pos; // #17      err = BSTR_seek( bs, seek_pos );      if( !err ) {         mps->frame = frame; // #11         decoder_reset( mpds );         mps->need_sync = TRUE; // #10      }   }   return err;} /* MPEGDEC_seek */int MPEGDEC_time( MPEGDEC_STREAM *mpds, UINT32 *ms_time_position )/*--------------------------------------------------------------------------   Get the current time position of an MPEG Audio stream   Input:  mpds = mpeg audio stream ptr returned by MPEGDEC_open   Output: ms_time_position = absolute time position in ms   Return 0 if Ok*/{   int err = -1;   MPA_STREAM *mps;   if( !mpds ) return MPEGDEC_ERR_EOF;   mps = (MPA_STREAM *)mpds->handle;   if( mps ) {      INT32 frame_bits;      if( mps->header.layer == 1 ) frame_bits = 384000; // 384*1000      else if( (mps->header.layer == 3) && (mps->header.ID == MPA_ID_2) ) frame_bits = 576000;      else frame_bits = 1152000;      *ms_time_position = (UINT32)(((REAL)mps->frame * (REAL)frame_bits ) / (REAL)mps->sfreq);      err = 0;   }   return err;} /* MPEGDEC_time */void MPEGDEC_close( MPEGDEC_STREAM *mpds )/*--------------------------------------------------------------------------   Close an MPEG Audio stream   Input:  mpds =  mpeg audio stream ptr returned by MPEGDEC_open*/{   MPA_STREAM *mps;   if( !mpds ) return;   mps = (MPA_STREAM *)mpds->handle;   if( mps ) {      if( mps->mpegimdct ) MPEGIMDCT_close( mps->mpegimdct ); // #8      if( mps->mpegsub ) MPEGSUB_close( mps->mpegsub );      if( mps->huffman ) HUFF_close( mps->huffman );      if( mps->bitstream ) BSTR_close( mps->bitstream );      free( mps );   }   free( mpds );} /* MPEGDEC_close */MPEGDEC_STREAM *MPEGDEC_open( char *filename, MPEGDEC_CTRL *ctrl )/*--------------------------------------------------------------------------   Open an MPEG Audio stream   Inputs: filename = stream filename to decode           ctrl = decoding controls   Return the mpeg audio stream ptr or NULL if failed to open stream*/{   MPEGDEC_STREAM *mpds;   MPA_STREAM *mps;   INT16 freq_div;   INT16 quality;   INT32 freq_max;   INT32 buffer_size; // #6   MPEGDEC_LAYER  *dec_lay; // #13   MPEGDEC_OUTPUT *dec_out; // #13   mpds = (MPEGDEC_STREAM *)malloc( sizeof( MPEGDEC_STREAM ) );   if( !mpds ) return NULL;   memset( mpds, 0, sizeof( MPEGDEC_STREAM ) );   mps = (MPA_STREAM *)malloc( sizeof( MPA_STREAM ) );   if( !mps ) {      MPEGDEC_close( mpds );      return NULL;   }   memset( mps, 0, sizeof( MPA_STREAM ) );   mpds->handle = mps;   // #7 Begin   buffer_size = ctrl->stream_buffer_size & (INT32)(~3); // Multiple of 4 bytes   if( buffer_size <= 0 ) buffer_size = MPEGDEC_BITSTREAM_BUFFER_SIZE;   // #7 End   mps->bitstream = BSTR_open( (BITSTREAM_ACCESS *)ctrl->bs_access,                               filename, buffer_size /* #7 */ );   if( !mps->bitstream ) {      MPEGDEC_close( mpds );      return NULL;   }   mps->stream_size = mps->bitstream->bitstream_size;   mps->huffman = HUFF_open();   if( !mps->huffman ) {      MPEGDEC_close( mpds );      return NULL;   }   mps->current_table = -1;// #17 Begin#if 1   if( synchronize( mps ) ) {      (void)MPEGDEC_close( mpds );      return NULL;   }   mps->need_sync = FALSE;   mps->bitstream_start_pos = mps->header.header_pos;   mps->stream_size = mps->bitstream->bitstream_size - mps->bitstream_start_pos;#else   if( MPEGDEC_read_header( mps, (BOOL)ctrl->check_mpeg ) ) { // #6: check_mpeg      (void)MPEGDEC_close( mpds );      return NULL;   }#endif// #17 End   // #13 Begin   if( mps->header.layer < 3 ) dec_lay = &ctrl->layer_1_2;   else dec_lay = &ctrl->layer_3;   mps->force_mono = dec_lay->force_mono;   if( mps->stereo ) dec_out = &dec_lay->stereo;   else dec_out = &dec_lay->mono;   freq_div = dec_out->freq_div;   quality = dec_out->quality;   freq_max = dec_out->freq_max;   // #13 End#ifdef MPEGAUD_DEMO   quality = 0;#endif   if( freq_div == 0 ) { // #4      INT32 freq = mps->sfreq;      mps->freq_div = 1;      do {         if( freq <= freq_max ) break;         mps->freq_div <<= 1;         freq >>= 1;      } while ( mps->freq_div < 4 );   }   else {      mps->freq_div = freq_div;   }   switch( mps->freq_div ) {      case 2:         mps->sb_max = MPA_SBLIMIT/2;         break;      case 4:         mps->sb_max = MPA_SBLIMIT/4;         break;      default:         mps->freq_div = 1;         mps->sb_max = MPA_SBLIMIT;         break;   }   mps->quality = quality;   if( mps->quality < MPEGDEC_QUALITY_LOW ) mps->quality = MPEGDEC_QUALITY_LOW;   else if( mps->quality > MPEGDEC_QUALITY_HIGH ) mps->quality = MPEGDEC_QUALITY_HIGH;   mps->mpegsub = MPEGSUB_open( mps->freq_div, mps->quality );   if( !mps->mpegsub ) {      MPEGDEC_close( mpds );      return NULL;   }   /* #8 Begin */   mps->mpegimdct = MPEGIMDCT_open();   if( !mps->mpegimdct ) {      MPEGDEC_close( mpds );      return NULL;   }   /* #8 End */   fill_info( mpds );   (void)BSTR_seek( mps->bitstream, /*0*/ mps->bitstream_start_pos ); // #17   decoder_reset( mpds );   return mpds;} /* MPEGDEC_open */

⌨️ 快捷键说明

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