home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
3
/
3593
/
aux.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-07
|
8KB
|
377 lines
/*
* July 5, 1991
* Copyright 1991 Lance Norskog And Sundry Contributors
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
*/
#include "aux.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <varargs.h>
#include <ctype.h>
#include <string.h>
/*
* AUX main program.
*/
float volume = 1.0; /* expansion coefficient */
float amplitude = 1.0; /* Largest sample so far in intermediate buffer */
int summary = 0; /* print summary of info about input */
int writing = 1; /* are we writing to a file? */
int verbose = 0; /* be noisy on stderr */
long soundbuf[BUFSIZ]; /* Intermediate processing buffer */
char *myname;
main(n, args)
int n;
char **args;
{
ft_t ft;
char *ifile, *ofile, *itype, *otype;
char c;
extern char *optarg;
extern int optind;
char *str;
myname = args[0];
init();
/* We're not talking about any file */
ft = 0;
ifile = ofile = NULL;
while ((c = getopt(n, args, "i:o:r:v:t:suUAbwlfdDxSV")) != -1) {
switch(c) {
case 'i':
ifile = optarg;
/* Now, all file type info is about input file */
ft = &informat;
if ((ft->fp = fopen(ifile, "r")) == NULL)
fail("Can't open input file '%s'", ifile);
break;
case 'o':
ofile = optarg;
/* Now, all file type info is about output file */
ft = &outformat;
unlink(ofile);
creat(ofile, 0666);
if ((ft->fp = fopen(ofile, "w")) == NULL)
fail("Can't open output file '%s'", ofile);
writing = 1;
break;
case 't':
if (! ft) usage("-t");
ft->filetype = optarg;
if (ft->filetype[0] == '.')
ft->filetype++;
break;
case 'r':
if (! ft) usage("-r");
str = optarg;
ft->rate = atoi(str);
if (! sscanf(str, "%d", &ft->rate))
fail("-r must be given a number");
break;
case 'v':
if (! ft) usage("-v");
str = optarg;
if (! sscanf("%e", optarg, &volume))
fail("Sample rate value '%s' is not a number",
optarg);
break;
case 'b':
if (! ft) usage("-b");
ft->size = BYTE;
break;
case 'w':
if (! ft) usage("-w");
ft->size = WORD;
break;
case 'l':
if (! ft) usage("-l");
ft->size = LONG;
break;
case 'f':
if (! ft) usage("-f");
ft->size = FLOAT;
break;
case 'd':
if (! ft) usage("-d");
ft->size = DOUBLE;
break;
case 'D':
if (! ft) usage("-D");
ft->size = IEEE;
break;
case 's':
if (! ft) usage("-s");
ft->style = SIGN2;
break;
case 'u':
if (! ft) usage("-u");
ft->style = UNSIGNED;
break;
case 'U':
if (! ft) usage("-U");
ft->style = ULAW;
break;
case 'A':
if (! ft) usage("-A");
ft->style = ALAW;
break;
case 'x':
if (! ft) usage("-x");
ft->swap = 1;
break;
case 'S':
summary = 1;
/*
* If we haven't specifically set an output file yet
* don't write a file if we're doing a summary.
*/
if (ft == &informat)
writing = 0;
break;
case 'V':
verbose = 1;
break;
}
}
if (optind < n)
usage(args[optind]);
/* Check global arguments */
if (volume <= 0.0)
fail("Volume must be greater than 0.0");
informat.seekable = (filetype(fileno(informat.fp)) == S_IFREG);
outformat.seekable = (filetype(fileno(outformat.fp)) == S_IFREG);
/* If file types have not been set with -t, set from file names. */
if (! informat.filetype) {
if (informat.filetype = strrchr(ifile, '/'))
informat.filetype++;
else
informat.filetype = ifile;
if (informat.filetype = strchr(informat.filetype, '.'))
informat.filetype++;
}
if (! outformat.filetype) {
if (outformat.filetype = strrchr(ofile, '/'))
outformat.filetype++;
else
outformat.filetype = ofile;
if (outformat.filetype = strchr(outformat.filetype, '.'))
outformat.filetype++;
}
process();
if (summary)
summarize();
exit(0);
}
init() {
/* init files */
informat.rate = outformat.rate = 0.0;
/* informat.scale = outformat.scale = 1.0; */
informat.size = outformat.size = -1;
informat.style = outformat.style = -1;
informat.channels = outformat.channels = 1; /* default to 1 */
informat.swap = 0;
informat.filetype = outformat.filetype = (char *) 0;
informat.fp = stdin;
informat.fp = stdout;
informat.which = "input";
outformat.which = "output";
}
process() {
long len;
gettype(&informat);
gettype(&outformat);
/* Read and write starters can change their formats. */
(* informat.h->startread)(&informat);
checkformat(&informat);
copyformat(&informat, &outformat);
if (writing)
(* outformat.h->startwrite)(&outformat);
checkformat(&outformat);
cmpformats(&informat, &outformat);
report("Output file: using sample rate %d\n\tsize %s, style %s, %d %s",
outformat.rate, sizes[outformat.size],
styles[outformat.style], outformat.channels,
(outformat.channels > 1) ? "channels" : "channel");
while((len = (* informat.h->read)(&informat, soundbuf, BUFSIZ)) > 0)
if (writing)
(* outformat.h->write)(&outformat, soundbuf, len);
(* informat.h->stopread)(&informat);
fclose(informat.fp);
if (writing)
(* outformat.h->stopwrite)(&outformat);
if (writing)
fclose(outformat.fp);
}
summarize() {
/* What would you like to see here? */;
}
/*
* Check that we have a known format suffix string.
*/
gettype(formp)
struct format *formp;
{
char **list;
int i;
extern struct handler handlers[];
if (! formp->filetype)
fail("Must give file type for %s file, either as suffix or with -t option",
formp->which);
for(i = 0; handlers[i].names; i++) {
for(list = handlers[i].names; *list; list++) {
char *s1 = *list, *s2 = formp->filetype;
while(*s1 && *s2 && (tolower(*s1) == tolower(*s2)))
s1++, s2++;
if (*s1 || *s2)
continue; /* not a match */
break;
}
if (! *list)
continue;
/* Found it! */
formp->h = &handlers[i];
return;
}
fail("File type '%s' of %s file is not known!",
formp->filetype, formp->which);
}
copyformat(ft, ft2)
ft_t ft, ft2;
{
int noise = 0;
if (ft2->rate == 0.0) {
ft2->rate = ft->rate;
noise = 1;
}
if (outformat.size == -1) {
ft2->size = ft->size;
noise = 1;
}
if (outformat.style == -1) {
ft2->style = ft->style;
noise = 1;
}
if (outformat.channels == -1) {
ft2->channels = ft->channels;
noise = 1;
}
return noise;
}
cmpformats(ft, ft2)
ft_t ft, ft2;
{
int noise = 0;
float abs;
abs = ft->rate - ft2->rate;
if (abs < 0.0)
abs = -abs;
/* Allow slop for cumulative rounding errors: they happen! */
if (abs > 10.0)
fail("Sampling rates are different: %d hz -> %d hz",
ft->rate, ft2->rate);
}
/* check that all settings have been given */
checkformat(ft)
ft_t ft;
{
if (ft->rate == 0.0)
fail("Sampling rate for %s file was not given\n", ft->which);
if ((ft->rate < 100) || (ft->rate > 50000))
fail("Sampling rate %f for %s file is bogus\n",
ft->rate, ft->which);
if (ft->size == -1)
fail("Data size was not given for %s file\n\
Use one of -b/-w/-l/-f/-d/-D", ft->which);
if (ft->channels == -1)
fail("Number of output channels was not given for %s file",
ft->which);
if (ft->style == -1)
fail("Data style was not given for %s file\n\
Use one of -s/-u/-U/-A", ft->which);
}
filetype(fd)
int fd;
{
struct stat st;
fstat(fd, &st);
return st.st_mode & S_IFMT;
}
char *usagestr =
"-i file opts -o file opts [ -V -S ]\nopts: -r rate -v volume -s/-u/-U/-A -b/-w/-l/-f/-d/-D -x\n";
usage(opt)
char *opt;
{
fprintf(stderr, "Usage: %s", usagestr);
fprintf(stderr, "\nFailed at: %s\n", opt);
exit(1);
}
report(va_alist)
va_dcl
{
va_list args;
char *fmt;
if (! verbose)
return;
fprintf(stderr, "%s: ", myname);
va_start(args);
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
fail(va_alist)
va_dcl
{
va_list args;
char *fmt;
fprintf(stderr, "%s: ", myname);
va_start(args);
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
exit(2);
}