Spaces:
Runtime error
Runtime error
/* | |
* 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 | |
*/ | |
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)); | |
if (fread(data , 1, datlen, f[0]) != datlen) | |
goto read_fail; | |
if (fread(signal, 1, siglen, f[1]) != siglen) | |
goto read_fail; | |
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 (FFABS(c) > sigamp * 0.94) | |
maxshift = FFMIN(maxshift, FFABS(pos)+32); | |
if (FFABS(c) > FFABS(bestc)) { | |
bestc = c; | |
bestpos = pos; | |
} | |
} | |
printf("presig: %d postsig:%d c:%7.4f lenerr:%d\n", bestpos, datlen - siglen - bestpos, bestc / sigamp, datlen - siglen); | |
free(data); | |
free(signal); | |
return 0; | |
read_fail: | |
free(data); | |
free(signal); | |
return 1; | |
} | |