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 >
C/C++ Source or Header  |  1991-07-07  |  8KB  |  377 lines

  1. /*
  2.  * July 5, 1991
  3.  * Copyright 1991 Lance Norskog And Sundry Contributors
  4.  * This source code is freely redistributable and may be used for
  5.  * any purpose.  This copyright notice must be maintained. 
  6.  * Lance Norskog And Sundry Contributors are not responsible for 
  7.  * the consequences of using this software.
  8.  */
  9.  
  10. #include "aux.h"
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <varargs.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16.  
  17. /*
  18.  * AUX main program.
  19.  */
  20.  
  21. float volume = 1.0;    /* expansion coefficient */
  22.  
  23. float amplitude = 1.0;    /* Largest sample so far in intermediate buffer */
  24.  
  25. int summary = 0;    /* print summary of info about input */
  26. int writing = 1;    /* are we writing to a file? */
  27. int verbose = 0;    /* be noisy on stderr */
  28.  
  29. long soundbuf[BUFSIZ];    /* Intermediate processing buffer */
  30.  
  31. char *myname;
  32.  
  33. main(n, args)
  34. int n;
  35. char **args;
  36. {
  37.     ft_t ft;
  38.     char *ifile, *ofile, *itype, *otype;
  39.     char c;
  40.     extern char *optarg;
  41.     extern int optind;
  42.     char *str;
  43.  
  44.     myname = args[0];
  45.     init();
  46.     
  47.     /* We're not talking about any file */
  48.     ft = 0;
  49.     ifile = ofile = NULL;
  50.     while ((c = getopt(n, args, "i:o:r:v:t:suUAbwlfdDxSV")) != -1) {
  51.         switch(c) {
  52.         case 'i':
  53.             ifile = optarg;
  54.             /* Now, all file type info is about input file */
  55.             ft = &informat;
  56.             if ((ft->fp = fopen(ifile, "r")) == NULL)
  57.                 fail("Can't open input file '%s'", ifile);
  58.             break;
  59.         case 'o':
  60.             ofile = optarg;
  61.             /* Now, all file type info is about output file */
  62.             ft = &outformat;    
  63.             unlink(ofile);
  64.             creat(ofile, 0666);
  65.             if ((ft->fp = fopen(ofile, "w")) == NULL)
  66.                 fail("Can't open output file '%s'", ofile);
  67.             writing = 1;
  68.             break;
  69.         case 't':
  70.             if (! ft) usage("-t");
  71.             ft->filetype = optarg;
  72.             if (ft->filetype[0] == '.')
  73.                 ft->filetype++;
  74.             break;
  75.  
  76.         case 'r':
  77.             if (! ft) usage("-r");
  78.             str = optarg;
  79.             ft->rate = atoi(str);
  80.             if (! sscanf(str, "%d", &ft->rate))
  81.                 fail("-r must be given a number");
  82.             break;
  83.         case 'v':
  84.             if (! ft) usage("-v");
  85.             str = optarg;
  86.             if (! sscanf("%e", optarg, &volume))
  87.                 fail("Sample rate value '%s' is not a number",
  88.                     optarg);
  89.             break;
  90.  
  91.         case 'b':
  92.             if (! ft) usage("-b");
  93.             ft->size = BYTE;
  94.             break;
  95.         case 'w':
  96.             if (! ft) usage("-w");
  97.             ft->size = WORD;
  98.             break;
  99.         case 'l':
  100.             if (! ft) usage("-l");
  101.             ft->size = LONG;
  102.             break;
  103.         case 'f':
  104.             if (! ft) usage("-f");
  105.             ft->size = FLOAT;
  106.             break;
  107.         case 'd':
  108.             if (! ft) usage("-d");
  109.             ft->size = DOUBLE;
  110.             break;
  111.         case 'D':
  112.             if (! ft) usage("-D");
  113.             ft->size = IEEE;
  114.             break;
  115.  
  116.         case 's':
  117.             if (! ft) usage("-s");
  118.             ft->style = SIGN2;
  119.             break;
  120.         case 'u':
  121.             if (! ft) usage("-u");
  122.             ft->style = UNSIGNED;
  123.             break;
  124.         case 'U':
  125.             if (! ft) usage("-U");
  126.             ft->style = ULAW;
  127.             break;
  128.         case 'A':
  129.             if (! ft) usage("-A");
  130.             ft->style = ALAW;
  131.             break;
  132.         
  133.         case 'x':
  134.             if (! ft) usage("-x");
  135.             ft->swap = 1;
  136.             break;
  137.         
  138.         case 'S':
  139.             summary = 1;
  140.             /* 
  141.              * If we haven't specifically set an output file yet
  142.              * don't write a file if we're doing a summary.
  143.              */
  144.             if (ft == &informat)
  145.                 writing = 0;
  146.             break;
  147.         case 'V':
  148.             verbose = 1;
  149.             break;
  150.         }
  151.     }
  152.     if (optind < n)
  153.         usage(args[optind]);
  154.  
  155.     /* Check global arguments */
  156.     if (volume <= 0.0)
  157.         fail("Volume must be greater than 0.0");
  158.     informat.seekable  = (filetype(fileno(informat.fp)) == S_IFREG);
  159.     outformat.seekable = (filetype(fileno(outformat.fp)) == S_IFREG); 
  160.  
  161.     /* If file types have not been set with -t, set from file names. */
  162.     if (! informat.filetype) {
  163.         if (informat.filetype = strrchr(ifile, '/'))
  164.             informat.filetype++;
  165.         else
  166.             informat.filetype = ifile;
  167.         if (informat.filetype = strchr(informat.filetype, '.'))
  168.             informat.filetype++;
  169.     }
  170.     if (! outformat.filetype) {
  171.         if (outformat.filetype = strrchr(ofile, '/'))
  172.             outformat.filetype++;
  173.         else
  174.             outformat.filetype = ofile;
  175.         if (outformat.filetype = strchr(outformat.filetype, '.'))
  176.             outformat.filetype++;
  177.     }
  178.  
  179.     process();
  180.     if (summary)
  181.         summarize();
  182.     exit(0);
  183. }
  184.  
  185. init() {
  186.  
  187.     /* init files */
  188.     informat.rate      = outformat.rate  = 0.0;
  189. /*    informat.scale     = outformat.scale = 1.0; */
  190.     informat.size      = outformat.size  = -1;
  191.     informat.style     = outformat.style = -1;
  192.     informat.channels  = outformat.channels = 1;    /* default to 1 */
  193.     informat.swap      = 0;
  194.     informat.filetype  = outformat.filetype  = (char *) 0;
  195.     informat.fp        = stdin;
  196.     informat.fp        = stdout;
  197.     informat.which     = "input";
  198.     outformat.which    = "output";
  199. }
  200.  
  201. process() {
  202.     long len;
  203.  
  204.     gettype(&informat);
  205.     gettype(&outformat);
  206.     /* Read and write starters can change their formats. */
  207.     (* informat.h->startread)(&informat);
  208.     checkformat(&informat);
  209.     copyformat(&informat, &outformat);
  210.     if (writing) 
  211.         (* outformat.h->startwrite)(&outformat);
  212.     checkformat(&outformat);
  213.     cmpformats(&informat, &outformat);
  214.     report("Output file: using sample rate %d\n\tsize %s, style %s, %d %s",
  215.         outformat.rate, sizes[outformat.size], 
  216.         styles[outformat.style], outformat.channels, 
  217.         (outformat.channels > 1) ? "channels" : "channel");
  218.     while((len = (* informat.h->read)(&informat, soundbuf, BUFSIZ)) > 0)
  219.         if (writing) 
  220.             (* outformat.h->write)(&outformat, soundbuf, len);
  221.     (* informat.h->stopread)(&informat);
  222.     fclose(informat.fp);
  223.     if (writing)
  224.         (* outformat.h->stopwrite)(&outformat);
  225.     if (writing)
  226.         fclose(outformat.fp);
  227. }
  228.  
  229. summarize() {
  230.     /* What would you like to see here? */;
  231. }
  232.  
  233. /*
  234.  * Check that we have a known format suffix string.
  235.  */
  236. gettype(formp)
  237. struct format *formp;
  238. {
  239.     char **list;
  240.     int i;
  241.     extern struct handler handlers[];
  242.  
  243.     if (! formp->filetype)
  244. fail("Must give file type for %s file, either as suffix or with -t option",
  245. formp->which);
  246.     for(i = 0; handlers[i].names; i++) {
  247.         for(list = handlers[i].names; *list; list++) {
  248.             char *s1 = *list, *s2 = formp->filetype;
  249.             while(*s1 && *s2 && (tolower(*s1) == tolower(*s2)))
  250.                 s1++, s2++;
  251.             if (*s1 || *s2)
  252.                 continue;    /* not a match */
  253.             break;
  254.         }
  255.         if (! *list)
  256.             continue;
  257.         /* Found it! */
  258.         formp->h = &handlers[i];
  259.         return;
  260.     }
  261.     fail("File type '%s' of %s file is not known!",
  262.         formp->filetype, formp->which);
  263. }
  264.  
  265. copyformat(ft, ft2)
  266. ft_t ft, ft2;
  267. {
  268.     int noise = 0;
  269.     if (ft2->rate == 0.0) {
  270.         ft2->rate = ft->rate;
  271.         noise = 1;
  272.     }
  273.     if (outformat.size == -1) {
  274.         ft2->size = ft->size;
  275.         noise = 1;
  276.     }
  277.     if (outformat.style == -1) {
  278.         ft2->style = ft->style;
  279.         noise = 1;
  280.     }
  281.     if (outformat.channels == -1) {
  282.         ft2->channels = ft->channels;
  283.         noise = 1;
  284.     }
  285.     return noise;
  286. }
  287.  
  288. cmpformats(ft, ft2)
  289. ft_t ft, ft2;
  290. {
  291.     int noise = 0;
  292.     float abs;
  293.  
  294.     abs = ft->rate - ft2->rate;
  295.     if (abs < 0.0)
  296.         abs = -abs;
  297.     /* Allow slop for cumulative rounding errors: they happen! */
  298.     if (abs > 10.0)
  299.         fail("Sampling rates are different: %d hz -> %d hz",
  300.             ft->rate, ft2->rate);
  301. }
  302.  
  303. /* check that all settings have been given */
  304. checkformat(ft) 
  305. ft_t ft;
  306. {
  307.     if (ft->rate == 0.0)
  308.         fail("Sampling rate for %s file was not given\n", ft->which);
  309.     if ((ft->rate < 100) || (ft->rate > 50000))
  310.         fail("Sampling rate %f for %s file is bogus\n", 
  311.             ft->rate, ft->which);
  312.     if (ft->size == -1)
  313.         fail("Data size was not given for %s file\n\
  314.             Use one of -b/-w/-l/-f/-d/-D", ft->which);
  315.     if (ft->channels == -1)
  316.         fail("Number of output channels was not given for %s file",
  317.             ft->which);
  318.     if (ft->style == -1)
  319.         fail("Data style was not given for %s file\n\
  320.             Use one of -s/-u/-U/-A", ft->which);
  321. }
  322.  
  323. filetype(fd)
  324. int fd;
  325. {
  326.     struct stat st;
  327.  
  328.     fstat(fd, &st);
  329.  
  330.     return st.st_mode & S_IFMT;
  331. }
  332.  
  333. char *usagestr = 
  334. "-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";
  335.  
  336. usage(opt)
  337. char *opt;
  338. {
  339.     fprintf(stderr, "Usage: %s", usagestr);
  340.     fprintf(stderr, "\nFailed at: %s\n", opt);
  341.     exit(1);
  342. }
  343.  
  344. report(va_alist) 
  345. va_dcl
  346. {
  347.     va_list args;
  348.     char *fmt;
  349.  
  350.     if (! verbose)
  351.         return;
  352.     fprintf(stderr, "%s: ", myname);
  353.     va_start(args);
  354.     fmt = va_arg(args, char *);
  355.     vfprintf(stderr, fmt, args);
  356.     va_end(args);
  357.     fprintf(stderr, "\n");
  358. }
  359.  
  360. fail(va_alist) 
  361. va_dcl
  362. {
  363.     va_list args;
  364.     char *fmt;
  365.  
  366.     fprintf(stderr, "%s: ", myname);
  367.     va_start(args);
  368.     fmt = va_arg(args, char *);
  369.     vfprintf(stderr, fmt, args);
  370.     va_end(args);
  371.     fprintf(stderr, "\n");
  372.     exit(2);
  373. }
  374.  
  375.  
  376.  
  377.