/* pHash, the open source perceptual hash library Copyright (C) 2009 Aetilius, Inc. All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Evan Klinger - eklinger@phash.org David Starkweather - dstarkweather@phash.org */ #include #include #include #include "audiophash.h" #include "phash.h" #define TRUE 1 #define FALSE 0 using namespace std; typedef struct hashpoint { char *filename; uint32_t *hash; int length; } HP; int main(int argc, char **argv) { const char *msg = ph_about(); printf(msg); printf("\n\n"); if (argc < 3) { printf("no args"); printf("usage: %s dir1 dir2\n", argv[0]); return -1; } const float nbsecs = 45.0f; const char *dir_name = argv[1]; // first directory const char *dir_name2 = argv[2]; // second directory const float threshold = 0.30; // ber threshold (0.25-0.35) const int block_size = 256; // number of frames to compare at a time const int sr = 8000; // sample rate to convert the stream const int channels = 1; // number of channels to convert stream int N1; char **files1 = ph_readfilenames(dir_name, N1); int N2; char **files2 = ph_readfilenames(dir_name2, N2); printf("dir1: %s %d\n", dir_name, N1); printf("dir2: %s %d\n", dir_name2, N2); if (N1 != N2) { printf("unequal number files in both directories\n"); return -1; } vector HashList(N1); float *tmpbuf; float *buf = new float[1 << 25]; int buflen = (1 << 25); if (!buf) { printf("unable to alloc buffer storage\n"); return -1; } int hashN = (1 << 26); uint32_t *hashes = new uint32_t[1 << 26]; if (!hashes) { printf("unable to alloc storage for hashes\n"); return -1; } int hash_index = 0; uint32_t *hash1, *hash2; int buflen1, buflen2; int nbframes1, nbframes2; double *ptrC; int Nc; printf("intra distances\n"); for (int i = 0; i < N1; i++) { printf(" files1[%d] = %s\n", i, files1[i]); buflen1 = buflen; tmpbuf = ph_readaudio(files1[i], sr, channels, buf, buflen1, nbsecs); if (!tmpbuf) continue; buf = tmpbuf; hash1 = ph_audiohash(buf, buflen1, hashes, hashN, sr, nbframes1); if (!hash1) continue; hashes += nbframes1; hashN -= nbframes1; HashList[i].filename = files1[i]; HashList[i].hash = hash1; HashList[i].length = nbframes1; printf(" files2[%d] = %s\n", i, files2[i]); buflen2 = buflen; tmpbuf = ph_readaudio(files2[i], sr, channels, buf, buflen2, nbsecs); if (!tmpbuf) continue; buf = tmpbuf; hash2 = ph_audiohash(buf, buflen2, hashes, hashN, sr, nbframes2); if (!hash2) continue; hashes += nbframes2; hashN -= nbframes2; ptrC = ph_audio_distance_ber(hash1, nbframes1, hash2, nbframes2, threshold, block_size, Nc); double maxC = 0.0f; for (int j = 0; j < Nc; j++) { if (ptrC[j] > maxC) maxC = ptrC[j]; } printf("distance %f\n", maxC); printf("********************************\n"); delete[] ptrC; } printf("hit any key to continue\n"); getchar(); for (int i = 0; i < N1; i++) { for (int j = i + 1; j < N1; j++) { ptrC = ph_audio_distance_ber(HashList[i].hash, HashList[i].length, HashList[j].hash, HashList[j].length, threshold, block_size, Nc); double maxC = 0.0f; for (int k = 0; k < Nc; k++) { if (ptrC[k] > maxC) maxC = ptrC[k]; } printf(" %d %d dist = %f\n", i, j, maxC); free(ptrC); } } return 0; }