/*
 * 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));

    if (fread(data  , 1, datlen, f[0]) != datlen)
        return 1;
    if (fread(signal, 1, siglen, f[1]) != siglen)
        return 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);

    return 0;
}
