📄 mp3dec.cpp.bak
字号:
/*
mp3dec.cpp:
decode mp3-data to 16bit pcm
Notice:
1. this code is writen for mips-cpu(ATI-XILLEON serial CHIP)
2. this code has optimized for mips1 (mips R3000)
Author:
XianXiang Cheng, Network Dept, &Rd Center, TclKing Ltd.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
#include <time.h>
#define FPM_MIPS /* switch, optimize for mips cpu */
#include "mad.h"
#include "mp3decode.h"
#include "mp3locals.h"
/* open mp3 decode debug ? */
int _mp3decode_debug = 0 ;
static inline
signed int scale(mad_fixed_t sample) ;
static signed short MadFixedToSshort(mad_fixed_t Fixed) ;
static void ApplyFilter(struct mad_frame *Frame, mad_fixed_t *Filter) ;
static const char *MadErrorString(const struct mad_stream *Stream) ;
static int FillMp3Info(Mp3Info_t *pMp3Info, struct mad_header *Header) ;
/*===================================================================*/
/*
* The following utility routine performs simple rounding, clipping, and
* scaling of MAD's high-resolution samples down to 16 bits. It does not
* perform any dithering or noise shaping, which would be recommended to
* obtain any exceptional audio quality. It is therefore not recommended to
* use this routine if high-quality output is desired.
*/
static inline
signed int scale(mad_fixed_t sample)
{
/* round */
sample += (1L << (MAD_F_FRACBITS - 16));
/* clip */
if (sample >= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE)
sample = -MAD_F_ONE;
/* quantize */
return sample >> (MAD_F_FRACBITS + 1 - 16);
}
/*===================================================================*/
/****************************************************************************
* Converts a sample from libmad's fixed point number format to a signed *
* short (16 bits). *
****************************************************************************/
static signed short MadFixedToSshort(mad_fixed_t Fixed)
{
/* Clipping */
if(Fixed>=MAD_F_ONE)
return(SHRT_MAX);
if(Fixed<=-MAD_F_ONE)
return(-SHRT_MAX);
/* Conversion. */
Fixed=Fixed>>(MAD_F_FRACBITS-15);
return((signed short)Fixed);
}
/*===================================================================*/
/****************************************************************************
* Applies a frequency-domain filter to audio data in the subband-domain. *
****************************************************************************/
static void ApplyFilter(struct mad_frame *Frame, mad_fixed_t *Filter)
{
int Channel,
Sample,
Samples,
SubBand;
/* There is two application loops, each optimized for the number
* of audio channels to process. The first alternative is for
* two-channel frames, the second is for mono-audio.
*/
Samples=MAD_NSBSAMPLES(&Frame->header);
if(Frame->header.mode!=MAD_MODE_SINGLE_CHANNEL)
for(Channel=0;Channel<2;Channel++)
for(Sample=0;Sample<Samples;Sample++)
for(SubBand=0;SubBand<32;SubBand++)
Frame->sbsample[Channel][Sample][SubBand]=
mad_f_mul(Frame->sbsample[Channel][Sample][SubBand],
Filter[SubBand]);
else
for(Sample=0;Sample<Samples;Sample++)
for(SubBand=0;SubBand<32;SubBand++)
Frame->sbsample[0][Sample][SubBand]=
mad_f_mul(Frame->sbsample[0][Sample][SubBand],
Filter[SubBand]);
}
/*===================================================================*/
static const char *MadErrorString(const struct mad_stream *Stream)
{
switch(Stream->error)
{
/* Generic unrecoverable errors. */
case MAD_ERROR_BUFLEN:
return("input buffer too small (or EOF)");
case MAD_ERROR_BUFPTR:
return("invalid (null) buffer pointer");
case MAD_ERROR_NOMEM:
return("not enough memory");
/* Frame header related unrecoverable errors. */
case MAD_ERROR_LOSTSYNC:
return("lost synchronization");
case MAD_ERROR_BADLAYER:
return("reserved header layer value");
case MAD_ERROR_BADBITRATE:
return("forbidden bitrate value");
case MAD_ERROR_BADSAMPLERATE:
return("reserved sample frequency value");
case MAD_ERROR_BADEMPHASIS:
return("reserved emphasis value");
/* Recoverable errors */
case MAD_ERROR_BADCRC:
return("CRC check failed");
case MAD_ERROR_BADBITALLOC:
return("forbidden bit allocation value");
case MAD_ERROR_BADSCALEFACTOR:
return("bad scalefactor index");
case MAD_ERROR_BADFRAMELEN:
return("bad frame length");
case MAD_ERROR_BADBIGVALUES:
return("bad big_values count");
case MAD_ERROR_BADBLOCKTYPE:
return("reserved block_type");
case MAD_ERROR_BADSCFSI:
return("bad scalefactor selection info");
case MAD_ERROR_BADDATAPTR:
return("bad main_data_begin pointer");
case MAD_ERROR_BADPART3LEN:
return("bad audio data length");
case MAD_ERROR_BADHUFFTABLE:
return("bad Huffman table select");
case MAD_ERROR_BADHUFFDATA:
return("Huffman data overrun");
case MAD_ERROR_BADSTEREO:
return("incompatible block_type for JS");
/* Unknown error. This switch may be out of sync with libmad's
* defined error codes.
*/
default:
return("Unknown error code");
}
}
/*===================================================================*/
static int FillMp3Info(Mp3Info_t *pMp3Info, struct mad_header *Header)
{
int result = -1 ;
Mp3Info_t *p = pMp3Info ;
const char *Layer,
*Mode,
*Emphasis ;
if (!p
|| !Header)
goto done ;
/* Convert the layer number to it's printed representation. */
switch(Header->layer)
{
case MAD_LAYER_I:
Layer="I";
p->layer = 1 ;
break;
case MAD_LAYER_II:
Layer="II";
p->layer = 2 ;
break;
case MAD_LAYER_III:
p->layer = 3 ;
Layer="III";
break;
default:
Layer="(unexpected layer value)";
p->layer = 0 ;
break;
}
/* Convert the audio mode to it's printed representation. */
switch(Header->mode)
{
case MAD_MODE_SINGLE_CHANNEL:
Mode="single channel";
p->channel = 1 ;
break;
case MAD_MODE_DUAL_CHANNEL:
Mode="dual channel";
p->channel = 2 ;
break;
case MAD_MODE_JOINT_STEREO:
Mode="joint (MS/intensity) stereo";
p->channel = 2 ;
break;
case MAD_MODE_STEREO:
Mode="normal LR stereo";
p->channel = 2 ;
break;
default:
Mode="(unexpected mode value)";
p->channel = 0 ;
break;
}
switch(Header->emphasis)
{
case MAD_EMPHASIS_NONE:
Emphasis="no";
break;
case MAD_EMPHASIS_50_15_US:
Emphasis="50/15 us";
break;
case MAD_EMPHASIS_CCITT_J_17:
Emphasis="CCITT J.17";
break;
#if (MAD_VERSION_MAJOR>=1) || \
((MAD_VERSION_MAJOR==0) && (MAD_VERSION_MINOR>=15))
case MAD_EMPHASIS_RESERVED:
Emphasis="reserved(!)";
break;
#endif
default:
Emphasis="(unexpected emphasis value)";
break;
}
if (_mp3decode_debug)
fprintf(stderr,"%lu kb/s audio MPEG layer %s stream %s CRC, "
"%s with %s emphasis at %d Hz sample rate\n",
Header->bitrate,Layer,
Header->flags&MAD_FLAG_PROTECTION?"with":"without",
Mode,Emphasis,Header->samplerate);
p->mpeg = 1 ;
p->bitRate = Header->bitrate ;
p->sampleRate = Header->samplerate ;
p->nBitsPerSample = 16; /* now, we set it fixed (16 bits) */
p->frameSize = 144*p->bitRate/p->sampleRate
+ ((Header->flags&MAD_FLAG_PADDING)?1:0) ;
result = 0 ;
done:
return (result) ;
}
/*===================================================================*/
/*===================================================================*/
/*===================================================================*/
int Mp3DecodeStart(Mp3DecodeCtrl_t *pMp3DecCtrl)
{
int result = -1 ;
Mp3DecodeCtrl_t *p = pMp3DecCtrl ;
if (!p)
goto done ;
mad_stream_init(&p->Stream);
mad_frame_init(&p->Frame);
mad_synth_init(&p->Synth);
mad_timer_reset(&p->Timer);
result = 0 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -