/* SndBreak by Jesse Burneko
 * 
 * This utility takes files which are already converted to infocom sound 
 * format but which exceed 65535 bytes in length and breaks them up into 
 * multiple sound files of 65535 bytes in length or shorter so that they may 
 * be played in succession.  This utility is useful in conjunction with SOX a 
 * copy of which may be found at 
 * ftp://ftp.gmd.de/if-archive/infocom/utilities.  SOX will take many popular 
 * sound formats such as .WAV and .AU files and convert them into infocom 
 * format.  However, if the original .wav or .au file exceeds 65535 bytes the 
 * data will be properly translated but the header info on the resulting .snd 
 * file will be incorrect.  SndBreak will take the converted file and break it 
 * up into multiple files attaching a corrected header.
 *
 * This program is free in so much as that it may be modified and distributed 
 * freely provided that I, Jesse Burneko, am identified as the original 
 * author and any modifications are clearly noted.
 * 
 * The syntax of sndbreak is as follows:
 *                     sndbreak sndfile
 * 
 * where:
 *         sndfile is the .snd file to be broken up and is required.
 *
 * The output will be placed in a series of files named sound1.snd, sound2.snd
 * sound3.snd...soundn.snd.
 */

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

#define MAX_DATA_LENGTH 0xfff5
#define MAX_FILE_LENGTH 0xffff
#define true 1
#define false 0

void extractfrequency(short *freq, FILE *snd)
{
  char *skip;
  
  skip = malloc(sizeof(char) * 4);
  
  fread(skip, 1, 4, snd);
  fread(freq, 1, 2, snd);
  fread(skip, 1, 4, snd);
}

void nextfile(char *filename)
{
  static int count = 0;
  char num[4];
  
  count++;
  strcpy(filename, "sound");
  sprintf(num, "%d", count);
  strcat(filename, num);
  strcat(filename, ".snd");
}

void writebytes(short freq, unsigned size, char *data)
{
  const char REPEATS = 1;
  const char BASE_NOTE = 60;
  const short DUMMY = 0;
   
  FILE *tmp;
  char filename[13];
  short flen, dlen;

   
  nextfile(filename);
  tmp = fopen(filename, "w");
  flen = ((short) size) + 8;
  dlen = (short) size;

  fwrite(&flen, 2, 1, tmp);
  fwrite(&REPEATS, 1, 1, tmp);
  fwrite(&BASE_NOTE, 1, 1, tmp);
  fwrite(&freq, 2, 1, tmp);
  fwrite(&DUMMY, 2, 1, tmp);
  fwrite(&dlen, 2, 1, tmp);
  fwrite(data, 1, size, tmp); 
}

FILE *openfile(char *filename)
{
  FILE *tmp;
  char *ptr;

  if((tmp = fopen(filename, "r")) == NULL)
    { 
      fprintf(stderr, "Error: Can not open file %s for input.\n", filename);
      exit(1);
    }
  ptr = strrchr(filename, '.');
  if(ptr == NULL || strcmp(ptr, ".snd") != 0)
    {
      fprintf(stderr, "Error: File %s does not have .snd extension.\n", filename);
      exit(1);
    }
  return tmp;
}

void extractparameters(char **infile, int argc, char *argv[])
{
  if(argc == 1)
    {
      fprintf(stderr, "Error: No input file specified.\n");
      exit(1);
    }
  else
    if(argc == 2)
      *infile = argv[1];
    else
    {
      fprintf(stderr, "Error: Too many parameters specified.\n");
      exit(1);
    }
} 

int containssnd(char *filename)
{
  char *ptr;
 
  ptr = strrchr(filename, '.');
  if(ptr == NULL || strcmp(ptr, ".snd") != 0)
    return false;
  else
    return true;
}
  
void main(int argc, char *argv[])
{
  FILE *snd;
  short frequency;
  unsigned bread;
  char *data;
  char *infile;

  extractparameters(&infile, argc, argv);
  snd = openfile(infile);
  data = malloc(sizeof(char) * MAX_DATA_LENGTH);
  extractfrequency(&frequency, snd);
  while((bread = fread(data, 1, MAX_DATA_LENGTH, snd)) != 0)
    writebytes(frequency, bread, data);
}









