title: Read and write 32bit wav file in C
body: <p>I'm making a small program to read &amp; write 32 bit wav file in C language.</p>
  
  <p>But, I got a problem.</p>
  
  <p>After compilation, Sometimes the program works well, yet sometimes, it doesn't work...like:</p>
  
  <ul>
  <li>output wav file is empty</li>
  <li>output wav file(1 sec) is too big, larger than 5GB...</li>
  </ul>
  
  <p>I really stack here...
  Anyone knows a solution??</p>
  
  <p>Below is my program </p>
  
  <p>↓ wave32.h ↓ </p>
  
  <pre><code>typedef struct
  {
    int fs; 
    int bits;
    int length;
    double *s; 
  } MONO_PCM;
  
  void wave_read_32bit_mono(MONO_PCM *pcm, char *file_name)
  {
    FILE *fp;
    char riff_chunk_ID[4];
    long riff_chunk_size;
    char file_format_type[4];
    char fmt_chunk_ID[4];
    long fmt_chunk_size;
    short wave_format_type;
    short channel;
    long samples_per_sec;
    long bytes_per_sec;
    short block_size;
    short bits_per_sample;
    char data_chunk_ID[4];
    long data_chunk_size;
    int data;
    int n;
  
    fp = fopen(file_name, "rb");
  
    fread(riff_chunk_ID, 1, 4, fp);
    fread(&amp;riff_chunk_size, 4, 1, fp);
    fread(file_format_type, 1, 4, fp);
    fread(fmt_chunk_ID, 1, 4, fp);
    fread(&amp;fmt_chunk_size, 4, 1, fp);
    fread(&amp;wave_format_type, 2, 1, fp);
    fread(&amp;channel, 2, 1, fp);
    fread(&amp;samples_per_sec, 4, 1, fp);
    fread(&amp;bytes_per_sec, 4, 1, fp);
    fread(&amp;block_size, 2, 1, fp);
    fread(&amp;bits_per_sample, 2, 1, fp);
    fread(data_chunk_ID, 1, 4, fp);
    fread(&amp;data_chunk_size, 4, 1, fp);
  
  
    pcm-&gt;fs = samples_per_sec;
    pcm-&gt;bits = bits_per_sample;
    pcm-&gt;length = data_chunk_size / 4;
    pcm-&gt;s = calloc(pcm-&gt;length, sizeof(double));
  
    for (n = 0; n &lt; pcm-&gt;length; n++)
    {
      fread(&amp;data, 4, 1, fp);
      pcm-&gt;s[n] =  ( (double)data / 2147483648.0 ) ;
    }
  
    fclose(fp);
  }
  void wave_write_32bit_mono(MONO_PCM *pcm, char *file_name)
  {
    FILE *fp;
    char riff_chunk_ID[4];
    long riff_chunk_size;
    char file_format_type[4];
    char fmt_chunk_ID[4];
    long fmt_chunk_size;
    short wave_format_type;
    short channel;
    long samples_per_sec;
    long bytes_per_sec;
    short block_size;
    short bits_per_sample;
    char data_chunk_ID[4];
    long data_chunk_size;
    double s;
    int data;
    int n;
  
    riff_chunk_ID[0] = 'R';
    riff_chunk_ID[1] = 'I';
    riff_chunk_ID[2] = 'F';
    riff_chunk_ID[3] = 'F';
    riff_chunk_size = 36 + pcm-&gt;length * 2;
    file_format_type[0] = 'W';
    file_format_type[1] = 'A';
    file_format_type[2] = 'V';
    file_format_type[3] = 'E';
  
    fmt_chunk_ID[0] = 'f';
    fmt_chunk_ID[1] = 'm';
    fmt_chunk_ID[2] = 't';
    fmt_chunk_ID[3] = ' ';
    fmt_chunk_size = 16;
    wave_format_type = 1;
    channel = 1;
    samples_per_sec = pcm-&gt;fs;
    bytes_per_sec = pcm-&gt;fs * pcm-&gt;bits / 8;
    block_size = pcm-&gt;bits / 8;
    bits_per_sample = pcm-&gt;bits;
  
    data_chunk_ID[0] = 'd';
    data_chunk_ID[1] = 'a';
    data_chunk_ID[2] = 't';
    data_chunk_ID[3] = 'a';
    data_chunk_size = pcm-&gt;length * 4;
  
    fp = fopen(file_name, "wb");
  
    fwrite(riff_chunk_ID, 1, 4, fp);
    fwrite(&amp;riff_chunk_size, 4, 1, fp);
    fwrite(file_format_type, 1, 4, fp);
    fwrite(fmt_chunk_ID, 1, 4, fp);
    fwrite(&amp;fmt_chunk_size, 4, 1, fp);
    fwrite(&amp;wave_format_type, 2, 1, fp);
    fwrite(&amp;channel, 2, 1, fp);
    fwrite(&amp;samples_per_sec, 4, 1, fp);
    fwrite(&amp;bytes_per_sec, 4, 1, fp);
    fwrite(&amp;block_size, 2, 1, fp);
    fwrite(&amp;bits_per_sample, 2, 1, fp);
    fwrite(data_chunk_ID, 1, 4, fp);
    fwrite(&amp;data_chunk_size, 4, 1, fp);
  
    for (n = 0; n &lt; pcm-&gt;length; n++)
    {
      s = (pcm-&gt;s[n]) * 2147483648.0;
  
  
      if (s &gt; 2147483647.0)
      {
        s = 2147483647.0;
      }
      else if (s &lt; -2147483647.0)
      {
        s = -2147483647.0;
      }
  
      data = (int)(s + 0.5);
      fwrite(&amp;data, 4, 1, fp);
    }
  
    fclose(fp);
  }
  </code></pre>
  
  <p>↓ wave32.c ↓ </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;math.h&gt;
  #include "wave32.h"
  
  int main(void)
  {
    MONO_PCM pcm0, pcm1;
    int n;
  
    wave_read_32bit_mono(&amp;pcm0, "sine32.wav"); // 1 sec sine wave 
  
    pcm1.fs = pcm0.fs;
    pcm1.bits = pcm0.bits;
    pcm1.length = pcm0.length;
    pcm1.s = calloc(pcm1.length, sizeof(double));
  
    for (n = 0; n &lt; pcm1.length; n++)
    {
  
      pcm1.s[n] = pcm0.s[n];
  
    }
  
    wave_write_32bit_mono(&amp;pcm1, "b.wav");
  
    free(pcm0.s);
    free(pcm1.s);
  
    return 0;
  }
  </code></pre>