home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Sound / SoX / Source / stat.c < prev    next >
C/C++ Source or Header  |  1999-07-18  |  5KB  |  212 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12.  * Sound Tools statistics "effect" file.
  13.  *
  14.  * Build various statistics on file and print them.
  15.  * No output.
  16.  */
  17.  
  18. #include "st.h"
  19.  
  20. /* Private data for STAT effect */
  21. typedef struct statstuff {
  22.     LONG    min, max, mean;        /* amplitudes */
  23.     LONG    dmin, dmax, dmean;    /* deltas */
  24.     LONG    last;            /* previous sample */
  25.     int    first;
  26.     int    total;
  27.     int    volume;
  28.         ULONG   bin[4];
  29. } *stat_t;
  30.  
  31. #define    abs(val)    (((val) < 0) ? -(val) : (val))
  32.  
  33. /*
  34.  * Process options
  35.  */
  36. void stat_getopts(effp, n, argv) 
  37. eff_t effp;
  38. int n;
  39. char **argv;
  40. {
  41.     stat_t stat = (stat_t) effp->priv;
  42.  
  43.     stat->volume = 0;
  44.     if (n)
  45.     {
  46.         if (!(strcmp(argv[0], "-v")))
  47.             stat->volume = 1;
  48.         else if (!(strcmp(argv[0], "debug")))
  49.             stat->volume = 2;
  50.         else
  51.             fail("Summary effect only allows debug or -v as options.");
  52.     }
  53. }
  54.  
  55. /*
  56.  * Prepare processing.
  57.  */
  58. void stat_start(effp)
  59. eff_t effp;
  60. {
  61.     stat_t stat = (stat_t) effp->priv;
  62.         int i;
  63.  
  64.     stat->min = stat->dmin = 0x7fffffffL;
  65.     stat->max = stat->dmax = 0x80000000L;
  66.     stat->first = 1;
  67.  
  68.     for (i = 0; i < 4; i++)
  69.         stat->bin[i] = 0;
  70.  
  71. }
  72.  
  73. /*
  74.  * Processed signed long samples from ibuf to obuf.
  75.  * Return number of samples processed.
  76.  */
  77.  
  78. void stat_flow(effp, ibuf, obuf, isamp, osamp)
  79. eff_t effp;
  80. LONG *ibuf, *obuf;
  81. int *isamp, *osamp;
  82. {
  83.     stat_t stat = (stat_t) effp->priv;
  84.     int len, done;
  85.     LONG samp, delta;
  86.     short count;
  87.  
  88.     count = 0;
  89.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  90.     for(done = 0; done < len; done++) {
  91.         /* work in absolute levels for both sample and delta */
  92.         samp = *ibuf++;
  93.             *obuf++ = samp;
  94.  
  95.         if (stat->volume == 2)
  96.         {
  97. #ifdef __alpha__
  98.             fprintf(stderr,"%8x ",samp);
  99. #else
  100.             fprintf(stderr,"%8lx ",samp);
  101. #endif
  102.             if (count++ == 5)
  103.             {
  104.                 fprintf(stderr,"\n");
  105.             count = 0;
  106.             }
  107.         }
  108.  
  109.                 stat->bin[RIGHT(samp,30)+2]++;
  110.  
  111.         samp = abs(samp);
  112.         if (samp < stat->min)
  113.             stat->min = samp;
  114.         if (samp > stat->max)
  115.             stat->max = samp;
  116.         if (stat->first) {
  117.             stat->first = 0;
  118.             stat->mean = samp;
  119.             stat->dmean = 0;
  120.         } else  {
  121.             /* overflow avoidance */
  122.             if ((stat->mean > 0x20000000L) || (samp > 0x20000000L))
  123.                 stat->mean = stat->mean/2 + samp/2;
  124.             else
  125.                 stat->mean = (stat->mean + samp)/2;
  126.  
  127.             delta = abs(samp - stat->last);
  128.             if (delta < stat->dmin)
  129.                 stat->dmin = delta;
  130.             if (delta > stat->dmax)
  131.                 stat->dmax = delta;
  132.             /* overflow avoidance */
  133.             if ((delta > 0x20000000L) || (stat->dmean > 0x20000000L))
  134.                 stat->dmean = stat->dmean/2 + delta/2;
  135.             else
  136.                 stat->dmean = (stat->dmean + delta)/2;
  137.         }
  138.         stat->last = samp;
  139.     }
  140.     /* Process all samples */
  141. }
  142.  
  143. /*
  144.  * Do anything required when you stop reading samples.  
  145.  * Don't close input file! 
  146.  */
  147. void
  148. stat_stop(effp)
  149. eff_t effp;
  150. {
  151.     stat_t stat = (stat_t) effp->priv;
  152.     double amp, range;
  153.         float x;
  154.  
  155.     stat->min   = RIGHT(stat->min, 16);
  156.     stat->max   = RIGHT(stat->max, 16);
  157.     stat->mean  = RIGHT(stat->mean, 16);
  158.     stat->dmin  = RIGHT(stat->dmin, 16);
  159.     stat->dmax  = RIGHT(stat->dmax, 16);
  160.     stat->dmean = RIGHT(stat->dmean, 16);
  161.  
  162.     range = 32767.0;
  163.  
  164.     amp = - stat->min;
  165.     if (amp < stat->max)
  166.         amp = stat->max;
  167.     /* Just print the volume adjustment */
  168.     if (stat->volume == 1) {
  169.         fprintf(stderr, "%.3f\n", 32767.0/amp);
  170.         return;
  171.     }
  172.     else if (stat->volume == 2) {
  173.         fprintf(stderr, "\n");
  174.     }
  175.     /* print them out */
  176.     fprintf(stderr, "Maximum amplitude: %.3f\n", stat->max/range);
  177.     fprintf(stderr, "Minimum amplitude: %.3f\n", stat->min/range);
  178.     fprintf(stderr, "Mean    amplitude: %.3f\n", stat->mean/range);
  179.  
  180.     fprintf(stderr, "Maximum delta:     %.3f\n", stat->dmax/range);
  181.     fprintf(stderr, "Minimum delta:     %.3f\n", stat->dmin/range);
  182.     fprintf(stderr, "Mean    delta:     %.3f\n", stat->dmean/range);
  183.  
  184.     fprintf(stderr, "Volume adjustment: %.3f\n", 32767.0/amp);
  185.  
  186.         if (stat->bin[2] == 0 && stat->bin[3] == 0)
  187.                 fprintf(stderr, "\nProbably text, not sound\n");
  188.         else {
  189.  
  190.                 x = (float)(stat->bin[0] + stat->bin[3]) / (float)(stat->bin[1] + stat->bin[2]);
  191.  
  192.                 if (x >= 3.0)                        /* use opposite style */
  193.                         if (effp->ininfo.style == UNSIGNED)
  194.                                 printf ("\nTry: -t raw -b -s \n");
  195.                         else
  196.                                 printf ("\nTry: -t raw -b -u \n");
  197.  
  198.                 else if (x <= 1.0/3.0);              /* correctly decoded */
  199.  
  200.                 else if (x >= 0.5 && x <= 2.0)       /* use ULAW */
  201.                         if (effp->ininfo.style == ULAW)
  202.                                 printf ("\nTry: -t raw -b -u \n");
  203.                         else
  204.                                 printf ("\nTry: -t raw -b -U \n");
  205.  
  206.                 else    
  207.                         fprintf (stderr, "\nCan't guess the type\n");
  208.         }
  209.  
  210. }
  211.  
  212.