home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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);
- }
-
-
-
-