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#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) 28 29static int64_t fsize(FILE *f) { 30 int64_t end, pos = ftell(f); 31 fseek(f, 0, SEEK_END); 32 end = ftell(f); 33 fseek(f, pos, SEEK_SET); 34 return end; 35} 36 37int main(int argc, char **argv) { 38 FILE *f[2]; 39 int i, pos; 40 int siglen, datlen; 41 int bestpos = 0; 42 double bestc = 0; 43 double sigamp = 0; 44 int16_t *signal, *data; 45 int maxshift = 16384; 46 47 if (argc < 3) { 48 printf("audiomatch <testfile> <reffile>\n"); 49 printf("WAV headers are skipped automatically.\n"); 50 return 1; 51 } 52 53 f[0] = fopen(argv[1], "rb"); 54 f[1] = fopen(argv[2], "rb"); 55 if (!f[0] || !f[1]) { 56 fprintf(stderr, "Could not open input files.\n"); 57 return 1; 58 } 59 60 for (i = 0; i < 2; i++) { 61 uint8_t p[100]; 62 if (fread(p, 1, 12, f[i]) != 12) 63 return 1; 64 if (!memcmp(p, "RIFF", 4) && 65 !memcmp(p + 8, "WAVE", 4)) { 66 if (fread(p, 1, 8, f[i]) != 8) 67 return 1; 68 while (memcmp(p, "data", 4)) { 69 int s = p[4] | p[5] << 8 | p[6] << 16 | p[7] << 24; 70 fseek(f[i], s, SEEK_CUR); 71 if (fread(p, 1, 8, f[i]) != 8) 72 return 1; 73 } 74 } else { 75 fseek(f[i], -12, SEEK_CUR); 76 } 77 } 78 79 datlen = fsize(f[0]) - ftell(f[0]); 80 siglen = fsize(f[1]) - ftell(f[1]); 81 data = malloc(datlen * sizeof(*data)); 82 signal = malloc(siglen * sizeof(*signal)); 83 84 if (fread(data , 1, datlen, f[0]) != datlen) 85 goto read_fail; 86 if (fread(signal, 1, siglen, f[1]) != siglen) 87 goto read_fail; 88 datlen /= 2; 89 siglen /= 2; 90 91 for (i = 0; i < siglen; i++) { 92 signal[i] = ((uint8_t*)(signal + i))[0] + 256*((uint8_t*)(signal + i))[1]; 93 sigamp += signal[i] * signal[i]; 94 } 95 for (i = 0; i < datlen; i++) 96 data[i] = ((uint8_t*)(data + i))[0] + 256*((uint8_t*)(data + i))[1]; 97 98 for (pos = 0; pos < maxshift; pos = pos < 0 ? -pos: -pos-1) { 99 int64_t c = 0; 100 int testlen = FFMIN(siglen, datlen-pos); 101 for (i = FFMAX(0, -pos); i < testlen; i++) { 102 int j = pos + i; 103 c += signal[i] * data[j]; 104 } 105 if (FFABS(c) > sigamp * 0.94) 106 maxshift = FFMIN(maxshift, FFABS(pos)+32); 107 if (FFABS(c) > FFABS(bestc)) { 108 bestc = c; 109 bestpos = pos; 110 } 111 } 112 printf("presig: %d postsig:%d c:%7.4f lenerr:%d\n", bestpos, datlen - siglen - bestpos, bestc / sigamp, datlen - siglen); 113 114 free(data); 115 free(signal); 116 return 0; 117 118read_fail: 119 free(data); 120 free(signal); 121 return 1; 122} 123