home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / windows3 / mtlabsnd.zip / STAT.C < prev    next >
Text File  |  1993-04-26  |  5KB  |  189 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.         unsigned long bin[4];
  29. } *stat_t;
  30.  
  31. #define    abs(val)    (((val) < 0) ? -(val) : (val))
  32.  
  33. /*
  34.  * Process options
  35.  */
  36. 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.         if (strcmp(argv[0], "-V"))
  46.             stat->volume = 1;
  47.         else
  48.             fail("Summary effect takes no options.");
  49. }
  50.  
  51. /*
  52.  * Prepare processing.
  53.  */
  54. stat_start(effp)
  55. eff_t effp;
  56. {
  57.     stat_t stat = (stat_t) effp->priv;
  58.         int i;
  59.  
  60.     stat->min = stat->dmin = 0x7fffffff;
  61.     stat->max = stat->dmax = 0x80000000;
  62.     stat->first = 1;
  63.  
  64.         for (i = 0; i < 4; i++)
  65.                 stat->bin[i] = 0;
  66. }
  67.  
  68. /*
  69.  * Processed signed long samples from ibuf to obuf.
  70.  * Return number of samples processed.
  71.  */
  72.  
  73. stat_flow(effp, ibuf, obuf, isamp, osamp)
  74. eff_t effp;
  75. long *ibuf, *obuf;
  76. int *isamp, *osamp;
  77. {
  78.     stat_t stat = (stat_t) effp->priv;
  79.     int len, done;
  80.     long samp, delta;
  81.  
  82.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  83.     for(done = 0; done < len; done++) {
  84.         /* work in absolute levels for both sample and delta */
  85.         samp = *ibuf++;
  86.             *obuf++ = samp;
  87.  
  88.                 stat->bin[RIGHT(samp,30)+2]++;
  89.  
  90.         samp = abs(samp);
  91.         if (samp < stat->min)
  92.             stat->min = samp;
  93.         if (samp > stat->max)
  94.             stat->max = samp;
  95.         if (stat->first) {
  96.             stat->first = 0;
  97.             stat->mean = samp;
  98.             stat->dmean = 0;
  99.         } else  {
  100.             /* overflow avoidance */
  101.             if ((stat->mean > 0x20000000) || (samp > 0x20000000))
  102.                 stat->mean = stat->mean/2 + samp/2;
  103.             else
  104.                 stat->mean = (stat->mean + samp)/2;
  105.  
  106.             delta = abs(samp - stat->last);
  107.             if (delta < stat->dmin)
  108.                 stat->dmin = delta;
  109.             if (delta > stat->dmax)
  110.                 stat->dmax = delta;
  111.             /* overflow avoidance */
  112.             if ((delta > 0x20000000) || (stat->dmean > 0x20000000))
  113.                 stat->dmean = stat->dmean/2 + delta/2;
  114.             else
  115.                 stat->dmean = (stat->dmean + delta)/2;
  116.         }
  117.         stat->last = samp;
  118.     }
  119.     /* Process all samples */
  120. }
  121.  
  122. /*
  123.  * Do anything required when you stop reading samples.  
  124.  * Don't close input file! 
  125.  */
  126. void
  127. stat_stop(effp)
  128. eff_t effp;
  129. {
  130.     stat_t stat = (stat_t) effp->priv;
  131.     double amp, range;
  132.         int i;
  133.         float x;
  134.  
  135.     stat->min   = RIGHT(stat->min, 16);
  136.     stat->max   = RIGHT(stat->max, 16);
  137.     stat->mean  = RIGHT(stat->mean, 16);
  138.     stat->dmin  = RIGHT(stat->dmin, 16);
  139.     stat->dmax  = RIGHT(stat->dmax, 16);
  140.     stat->dmean = RIGHT(stat->dmean, 16);
  141.  
  142.     range = 32767.0;
  143.  
  144.     amp = - stat->min;
  145.     if (amp < stat->max)
  146.         amp = stat->max;
  147.     /* Just print the volume adjustment */
  148.     if (stat->volume) {
  149.         fprintf(stderr, "%.3f\n", 32767.0/amp);
  150.         return;
  151.     }
  152.     /* print them out */
  153.     fprintf(stderr, "Maximum amplitude: %.3f\n", stat->max/range);
  154.     fprintf(stderr, "Minimum amplitude: %.3f\n", stat->min/range);
  155.     fprintf(stderr, "Mean    amplitude: %.3f\n", stat->mean/range);
  156.  
  157.     fprintf(stderr, "Maximum delta:     %.3f\n", stat->dmax/range);
  158.     fprintf(stderr, "Minimum delta:     %.3f\n", stat->dmin/range);
  159.     fprintf(stderr, "Mean    delta:     %.3f\n", stat->dmean/range);
  160.  
  161.     fprintf(stderr, "Volume adjustment: %.3f\n", 32767.0/amp);
  162.  
  163.         if (stat->bin[2] == 0 && stat->bin[3] == 0)
  164.                 fprintf(stderr, "\nProbably text, not sound\n");
  165.         else {
  166.  
  167.                 x = (float)(stat->bin[0] + stat->bin[3]) / (float)(stat->bin[1] + stat->bin[2]);
  168.  
  169.                 if (x >= 3.0)                        /* use opposite style */
  170.                         if (effp->ininfo.style == UNSIGNED)
  171.                                 printf ("\nTry: -t raw -b -s \n");
  172.                         else
  173.                                 printf ("\nTry: -t raw -b -u \n");
  174.  
  175.                 else if (x <= 1.0/3.0);              /* correctly decoded */
  176.  
  177.                 else if (x >= 0.5 && x <= 2.0)       /* use ULAW */
  178.                         if (effp->ininfo.style == ULAW)
  179.                                 printf ("\nTry: -t raw -b -u \n");
  180.                         else
  181.                                 printf ("\nTry: -t raw -b -U \n");
  182.  
  183.                 else    
  184.                         fprintf (stderr, "\nCan't guess the type\n");
  185.         }
  186.  
  187. }
  188.  
  189.