~x3lectric/xbmc/svn-trunk

« back to all changes in this revision

Viewing changes to lib/liblame/misc/mlame_corr.c

  • Committer: wiso
  • Date: 2010-05-07 16:57:13 UTC
  • Revision ID: svn-v4:568bbfeb-2a22-0410-94d2-cc84cf5bfa90:trunk:29897
copy lame-3.98.4 to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}