📄 madlld.c
字号:
/* HTAB = 4 */
/****************************************************************************
* madlld.c -- A simple program decoding an mpeg audio stream to 16-bit *
* PCM from stdin to stdout. This program is just a simple sample *
* demonstrating how the low-level libmad API can be used. *
*--------------------------------------------------------------------------*
* (c) 2001, 2002 Bertrand Petit *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided *
* with the distribution. *
* *
* 3. Neither the name of the author nor the names of its contributors *
* may be used to endorse or promote products derived from this *
* software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
* SUCH DAMAGE. *
* *
****************************************************************************/
/*
* $Name: v1_0p1 $
* $Date: 2002/01/08 01:06:56 $
* $Revision: 1.9 $
*/
/****************************************************************************
* Includes *
****************************************************************************/
#include <stdio.h>
#include <string.h>
#define HAVE_ERRNO_H
#ifdef HAVE_ERRNO_H
# include <errno.h>
#elif defined(_WIN32_WCE)
# define strerror(x) "strerror not supported"
int errno=1;
#endif
#include "mad_decode.h"
/****************************************************************************
* Global variables. *
****************************************************************************/
const char *ProgName;
/****************************************************************************
* Return an error string associated with a mad error code. *
****************************************************************************/
/* Mad version 0.14.2b introduced the mad_stream_errorstr() function.
* For previous library versions a replacement is provided below.
*/
#if (MAD_VERSION_MAJOR>=1) || \
((MAD_VERSION_MAJOR==0) && \
(((MAD_VERSION_MINOR==14) && \
(MAD_VERSION_PATCH>=2)) || \
(MAD_VERSION_MINOR>14)))
#define MadErrorString(x) mad_stream_errorstr(x)
#else
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 swich may be out of sync with libmad's
* defined error codes.
*/
default:
return("Unknown error code");
}
}
#endif
/****************************************************************************
* Converts a sample from mad's fixed point number format to an unsigned *
* short (16 bits). *
****************************************************************************/
static unsigned short MadFixedToUshort(mad_fixed_t Fixed)
{
/* A fixed point number is formed of the following bit pattern:
*
* SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
* MSB LSB
* S ==> Sign (0 is positive, 1 is negative)
* W ==> Whole part bits
* F ==> Fractional part bits
*
* This pattern contains MAD_F_FRACBITS fractional bits, one
* should alway use this macro when working on the bits of a fixed
* point number. It is not guaranteed to be constant over the
* different platforms supported by libmad.
*
* The unsigned short value is formed by the least significant
* whole part bit, followed by the 15 most significant fractional
* part bits. Warning: this is a quick and dirty way to compute
* the 16-bit number, madplay includes much better algorithms.
*/
Fixed=Fixed>>(MAD_F_FRACBITS-15);
return((unsigned short)Fixed);
}
/****************************************************************************
* Print human readable informations about an audio MPEG frame. *
****************************************************************************/
static int PrintFrameInfo(FILE *fp, struct mad_header *Header)
{
const char *Layer,
*Mode,
*Emphasis;
/* Convert the layer number to it's printed representation. */
switch(Header->layer)
{
case MAD_LAYER_I:
Layer="I";
break;
case MAD_LAYER_II:
Layer="II";
break;
case MAD_LAYER_III:
Layer="III";
break;
default:
Layer="(unexpected layer value)";
break;
}
/* Convert the audio mode to it's printed representation. */
switch(Header->mode)
{
case MAD_MODE_SINGLE_CHANNEL:
Mode="single channel";
break;
case MAD_MODE_DUAL_CHANNEL:
Mode="dual channel";
break;
case MAD_MODE_JOINT_STEREO:
Mode="joint (MS/intensity) stereo";
break;
case MAD_MODE_STEREO:
Mode="normal LR stereo";
break;
default:
Mode="(unexpected mode value)";
break;
}
/* Convert the emphasis to it's printed representation. */
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;
default:
Emphasis="(unexpected emphasis value)";
break;
}
fprintf(fp,"%s: %lu kb/s audio mpeg layer %s stream %s crc, "
"%s with %s emphasis at %d Hz sample rate\n",
ProgName,Header->bitrate,Layer,
Header->flags&MAD_FLAG_PROTECTION?"with":"without",
Mode,Emphasis,Header->samplerate);
return(ferror(fp));
}
/****************************************************************************
* Main decoding loop. This is where mad is used. *
****************************************************************************/
#define INPUT_BUFFER_SIZE (5*8192)
#define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */
static int MpegAudioDecoder(FILE *InputFp, FILE *OutputFp)
{
struct mad_stream Stream;
struct mad_frame Frame;
struct mad_synth Synth;
mad_timer_t Timer;
unsigned char InputBuffer[INPUT_BUFFER_SIZE],
OutputBuffer[OUTPUT_BUFFER_SIZE],
*OutputPtr=OutputBuffer;
const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
int Status=0,
i;
unsigned long FrameCount=0;
/* First the structures used by libmad must be initialized. */
mad_stream_init(&Stream);
mad_frame_init(&Frame);
mad_synth_init(&Synth);
mad_timer_reset(&Timer);
/* Decoding options can here be set in the options field of the
* Stream structure.
*/
/* This is the decoding loop. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -