/* 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);
}