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

    return 0;
}
