📄 mlame_corr.c
字号:
/* Bug: - runs only on little endian machines for WAV files - Not all WAV files are recognized */#include <stdio.h>#include <unistd.h>#include <math.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <memory.h>typedef signed short stereo [2];typedef signed short mono;typedef struct { unsigned long long n; long double x; long double x2; long double y; long double y2; long double xy;} korr_t;void analyze_stereo ( const stereo* p, size_t len, korr_t* k ){ long double _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0; double t1; double t2; k -> n += len; for ( ; len--; p++ ) { _x += (t1 = (*p)[0]); _x2 += t1 * t1; _y += (t2 = (*p)[1]); _y2 += t2 * t2; _xy += t1 * t2; } k -> x += _x ; k -> x2 += _x2; k -> y += _y ; k -> y2 += _y2; k -> xy += _xy;}void analyze_dstereo ( const stereo* p, size_t len, korr_t* k ){ static double l0 = 0; static double l1 = 0; long double _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0; double t1; double t2; k -> n += len; for ( ; len--; p++ ) { _x += (t1 = (*p)[0] - l0); _x2 += t1 * t1; _y += (t2 = (*p)[1] - l1); _y2 += t2 * t2; _xy += t1 * t2; l0 = (*p)[0]; l1 = (*p)[1]; } k -> x += _x ; k -> x2 += _x2; k -> y += _y ; k -> y2 += _y2; k -> xy += _xy;}void analyze_mono ( const mono* p, size_t len, korr_t* k ){ long double _x = 0, _x2 = 0; double t1; k -> n += len; for ( ; len--; p++ ) { _x += (t1 = (*p)); _x2 += t1 * t1; } k -> x += _x ; k -> x2 += _x2; k -> y += _x ; k -> y2 += _x2; k -> xy += _x2;}void analyze_dmono ( const mono* p, size_t len, korr_t* k ){ static double l0 = 0; long double _x = 0, _x2 = 0; double t1; k -> n += len; for ( ; len--; p++ ) { _x += (t1 = (*p) - l0); _x2 += t1 * t1; l0 = *p; } k -> x += _x ; k -> x2 += _x2; k -> y += _x ; k -> y2 += _x2; k -> xy += _x2;}int sgn ( long double x ){ if ( x > 0 ) return +1; if ( x < 0 ) return -1; return 0;}int report ( const korr_t* k ){ long double scale = sqrt ( 1.e5 / (1<<29) ); // Sine Full Scale is +10 dB, 7327 = 100% long double r; long double rd; long double sx; long double sy; long double x; long double y; long double b; r = (k->x2*k->n - k->x*k->x) * (k->y2*k->n - k->y*k->y); r = r > 0.l ? (k->xy*k->n - k->x*k->y) / sqrt (r) : 1.l; sx = k->n > 1 ? sqrt ( (k->x2 - k->x*k->x/k->n) / (k->n - 1) ) : 0.l; sy = k->n > 1 ? sqrt ( (k->y2 - k->y*k->y/k->n) / (k->n - 1) ) : 0.l; x = k->n > 0 ? k->x/k->n : 0.l; y = k->n > 0 ? k->y/k->n : 0.l; b = atan2 ( sy, sx * sgn (r) ) * ( 8 / M_PI); // 6 5 4 3 2// _______________________________// |\ | /|// 7 | \ | / | 1// | \ | / | // | \ | / |// | \ | / |// 8 |--------------+--------------| 0// | / | \ |// | / | \ |// -7 | / | \ | -1// | / | \ |// |/_____________|_____________\|//// -6 -5 -4 -3 -2 if ( r > 0.98 ) { printf ("-mm"); // disguised mono file return; } if ( fabs (b-2) > 0.666 ) { printf ("-ms"); // low profit for joint stereo return; } if ( r < 0.333 ) { printf ("-ms"); // low profit for joint stereo return; }}void readfile ( const char* name, int fd ){ unsigned short header [22]; stereo s [4096]; mono m [8192]; size_t samples; korr_t k0; korr_t k1; memset ( &k0, 0, sizeof(k0) ); memset ( &k1, 0, sizeof(k1) ); read ( fd, header, sizeof(header) ); switch ( header[11] ) { case 1: printf ("-mm\n"); break; case 2: while ( ( samples = read (fd, s, sizeof(s)) ) > 0 ) { analyze_stereo ( s, samples / sizeof (*s), &k0 ); analyze_dstereo ( s, samples / sizeof (*s), &k1 ); } report (&k0); report (&k1); break; default: fprintf ( stderr, "%u Channels not supported: %s\n", header[11], name ); break; }}int main ( int argc, char** argv ){ char* name; int fd; if (argc < 2) readfile ( "<stdin>", 0 ); else while ( (name = *++argv) != NULL ) { if ( (fd = open ( name, O_RDONLY )) >= 0 ) { readfile ( name, fd ); close ( fd ); } else { fprintf ( stderr, "Can't open: %s\n", name ); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -