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