minimad.c

00001 /*
00002  * libmad - MPEG audio decoder library
00003  * Copyright (C) 2000-2003 Underbit Technologies, Inc.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * $Id: minimad.c,v 1.1 2003/08/31 18:59:46 gabest Exp $
00020  */
00021 
00022 # include <stdio.h>
00023 # include <unistd.h>
00024 # include <sys/stat.h>
00025 # include <sys/mman.h>
00026 
00027 # include "mad.h"
00028 
00029 /*
00030  * This is perhaps the simplest example use of the MAD high-level API.
00031  * Standard input is mapped into memory via mmap(), then the high-level API
00032  * is invoked with three callbacks: input, output, and error. The output
00033  * callback converts MAD's high-resolution PCM samples to 16 bits, then
00034  * writes them to standard output in little-endian, stereo-interleaved
00035  * format.
00036  */
00037 
00038 static int decode(unsigned char const *, unsigned long);
00039 
00040 int main(int argc, char *argv[])
00041 {
00042   struct stat stat;
00043   void *fdm;
00044 
00045   if (argc != 1)
00046     return 1;
00047 
00048   if (fstat(STDIN_FILENO, &stat) == -1 ||
00049       stat.st_size == 0)
00050     return 2;
00051 
00052   fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);
00053   if (fdm == MAP_FAILED)
00054     return 3;
00055 
00056   decode(fdm, stat.st_size);
00057 
00058   if (munmap(fdm, stat.st_size) == -1)
00059     return 4;
00060 
00061   return 0;
00062 }
00063 
00064 /*
00065  * This is a private message structure. A generic pointer to this structure
00066  * is passed to each of the callback functions. Put here any data you need
00067  * to access from within the callbacks.
00068  */
00069 
00070 struct buffer {
00071   unsigned char const *start;
00072   unsigned long length;
00073 };
00074 
00075 /*
00076  * This is the input callback. The purpose of this callback is to (re)fill
00077  * the stream buffer which is to be decoded. In this example, an entire file
00078  * has been mapped into memory, so we just call mad_stream_buffer() with the
00079  * address and length of the mapping. When this callback is called a second
00080  * time, we are finished decoding.
00081  */
00082 
00083 static
00084 enum mad_flow input(void *data,
00085                     struct mad_stream *stream)
00086 {
00087   struct buffer *buffer = data;
00088 
00089   if (!buffer->length)
00090     return MAD_FLOW_STOP;
00091 
00092   mad_stream_buffer(stream, buffer->start, buffer->length);
00093 
00094   buffer->length = 0;
00095 
00096   return MAD_FLOW_CONTINUE;
00097 }
00098 
00099 /*
00100  * The following utility routine performs simple rounding, clipping, and
00101  * scaling of MAD's high-resolution samples down to 16 bits. It does not
00102  * perform any dithering or noise shaping, which would be recommended to
00103  * obtain any exceptional audio quality. It is therefore not recommended to
00104  * use this routine if high-quality output is desired.
00105  */
00106 
00107 static inline
00108 signed int scale(mad_fixed_t sample)
00109 {
00110   /* round */
00111   sample += (1L << (MAD_F_FRACBITS - 16));
00112 
00113   /* clip */
00114   if (sample >= MAD_F_ONE)
00115     sample = MAD_F_ONE - 1;
00116   else if (sample < -MAD_F_ONE)
00117     sample = -MAD_F_ONE;
00118 
00119   /* quantize */
00120   return sample >> (MAD_F_FRACBITS + 1 - 16);
00121 }
00122 
00123 /*
00124  * This is the output callback function. It is called after each frame of
00125  * MPEG audio data has been completely decoded. The purpose of this callback
00126  * is to output (or play) the decoded PCM audio.
00127  */
00128 
00129 static
00130 enum mad_flow output(void *data,
00131                      struct mad_header const *header,
00132                      struct mad_pcm *pcm)
00133 {
00134   unsigned int nchannels, nsamples;
00135   mad_fixed_t const *left_ch, *right_ch;
00136 
00137   /* pcm->samplerate contains the sampling frequency */
00138 
00139   nchannels = pcm->channels;
00140   nsamples  = pcm->length;
00141   left_ch   = pcm->samples[0];
00142   right_ch  = pcm->samples[1];
00143 
00144   while (nsamples--) {
00145     signed int sample;
00146 
00147     /* output sample(s) in 16-bit signed little-endian PCM */
00148 
00149     sample = scale(*left_ch++);
00150     putchar((sample >> 0) & 0xff);
00151     putchar((sample >> 8) & 0xff);
00152 
00153     if (nchannels == 2) {
00154       sample = scale(*right_ch++);
00155       putchar((sample >> 0) & 0xff);
00156       putchar((sample >> 8) & 0xff);
00157     }
00158   }
00159 
00160   return MAD_FLOW_CONTINUE;
00161 }
00162 
00163 /*
00164  * This is the error callback function. It is called whenever a decoding
00165  * error occurs. The error is indicated by stream->error; the list of
00166  * possible MAD_ERROR_* errors can be found in the mad.h (or
00167  * libmad/stream.h) header file.
00168  */
00169 
00170 static
00171 enum mad_flow error(void *data,
00172                     struct mad_stream *stream,
00173                     struct mad_frame *frame)
00174 {
00175   struct buffer *buffer = data;
00176 
00177   fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
00178           stream->error, mad_stream_errorstr(stream),
00179           stream->this_frame - buffer->start);
00180 
00181   /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */
00182 
00183   return MAD_FLOW_CONTINUE;
00184 }
00185 
00186 /*
00187  * This is the function called by main() above to perform all the
00188  * decoding. It instantiates a decoder object and configures it with the
00189  * input, output, and error callback functions above. A single call to
00190  * mad_decoder_run() continues until a callback function returns
00191  * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and
00192  * signal an error).
00193  */
00194 
00195 static
00196 int decode(unsigned char const *start, unsigned long length)
00197 {
00198   struct buffer buffer;
00199   struct mad_decoder decoder;
00200   int result;
00201 
00202   /* initialize our private message structure */
00203 
00204   buffer.start  = start;
00205   buffer.length = length;
00206 
00207   /* configure input, output, and error functions */
00208 
00209   mad_decoder_init(&decoder, &buffer,
00210                    input, 0 /* header */, 0 /* filter */, output,
00211                    error, 0 /* message */);
00212 
00213   /* start decoding */
00214 
00215   result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
00216 
00217   /* release the decoder */
00218 
00219   mad_decoder_finish(&decoder);
00220 
00221   return result;
00222 }

Generated on Tue Dec 13 14:47:48 2005 for guliverkli by  doxygen 1.4.5