/* * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <inttypes.h> #define FFMIN(a,b) ((a) > (b) ? (b) : (a)) #define FFMAX(a,b) ((a) > (b) ? (a) : (b)) static int64_t fsize(FILE *f){ int64_t end, pos= ftell(f); fseek(f, 0, SEEK_END); end = ftell(f); fseek(f, pos, SEEK_SET); return end; } int main(int argc, char **argv){ FILE *f[2]; int i, pos; int siglen, datlen; int bestpos = 0; double bestc=0; double sigamp= 0; int16_t *signal, *data; int maxshift= 16384; if (argc < 3) { printf("audiomatch <testfile> <reffile>\n"); printf("WAV headers are skipped automatically.\n"); return 1; } f[0] = fopen(argv[1], "rb"); f[1] = fopen(argv[2], "rb"); if (!f[0] || !f[1]) { fprintf(stderr, "Could not open input files.\n"); return 1; } for (i = 0; i < 2; i++) { uint8_t p[100]; if (fread(p, 1, 12, f[i]) != 12) return 1; if (!memcmp(p, "RIFF", 4) && !memcmp(p + 8, "WAVE", 4)) { if (fread(p, 1, 8, f[i]) != 8) return 1; while (memcmp(p, "data", 4)) { int s = p[4] | p[5] << 8 | p[6] << 16 | p[7] << 24; fseek(f[i], s, SEEK_CUR); if (fread(p, 1, 8, f[i]) != 8) return 1; } } else { fseek(f[i], -12, SEEK_CUR); } } datlen = fsize(f[0]) - ftell(f[0]); siglen = fsize(f[1]) - ftell(f[1]); data = malloc(datlen * sizeof(*data)); signal = malloc(siglen * sizeof(*signal)); fread(data , 1, datlen, f[0]); fread(signal, 1, siglen, f[1]); datlen /= 2; siglen /= 2; for(i=0; i<siglen; i++){ signal[i] = ((uint8_t*)(signal + i))[0] + 256*((uint8_t*)(signal + i))[1]; sigamp += signal[i] * signal[i]; } for(i=0; i<datlen; i++) data[i] = ((uint8_t*)(data + i))[0] + 256*((uint8_t*)(data + i))[1]; for(pos = 0; pos<maxshift; pos = pos < 0 ? -pos: -pos-1){ int64_t c= 0; int testlen = FFMIN(siglen, datlen-pos); for(i=FFMAX(0, -pos); i<testlen; i++){ int j= pos+i; c += signal[i] * data[j]; } if(fabs(c) > sigamp * 0.94) maxshift = FFMIN(maxshift, fabs(pos)+32); if(fabs(c)>fabs(bestc)){ bestc= c; bestpos = pos; } } printf("presig: %d postsig:%d c:%7.4f lenerr:%d\n", bestpos, datlen - siglen - bestpos, bestc / sigamp, datlen - siglen); }