wave.c
上传用户:shenggui01
上传日期:2022-01-16
资源大小:54k
文件大小:4k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. /* wave.c
  2.  *
  3.  * Data input functions.
  4.  */
  5. #include "types.h"
  6. /*
  7.  * wave_close:
  8.  * -----------
  9.  */
  10. void wave_close(void)
  11. {
  12.   fclose(config.wave.file);
  13. }
  14. /*
  15.  * wave_open:
  16.  * ----------
  17.  * Opens and verifies the header of the Input Wave file. The file pointer is
  18.  * left pointing to the start of the samples.
  19.  */
  20. void wave_open(int raw, int mono_from_stereo)
  21. {
  22.   static char *channel_mappings[] = {NULL,"mono","stereo"};
  23.   static char *file_type[] = {"RIFF-WAVE PCM","RAW DATA PCM"};
  24.   /* Wave file headers can vary from this, but we're only intereseted in this format */
  25.   struct wave_header
  26.   {
  27.     char riff[4];             /* "RIFF" */
  28.     unsigned long size;       /* length of rest of file = size of rest of header(36) + data length */
  29.     char wave[4];             /* "WAVE" */
  30.     char fmt[4];              /* "fmt " */
  31.     unsigned long fmt_len;    /* length of rest of fmt chunk = 16 */
  32.     unsigned short tag;       /* MS PCM = 1 */
  33.     unsigned short channels;  /* channels, mono = 1, stereo = 2 */
  34.     unsigned long samp_rate;  /* samples per second = 44100 */
  35.     unsigned long byte_rate;  /* bytes per second = samp_rate * byte_samp = 176400 */
  36.     unsigned short byte_samp; /* block align (bytes per sample) = channels * bits_per_sample / 8 = 4 */
  37.     unsigned short bit_samp;  /* bits per sample = 16 for MS PCM (format specific) */
  38.     char data[4];             /* "data" */
  39.     unsigned long length;     /* data length (bytes) */
  40.   } header;
  41.   /* open input file */
  42.   if((config.wave.file = fopen(config.infile,"rb")) == NULL)
  43.     error("Unable to open file");
  44.   if(raw)
  45.   {
  46.       fseek(config.wave.file, 0, SEEK_END); /* find length of file */
  47.       header.length = ftell(config.wave.file);
  48.       fseek(config.wave.file, 0, SEEK_SET);
  49.       header.channels = (mono_from_stereo) ? 1 : 2;
  50.       header.samp_rate = config.wave.samplerate; /* 44100 if not set by user */
  51.       header.bit_samp = 16;     /* assumed */
  52.       header.byte_samp = header.channels * header.bit_samp / 8;
  53.       header.byte_rate = header.samp_rate * header.byte_samp;
  54.   }
  55.   else /* wave */
  56.   {
  57.       if (fread(&header, sizeof(header), 1, config.wave.file) != 1)
  58.         error("Invalid Header");
  59.       if(strncmp(header.riff,"RIFF",4) != 0) error("Not a MS-RIFF file");
  60.       if(strncmp(header.wave,"WAVE",4) != 0) error("Not a WAVE audio");
  61.       if(strncmp(header.fmt, "fmt ",4) != 0) error("Can't find format chunk");
  62.       if(header.tag != 1)                    error("Unknown WAVE format");
  63.       if(header.channels > 2)                error("More than 2 channels");
  64.       if(header.bit_samp != 16)              error("Not 16 bit");
  65.       if(strncmp(header.data,"data",4) != 0) error("Can't find data chunk");
  66.   }
  67.   config.wave.channels      = header.channels;
  68.   config.wave.samplerate    = header.samp_rate;
  69.   config.wave.bits          = header.bit_samp;
  70.   config.wave.total_samples = header.length / header.byte_samp;
  71.   config.wave.length        = header.length / header.byte_rate;
  72.   if((config.wave.channels == 1) || mono_from_stereo)
  73.   {
  74.     config.mpeg.channels = 1;
  75.     config.mpeg.mode = MODE_MONO;
  76.   }
  77.   printf("%s, %s %ldHz %dbit, Length: %2ld:%2ld:%2ldn",
  78.           file_type[raw],
  79.           channel_mappings[config.wave.channels],
  80.           config.wave.samplerate,
  81.           config.wave.bits,
  82.           config.wave.length/3600,(config.wave.length/60)%60,config.wave.length%60);
  83. }
  84. /*
  85.  * wave_get:
  86.  * ---------
  87.  * Reads samples from the file in longs. A long can
  88.  * hold one stereo or two mono samples.
  89.  * Returns the address of the start of the next frame or NULL if there are no
  90.  * more. The last frame will be padded with zero's.
  91.  */
  92. unsigned long int *wave_get(void)
  93. {
  94.   int n,p;
  95.   static unsigned long buff[samp_per_frame];
  96.   n = config.mpeg.samples_per_frame >> (2 - config.wave.channels);
  97.   p = fread(buff,sizeof(unsigned long),(short)n,config.wave.file);
  98.   if(!p)
  99.     return 0;
  100.   else
  101.   {
  102.     for(; p<n; p++)
  103.       buff[p]=0;
  104.     return buff;
  105.   }
  106. }