简单mp3的实现

  
  
  
  
  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4. #include <string.h> 
  5. #include <fcntl.h> 
  6. #include <sys/ioctl.h> 
  7. #include <sys/soundcard.h> 
  8. # include <sys/stat.h> 
  9. # include <sys/mman.h> 
  10.  
  11. # include "mad.h" 
  12.  
  13. int soundfd; 
  14.  
  15. void set_dsp() 
  16. {    
  17.     int format = AFMT_S16_LE; 
  18.     int channels = 2;   //CHANNELS 
  19.     int rate = 44100;   //HZ 
  20.      
  21.     if((soundfd = open("/dev/dsp" , O_WRONLY)) < 0) 
  22.     { 
  23.         fprintf(stderr , "can't open sound device!\n"); 
  24.         exit(-1); 
  25.     } 
  26.     ioctl(soundfd , SNDCTL_DSP_SPEED , &rate); 
  27.     ioctl(soundfd , SNDCTL_DSP_SETFMT, &format); 
  28.     ioctl(soundfd , SNDCTL_DSP_CHANNELS , &channels); 
  29.     return ; 
  30.  
  31. void write_dsp(int c) 
  32.     write(soundfd , (char *)&c , 1); 
  33.     return ; 
  34.  
  35. /* 
  36.  * This is perhaps the simplest example use of the MAD high-level API. 
  37.  * Standard input is mapped into memory via mmap(), then the high-level API 
  38.  * is invoked with three callbacks: input, output, and error. The output 
  39.  * callback converts MAD's high-resolution PCM samples to 16 bits, then 
  40.  * writes them to standard output in little-endian, stereo-interleaved 
  41.  * format. 
  42.  */ 
  43.  
  44.  
  45. static int decode(unsigned char const *, unsigned long); 
  46.  
  47. int main(int argc, char *argv[]) 
  48.   struct stat stat; 
  49.   void *fdm; 
  50.   set_dsp(); 
  51.   if (argc != 1) 
  52.     return 1; 
  53.  
  54.   if (fstat(STDIN_FILENO, &stat) == -1 || 
  55.       stat.st_size == 0) 
  56.     return 2; 
  57.  
  58.   fdm = mmap(0, stat.st_size , PROT_READ, MAP_SHARED, STDIN_FILENO, 0); 
  59.   if (fdm == MAP_FAILED) 
  60.     return 3; 
  61.  
  62.   decode(fdm, stat.st_size); 
  63.  
  64.   if (munmap(fdm, stat.st_size) == -1) 
  65.     return 4; 
  66.  
  67.   return 0; 
  68.  
  69. /* 
  70.  * This is a private message structure. A generic pointer to this structure 
  71.  * is passed to each of the callback functions. Put here any data you need 
  72.  * to access from within the callbacks. 
  73.  */ 
  74.  
  75. struct buffer { 
  76.   unsigned char const *start; 
  77.   unsigned long length; 
  78. }; 
  79.  
  80. /* 
  81.  * This is the input callback. The purpose of this callback is to (re)fill 
  82.  * the stream buffer which is to be decoded. In this example, an entire file 
  83.  * has been mapped into memory, so we just call mad_stream_buffer() with the 
  84.  * address and length of the mapping. When this callback is called a second 
  85.  * time, we are finished decoding. 
  86.  */ 
  87.  
  88. static 
  89. enum mad_flow input(void *data, 
  90.             struct mad_stream *stream) 
  91.   struct buffer *buffer = data; 
  92.  
  93.   if (!buffer->length) 
  94.     return MAD_FLOW_STOP; 
  95.  
  96.   mad_stream_buffer(stream, buffer->start, buffer->length); 
  97.  
  98.   buffer->length = 0; 
  99.  
  100.   return MAD_FLOW_CONTINUE; 
  101.  
  102. /* 
  103.  * The following utility routine performs simple rounding, clipping, and 
  104.  * scaling of MAD's high-resolution samples down to 16 bits. It does not 
  105.  * perform any dithering or noise shaping, which would be recommended to 
  106.  * obtain any exceptional audio quality. It is therefore not recommended to 
  107.  * use this routine if high-quality output is desired. 
  108.  */ 
  109.  
  110. static inline 
  111. signed int scale(mad_fixed_t sample) 
  112.   /* round */ 
  113.   sample += (1L << (MAD_F_FRACBITS - 16)); 
  114.  
  115.   /* clip */ 
  116.   if (sample >= MAD_F_ONE) 
  117.     sample = MAD_F_ONE - 1; 
  118.   else if (sample < -MAD_F_ONE) 
  119.     sample = -MAD_F_ONE; 
  120.  
  121.   /* quantize */ 
  122.   return sample >> (MAD_F_FRACBITS + 1 - 16); 
  123.  
  124. /* 
  125.  * This is the output callback function. It is called after each frame of 
  126.  * MPEG audio data has been completely decoded. The purpose of this callback 
  127.  * is to output (or play) the decoded PCM audio. 
  128.  */ 
  129.  
  130. static 
  131. enum mad_flow output(void *data, 
  132.              struct mad_header const *header, 
  133.              struct mad_pcm *pcm) 
  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.     write_dsp((sample >> 0) & 0xff); 
  151.     write_dsp((sample >> 8) & 0xff); 
  152.  
  153.     if (nchannels == 2) { 
  154.       sample = scale(*right_ch++); 
  155.       write_dsp((sample >> 0) & 0xff); 
  156.       write_dsp((sample >> 8) & 0xff); 
  157.     } 
  158.   } 
  159.  
  160.   return MAD_FLOW_CONTINUE; 
  161.  
  162. /* 
  163.  * This is the error callback function. It is called whenever a decoding 
  164.  * error occurs. The error is indicated by stream->error; the list of 
  165.  * possible MAD_ERROR_* errors can be found in the mad.h (or stream.h) 
  166.  * header file. 
  167.  */ 
  168.  
  169. static 
  170. enum mad_flow error(void *data, 
  171.             struct mad_stream *stream, 
  172.             struct mad_frame *frame) 
  173.   struct buffer *buffer = data; 
  174.  
  175.   fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n"
  176.       stream->error, mad_stream_errorstr(stream), 
  177.       stream->this_frame - buffer->start); 
  178.  
  179.   /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */ 
  180.  
  181.   return MAD_FLOW_CONTINUE; 
  182.  
  183. /* 
  184.  * This is the function called by main() above to perform all the decoding. 
  185.  * It instantiates a decoder object and configures it with the input, 
  186.  * output, and error callback functions above. A single call to 
  187.  * mad_decoder_run() continues until a callback function returns 
  188.  * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and 
  189.  * signal an error). 
  190.  */ 
  191.  
  192. static 
  193. int decode(unsigned char const *start, unsigned long length) 
  194.   struct buffer buffer; 
  195.   struct mad_decoder decoder; 
  196.   int result; 
  197.  
  198.   /* initialize our private message structure */ 
  199.  
  200.   buffer.start  = start; 
  201.   buffer.length = length; 
  202.  
  203.   /* configure input, output, and error functions */ 
  204.  
  205.   mad_decoder_init(&decoder, &buffer, 
  206.            input, 0 /* header */, 0 /* filter */, output, 
  207.            error, 0 /* message */); 
  208.  
  209.   /* start decoding */ 
  210.  
  211.   result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); 
  212.  
  213.   /* release the decoder */ 
  214.  
  215.   mad_decoder_finish(&decoder); 
  216.  
  217.   return result; 

 

你可能感兴趣的:(mp3实现)