/*
 * 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))
#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))

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;
}
