
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define STARTNUM    0
#define OUTNSIZE    20

typedef struct wavhead {
  unsigned long     RIFF;
  unsigned long     totalsizem8;
  unsigned long     WAVE;
  unsigned long     fmt;
  unsigned long     fmtsize;
  unsigned short    audiofmt;
  unsigned short    nchannels;
  unsigned long     samplerate;
  unsigned long     byterate;
  unsigned short    blockalign;
  unsigned short    bitspersample;
  unsigned long     data;
  unsigned long     restsize;
}
wavheader;

int main(int argc, char **argv)
{
  FILE *in, *out;
  wavheader *head;
  char *datbuf;
  char outname[OUTNSIZE];
  long datsetlength, rate, size, lastsplit, nextsplit, nextcount;
  int argi;
  
  if( argc< 3 ) {
    fprintf(stderr, "usage: wavsplit <wav file> <split time 1 [sec]> ...\n");
    exit(1);
  }
  
  in= fopen( argv[1], "r");
  head= (wavheader*)malloc(sizeof(wavheader));
  fread(head, sizeof(wavheader), 1L, in);
  if( ferror(in) ) {
    fprintf(stderr, "Error reading wav header.  Aborting.\n");
    exit(1);
  }
  datsetlength= head->blockalign;
  rate= head->samplerate;
  size= head->restsize/head->blockalign;
  datbuf= (char*)malloc(datsetlength);
  nextsplit= 0;
  for( argi= 2; argi<=argc; ++argi )
  {
    lastsplit= nextsplit;
    if( argi< argc )
      nextsplit= (int)floor(strtod(argv[argi], NULL) * rate + 0.5);
    else
      nextsplit= size;
    nextcount= nextsplit - lastsplit;
    if( nextcount< 0L ) {
       fprintf(stderr, "Length of part %d negative.\n", argi-2);
       exit(1);
    }
    head->restsize= nextcount * datsetlength;
    head->totalsizem8= head->restsize + 8L + sizeof(wavheader);
    snprintf(outname, OUTNSIZE, "%02d.wav", STARTNUM+argi-2);
    out= fopen(outname, "w");
    fwrite(head, sizeof(wavheader), 1L, out);
    while( --nextcount >= 0 ) {
      fread(datbuf, datsetlength, 1L, in);
      fwrite(datbuf, datsetlength, 1L, out);
    }
    fclose(out);
    if( ferror(out) ) {
      fprintf(stderr, "Error writing part %d.\n", argi-2);
      exit(1);
    }
    if( ferror(in) ) {
      fprintf(stderr, "Error reading part %d.\n", argi-2);
      exit(1);
    }
  }
  free(datbuf);
  free(head);
  fclose(in);
}






