home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / sound / sox / source / c / stat < prev    next >
Encoding:
Text File  |  1994-06-05  |  4.5 KB  |  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. /*
  53.  * Prepare processing.
  54.  */
  55. stat_start(effp)
  56. eff_t effp;
  57. {
  58.     stat_t stat = (stat_t) effp->priv;
  59.         int i;
  60.  
  61.     stat->min = stat->dmin = 0x7fffffff;
  62.     stat->max = stat->dmax = 0x80000000;
  63.     stat->first = 1;
  64.  
  65.         for (i = 0; i < 4; i++)
  66.                 stat->bin[i] = 0;
  67. }
  68.  
  69. /*
  70.  * Processed signed long samples from ibuf to obuf.
  71.  * Return number of samples processed.
  72.  */
  73.  
  74. stat_flow(effp, ibuf, obuf, isamp, osamp)
  75. eff_t effp;
  76. long *ibuf, *obuf;
  77. int *isamp, *osamp;
  78. {
  79.     stat_t stat = (stat_t) effp->priv;
  80.     int len, done;
  81.     long samp, delta;
  82.  
  83.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  84.     for(done = 0; done < len; done++) {
  85.         /* work in absolute levels for both sample and delta */
  86.         samp = *ibuf++;
  87.             *obuf++ = samp;
  88.  
  89.                 stat->bin[RIGHT(samp,30)+2]++;
  90.  
  91.         samp = abs(samp);
  92.         if (samp < stat->min)
  93.             stat->min = samp;
  94.         if (samp > stat->max)
  95.             stat->max = samp;
  96.         if (stat->first) {
  97.             stat->first = 0;
  98.             stat->mean = samp;
  99.             stat->dmean = 0;
  100.         } else  {
  101.             /* overflow avoidance */
  102.             if ((stat->mean > 0x20000000) || (samp > 0x20000000))
  103.                 stat->mean = stat->mean/2 + samp/2;
  104.             else
  105.                 stat->mean = (stat->mean + samp)/2;
  106.  
  107.             delta = abs(samp - stat->last);
  108.             if (delta < stat->dmin)
  109.                 stat->dmin = delta;
  110.             if (delta > stat->dmax)
  111.                 stat->dmax = delta;
  112.             /* overflow avoidance */
  113.             if ((delta > 0x20000000) || (stat->dmean > 0x20000000))
  114.                 stat->dmean = stat->dmean/2 + delta/2;
  115.             else
  116.                 stat->dmean = (stat->dmean + delta)/2;
  117.         }
  118.         stat->last = samp;
  119.     }
  120.     /* Process all samples */
  121. }
  122.  
  123. /*
  124.  * Do anything required when you stop reading samples.  
  125.  * Don't close input file! 
  126.  */
  127. void
  128. stat_stop(effp)
  129. eff_t effp;
  130. {
  131.     stat_t stat = (stat_t) effp->priv;
  132.     double amp, range;
  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.