blob: ca56df09b302eb49cf8c9b81064b45cc116bee8d
1 | /* |
2 | * This file is part of FFmpeg. |
3 | * |
4 | * FFmpeg is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * FFmpeg is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with FFmpeg; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include <stdio.h> |
20 | #include <stdlib.h> |
21 | #include <string.h> |
22 | #include <math.h> |
23 | #include <inttypes.h> |
24 | |
25 | #define FFMIN(a,b) ((a) > (b) ? (b) : (a)) |
26 | #define FFMAX(a,b) ((a) > (b) ? (a) : (b)) |
27 | |
28 | static int64_t fsize(FILE *f){ |
29 | int64_t end, pos= ftell(f); |
30 | fseek(f, 0, SEEK_END); |
31 | end = ftell(f); |
32 | fseek(f, pos, SEEK_SET); |
33 | return end; |
34 | } |
35 | |
36 | int main(int argc, char **argv){ |
37 | FILE *f[2]; |
38 | int i, pos; |
39 | int siglen, datlen; |
40 | int bestpos = 0; |
41 | double bestc=0; |
42 | double sigamp= 0; |
43 | int16_t *signal, *data; |
44 | int maxshift= 16384; |
45 | |
46 | if (argc < 3) { |
47 | printf("audiomatch <testfile> <reffile>\n"); |
48 | printf("WAV headers are skipped automatically.\n"); |
49 | return 1; |
50 | } |
51 | |
52 | f[0] = fopen(argv[1], "rb"); |
53 | f[1] = fopen(argv[2], "rb"); |
54 | if (!f[0] || !f[1]) { |
55 | fprintf(stderr, "Could not open input files.\n"); |
56 | return 1; |
57 | } |
58 | |
59 | for (i = 0; i < 2; i++) { |
60 | uint8_t p[100]; |
61 | if (fread(p, 1, 12, f[i]) != 12) |
62 | return 1; |
63 | if (!memcmp(p, "RIFF", 4) && |
64 | !memcmp(p + 8, "WAVE", 4)) { |
65 | if (fread(p, 1, 8, f[i]) != 8) |
66 | return 1; |
67 | while (memcmp(p, "data", 4)) { |
68 | int s = p[4] | p[5] << 8 | p[6] << 16 | p[7] << 24; |
69 | fseek(f[i], s, SEEK_CUR); |
70 | if (fread(p, 1, 8, f[i]) != 8) |
71 | return 1; |
72 | } |
73 | } else { |
74 | fseek(f[i], -12, SEEK_CUR); |
75 | } |
76 | } |
77 | |
78 | datlen = fsize(f[0]) - ftell(f[0]); |
79 | siglen = fsize(f[1]) - ftell(f[1]); |
80 | data = malloc(datlen * sizeof(*data)); |
81 | signal = malloc(siglen * sizeof(*signal)); |
82 | |
83 | fread(data , 1, datlen, f[0]); |
84 | fread(signal, 1, siglen, f[1]); |
85 | datlen /= 2; |
86 | siglen /= 2; |
87 | |
88 | for(i=0; i<siglen; i++){ |
89 | signal[i] = ((uint8_t*)(signal + i))[0] + 256*((uint8_t*)(signal + i))[1]; |
90 | sigamp += signal[i] * signal[i]; |
91 | } |
92 | for(i=0; i<datlen; i++) |
93 | data[i] = ((uint8_t*)(data + i))[0] + 256*((uint8_t*)(data + i))[1]; |
94 | |
95 | for(pos = 0; pos<maxshift; pos = pos < 0 ? -pos: -pos-1){ |
96 | int64_t c= 0; |
97 | int testlen = FFMIN(siglen, datlen-pos); |
98 | for(i=FFMAX(0, -pos); i<testlen; i++){ |
99 | int j= pos+i; |
100 | c += signal[i] * data[j]; |
101 | } |
102 | if(fabs(c) > sigamp * 0.94) |
103 | maxshift = FFMIN(maxshift, fabs(pos)+32); |
104 | if(fabs(c)>fabs(bestc)){ |
105 | bestc= c; |
106 | bestpos = pos; |
107 | } |
108 | } |
109 | printf("presig: %d postsig:%d c:%7.4f lenerr:%d\n", bestpos, datlen - siglen - bestpos, bestc / sigamp, datlen - siglen); |
110 | } |
111 |