minimad

来源:互联网 发布:淘宝评价被系统删除 编辑:程序博客网 时间:2024/06/10 20:42
/**  002  * libmad - MPEG audio decoder library  003  * Copyright (C) 2000-2004 Underbit Technologies, Inc.  004  *  005  * This program is free software; you can redistribute it and/or modify  006  * it under the terms of the GNU General Public License as published by  007  * the Free Software Foundation; either version 2 of the License, or  008  * (at your option) any later version.  009  *  010  * This program is distributed in the hope that it will be useful,  011  * but WITHOUT ANY WARRANTY; without even the implied warranty of  012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  013  * GNU General Public License for more details.  014  *  015  * You should have received a copy of the GNU General Public License  016  * along with this program; if not, write to the Free Software  017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  018  *  019  * $Id: minimad.c,v 1.4 2004/01/23 09:41:32 rob Exp $  020  */ 021    022 # include <stdio.h>  023 # include <unistd.h>  024 # include <sys/stat.h>  025 # include <sys/mman.h>  026    027 # include "mad.h"  028    029 /**  030  * This is perhaps the simplest example use of the MAD high-level API.  031  * Standard input is mapped into memory via mmap(), then the high-level API  032  * is invoked with three callbacks: input, output, and error. The output  033  * callback converts MAD's high-resolution PCM samples to 16 bits, then  034  * writes them to standard output in little-endian, stereo-interleaved  035  * format.  036  */ 037    038 static int decode(unsigned char const *, unsigned long);  039    040 int main(int argc, char *argv[])  041 {  042   struct stat stat;  043   void *fdm;  044    045   if (argc != 1)  046     return 1;  047    048   if (fstat(STDIN_FILENO, &stat) == -1 ||  049       stat.st_size == 0)  050     return 2;  051    052   fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);  053   if (fdm == MAP_FAILED)  054     return 3;  055    056   decode(fdm, stat.st_size);  057    058   if (munmap(fdm, stat.st_size) == -1)  059     return 4;  060    061   return 0;  062 }  063    064 /**  065  * This is a private message structure. A generic pointer to this structure  066  * is passed to each of the callback functions. Put here any data you need  067  * to access from within the callbacks.  068  */ 069    070 struct buffer {  071   unsigned char const *start;  072   unsigned long length;  073 };  074    075 /**  076  * This is the input callback. The purpose of this callback is to (re)fill  077  * the stream buffer which is to be decoded. In this example, an entire file  078  * has been mapped into memory, so we just call mad_stream_buffer() with the  079  * address and length of the mapping. When this callback is called a second  080  * time, we are finished decoding.  081  */ 082    083 static 084 enum mad_flow input(void *data,  085             struct mad_stream *stream)  086 {  087   struct buffer *buffer = data;  088    089   if (!buffer->length)  090     return MAD_FLOW_STOP;  091    092   mad_stream_buffer(stream, buffer->start, buffer->length);  093    094   buffer->length = 0;  095    096   return MAD_FLOW_CONTINUE;  097 }  098    099 /**  100  * The following utility routine performs simple rounding, clipping, and  101  * scaling of MAD's high-resolution samples down to 16 bits. It does not  102  * perform any dithering or noise shaping, which would be recommended to  103  * obtain any exceptional audio quality. It is therefore not recommended to  104  * use this routine if high-quality output is desired.  105  */ 106    107 static inline 108 signed int scale(mad_fixed_t sample)  109 {  110   /** round */ 111   sample += (1L << (MAD_F_FRACBITS - 16));  112    113   /** clip */ 114   if (sample >= MAD_F_ONE)  115     sample = MAD_F_ONE - 1;  116   else if (sample < -MAD_F_ONE)  117     sample = -MAD_F_ONE;  118    119   /** quantize */ 120   return sample >> (MAD_F_FRACBITS + 1 - 16);  121 }  122    123 /**  124  * This is the output callback function. It is called after each frame of  125  * MPEG audio data has been completely decoded. The purpose of this callback  126  * is to output (or play) the decoded PCM audio.  127  */ 128    129 static 130 enum mad_flow output(void *data,  131              struct mad_header const *header,  132              struct mad_pcm *pcm)  133 {  134   unsigned int nchannels, nsamples;  135   mad_fixed_t const *left_ch, *right_ch;  136    137   /** pcm->samplerate contains the sampling frequency */ 138    139   nchannels = pcm->channels;  140   nsamples  = pcm->length;  141   left_ch   = pcm->samples[0];  142   right_ch  = pcm->samples[1];  143    144   while (nsamples--) {  145     signed int sample;  146    147     /** output sample(s) in 16-bit signed little-endian PCM */ 148    149     sample = scale(*left_ch++);  150     putchar((sample >> 0) & 0xff);  151     putchar((sample >> 8) & 0xff);  152    153     if (nchannels == 2) {  154       sample = scale(*right_ch++);  155       putchar((sample >> 0) & 0xff);  156       putchar((sample >> 8) & 0xff);  157     }  158   }  159    160   return MAD_FLOW_CONTINUE;  161 }  162    163 /**  164  * This is the error callback function. It is called whenever a decoding  165  * error occurs. The error is indicated by stream->error; the list of  166  * possible MAD_ERROR_* errors can be found in the mad.h (or stream.h)  167  * header file.  168  */ 169    170 static 171 enum mad_flow error(void *data,  172             struct mad_stream *stream,  173             struct mad_frame *frame)  174 {  175   struct buffer *buffer = data;  176    177   fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",  178       stream->error, mad_stream_errorstr(stream),  179       stream->this_frame - buffer->start);  180    181   /** return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */ 182    183   return MAD_FLOW_CONTINUE;  184 }  185    186 /**  187  * This is the function called by main() above to perform all the decoding.  188  * It instantiates a decoder object and configures it with the input,  189  * output, and error callback functions above. A single call to  190  * mad_decoder_run() continues until a callback function returns  191  * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and  192  * signal an error).  193  */ 194    195 static 196 int decode(unsigned char const *start, unsigned long length)  197 {  198   struct buffer buffer;  199   struct mad_decoder decoder;  200   int result;  201    202   /** initialize our private message structure */ 203    204   buffer.start  = start;  205   buffer.length = length;  206    207   /** configure input, output, and error functions */ 208    209   mad_decoder_init(&decoder, &buffer,  210            input, 0 /** header */, 0 /** filter */, output,  211            error, 0 /** message */);  212    213   /** start decoding */ 214    215   result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);  216    217   /** release the decoder */ 218    219   mad_decoder_finish(&decoder);  220    221   return result;  222 } 

原创粉丝点击