1 /*
2 * This file is part of libdcadec.
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation; either version 2.1 of the License, or (at your
7 * option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <math.h>
24
25 #define BUF 3000
26 #define HDR 44
27
main(int argc,char ** argv)28 int main(int argc, char **argv)
29 {
30 uint8_t buf1[BUF], buf2[BUF], *p1, *p2;
31 int64_t acc = 0, cnt = 0;
32 size_t r1, r2, i;
33 double ref = 0.0;
34
35 if (argc != 4)
36 goto fail;
37
38 if (strcmp(argv[3], "?")) {
39 char *p;
40 ref = strtod(argv[3], &p);
41 if (*p || p == argv[3])
42 goto fail;
43 }
44
45 FILE *fp1 = fopen(argv[1], "rb");
46 FILE *fp2 = fopen(argv[2], "rb");
47 if (!fp1 || !fp2)
48 goto fail;
49
50 if (fread(buf1, HDR, 1, fp1) != 1 || fread(buf2, HDR, 1, fp2) != 1)
51 goto fail;
52
53 if (memcmp(buf1, buf2, HDR) || memcmp(buf1, "RIFF", 4))
54 goto fail;
55
56 int bps;
57 switch (buf1[34] | (buf1[35] << 8)) {
58 case 16:
59 bps = 2;
60 break;
61 case 24:
62 bps = 3;
63 break;
64 default:
65 goto fail;
66 }
67
68 do {
69 r1 = fread(buf1, 1, BUF, fp1);
70 r2 = fread(buf2, 1, BUF, fp2);
71 if (r1 != r2 || r1 % bps)
72 goto fail;
73
74 for (i = 0, p1 = buf1, p2 = buf2; i < r1 / bps; i++, p1 += bps, p2 += bps) {
75 int64_t d;
76
77 if (bps == 3) {
78 uint32_t u1 = (p1[0] << 8) | (p1[1] << 16) | ((uint32_t)p1[2] << 24);
79 uint32_t u2 = (p2[0] << 8) | (p2[1] << 16) | ((uint32_t)p2[2] << 24);
80 int32_t v1 = (int32_t)u1 >> 8;
81 int32_t v2 = (int32_t)u2 >> 8;
82 d = v1 - v2;
83 } else {
84 int16_t v1 = p1[0] | (p1[1] << 8);
85 int16_t v2 = p2[0] | (p2[1] << 8);
86 d = v1 - v2;
87 }
88
89 acc += d * d;
90 }
91
92 cnt += i;
93 } while (r1 == BUF);
94
95 if (!cnt)
96 goto fail;
97
98 double var = (double)acc / cnt;
99 double dev = sqrt(var);
100 if (strcmp(argv[3], "?")) {
101 if (fabs(dev - ref) > 0.1)
102 goto fail;
103 printf("%s: OK\n", argv[1]);
104 } else {
105 printf("%s: %f\n", argv[1], dev);
106 }
107
108 return 0;
109
110 fail:
111 printf("%s: FAILED\n", argc > 1 ? argv[1] : "???");
112 return 1;
113 }
114