home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / Sound / LAME / WarpOS / src / misc / mlame_corr.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-11  |  5.0 KB  |  221 lines

  1. /*
  2.     Bug: 
  3.     - runs only on little endian machines for WAV files
  4.         - Not all WAV files are recognized
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <math.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>
  13. #include <memory.h>
  14.  
  15. typedef signed short stereo [2];
  16. typedef signed short mono;
  17. typedef struct {
  18.     unsigned long long  n;
  19.     long double         x;
  20.     long double         x2;
  21.     long double         y;
  22.     long double         y2;
  23.     long double         xy;
  24. } korr_t;
  25.  
  26. void analyze_stereo ( const stereo* p, size_t len, korr_t* k )
  27. {
  28.     long double  _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0;
  29.     double       t1;
  30.     double       t2;
  31.     
  32.     k -> n  += len;
  33.     
  34.     for ( ; len--; p++ ) {
  35.         _x  += (t1 = (*p)[0]); _x2 += t1 * t1;
  36.         _y  += (t2 = (*p)[1]); _y2 += t2 * t2;
  37.                                _xy += t1 * t2;
  38.     }
  39.     
  40.     k -> x  += _x ;
  41.     k -> x2 += _x2;
  42.     k -> y  += _y ;
  43.     k -> y2 += _y2;
  44.     k -> xy += _xy;
  45. }
  46.  
  47. void analyze_dstereo ( const stereo* p, size_t len, korr_t* k )
  48. {
  49.     static double l0 = 0;
  50.     static double l1 = 0;
  51.     long double   _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0;
  52.     double        t1;
  53.     double        t2;
  54.     
  55.     k -> n  += len;
  56.     
  57.     for ( ; len--; p++ ) {
  58.         _x  += (t1 = (*p)[0] - l0);  _x2 += t1 * t1;
  59.         _y  += (t2 = (*p)[1] - l1);  _y2 += t2 * t2;
  60.                                      _xy += t1 * t2;
  61.     l0   = (*p)[0];
  62.     l1   = (*p)[1];
  63.     }
  64.     
  65.     k -> x  += _x ;
  66.     k -> x2 += _x2;
  67.     k -> y  += _y ;
  68.     k -> y2 += _y2;
  69.     k -> xy += _xy;
  70. }
  71.  
  72.  
  73. void analyze_mono   ( const mono* p, size_t len, korr_t* k )
  74. {
  75.     long double   _x = 0, _x2 = 0;
  76.     double        t1;
  77.     
  78.     k -> n  += len;
  79.     
  80.     for ( ; len--; p++ ) {
  81.         _x  += (t1 = (*p)); _x2 += t1 * t1;
  82.     }
  83.     
  84.     k -> x  += _x ;
  85.     k -> x2 += _x2;
  86.     k -> y  += _x ;
  87.     k -> y2 += _x2;
  88.     k -> xy += _x2;
  89. }
  90.  
  91. void analyze_dmono   ( const mono* p, size_t len, korr_t* k )
  92. {
  93.     static double l0 = 0;
  94.     long double   _x = 0, _x2 = 0;
  95.     double        t1;
  96.     
  97.     k -> n  += len;
  98.     
  99.     for ( ; len--; p++ ) {
  100.         _x  += (t1 = (*p) - l0); _x2 += t1 * t1;
  101.     l0   = *p;
  102.     }
  103.     
  104.     k -> x  += _x ;
  105.     k -> x2 += _x2;
  106.     k -> y  += _x ;
  107.     k -> y2 += _x2;
  108.     k -> xy += _x2;
  109. }
  110.  
  111. int sgn ( long double x )
  112. {
  113.     if ( x > 0 ) return +1;
  114.     if ( x < 0 ) return -1;
  115.     return 0;
  116. }
  117.  
  118. int report ( const korr_t* k )
  119. {
  120.     long double  scale = sqrt ( 1.e5 / (1<<29) ); // Sine Full Scale is +10 dB, 7327 = 100%
  121.     long double  r;
  122.     long double  rd;
  123.     long double  sx;
  124.     long double  sy;
  125.     long double  x;
  126.     long double  y;
  127.     long double  b;
  128.     
  129.     r  = (k->x2*k->n - k->x*k->x) * (k->y2*k->n - k->y*k->y);
  130.     r  = r  > 0.l  ?  (k->xy*k->n - k->x*k->y) / sqrt (r)  :  1.l;
  131.     sx = k->n > 1  ?  sqrt ( (k->x2 - k->x*k->x/k->n) / (k->n - 1) )  :  0.l;
  132.     sy = k->n > 1  ?  sqrt ( (k->y2 - k->y*k->y/k->n) / (k->n - 1) )  :  0.l;
  133.     x  = k->n > 0  ?  k->x/k->n  :  0.l;
  134.     y  = k->n > 0  ?  k->y/k->n  :  0.l;
  135.     
  136.     b  = atan2 ( sy, sx * sgn (r) ) * ( 8 / M_PI);
  137.    
  138. //    6       5        4        3        2
  139. //      _______________________________
  140. //      |\             |             /|
  141. //    7 |   \          |          /   |  1
  142. //      |      \       |       /      |  
  143. //      |         \    |    /         |
  144. //      |            \ | /            |
  145. //    8 |--------------+--------------|  0
  146. //      |            / | \            |
  147. //      |         /    |    \         |
  148. //   -7 |      /       |       \      | -1
  149. //      |   /          |          \   |
  150. //      |/_____________|_____________\|
  151. //
  152. //   -6       -5      -4      -3        -2
  153.     
  154.     if ( r > 0.98 ) {
  155.         printf ("-mm");        // disguised mono file
  156.     return;
  157.     }
  158.     if ( fabs (b-2) > 0.666 ) {
  159.         printf ("-ms");        // low profit for joint stereo
  160.     return;
  161.     }
  162.     if ( r < 0.333 ) {
  163.         printf ("-ms");        // low profit for joint stereo
  164.     return;
  165.     }
  166. }
  167.  
  168. void readfile ( const char* name, int fd )
  169. {
  170.     unsigned short  header [22];
  171.     stereo          s [4096];
  172.     mono            m [8192];
  173.     size_t          samples;
  174.     korr_t          k0;
  175.     korr_t          k1;
  176.     
  177.     memset ( &k0, 0, sizeof(k0) );
  178.     memset ( &k1, 0, sizeof(k1) );
  179.     
  180.     read ( fd, header, sizeof(header) );
  181.     
  182.     switch ( header[11] ) {
  183.     case 1:
  184.         printf ("-mm\n");
  185.         break;
  186.     
  187.     case 2:
  188.         while  ( ( samples = read (fd, s, sizeof(s)) ) > 0 ) {
  189.             analyze_stereo  ( s, samples / sizeof (*s), &k0 );
  190.             analyze_dstereo ( s, samples / sizeof (*s), &k1 );
  191.     }
  192.         report (&k0);
  193.         report (&k1);
  194.     break;
  195.     
  196.     default:
  197.         fprintf ( stderr, "%u Channels not supported: %s\n", header[11], name );
  198.         break;
  199.     }
  200. }
  201.  
  202. int main ( int argc, char** argv )
  203. {
  204.     char*  name;
  205.     int    fd;
  206.     
  207.     if (argc < 2)
  208.         readfile ( "<stdin>", 0 );
  209.     else        
  210.         while ( (name = *++argv) != NULL ) {
  211.         if ( (fd = open ( name, O_RDONLY )) >= 0 ) {
  212.                 readfile ( name, fd );
  213.         close ( fd );
  214.         } else {
  215.             fprintf ( stderr, "Can't open: %s\n", name );
  216.         }
  217.         }
  218.     
  219.     return 0;
  220. }
  221.