Chris@26: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@26: Chris@26: /* Chris@26: Vamp feature extraction plugin using the MATCH audio alignment Chris@26: algorithm. Chris@26: Chris@26: Centre for Digital Music, Queen Mary, University of London. Chris@26: This file copyright 2007 Simon Dixon, Chris Cannam and QMUL. Chris@26: Chris@26: This program is free software; you can redistribute it and/or Chris@26: modify it under the terms of the GNU General Public License as Chris@26: published by the Free Software Foundation; either version 2 of the Chris@26: License, or (at your option) any later version. See the file Chris@26: COPYING included with this distribution for more information. Chris@26: */ Chris@26: Chris@26: #include "DistanceMetric.h" Chris@26: Chris@26: #include Chris@26: #include Chris@133: #include Chris@26: Chris@133: using namespace std; Chris@26: Chris@140: //#define DEBUG_DISTANCE_METRIC 1 Chris@140: Chris@143: DistanceMetric::DistanceMetric(Parameters params) : Chris@143: m_params(params) Chris@140: { Chris@140: #ifdef DEBUG_DISTANCE_METRIC Chris@143: cerr << "*** DistanceMetric: norm = " << m_params.norm Chris@143: << endl; Chris@140: #endif Chris@140: } Chris@140: Chris@26: double Chris@26: DistanceMetric::calcDistance(const vector &f1, Chris@26: const vector &f2) Chris@26: { Chris@26: double d = 0; Chris@26: double sum = 0; Chris@26: Chris@26: int featureSize = f1.size(); Chris@26: assert(int(f2.size()) == featureSize); Chris@145: Chris@26: for (int i = 0; i < featureSize; i++) { Chris@26: d += fabs(f1[i] - f2[i]); Chris@145: sum += fabs(f1[i]) + fabs(f2[i]); Chris@26: } Chris@26: Chris@145: double noise = 1e-3 * featureSize; Chris@145: d += noise; Chris@145: sum += noise; Chris@145: Chris@143: if (sum == 0) { Chris@26: return 0; Chris@143: } Chris@26: Chris@143: double distance = 0; Chris@26: Chris@143: if (m_params.norm == NormaliseDistanceToSum) { Chris@143: Chris@143: distance = d / sum; // 0 <= d/sum <= 2 Chris@143: Chris@143: } else if (m_params.norm == NormaliseDistanceToLogSum) { Chris@143: Chris@143: // note if this were to be restored, it would have to use Chris@143: // totalEnergies vector instead of f1[freqMapSize] which used to Chris@143: // store the total energy: Chris@143: // double weight = (5 + Math.log(f1[freqMapSize] + f2[freqMapSize]))/10.0; Chris@143: Chris@143: double weight = (8 + log(sum)) / 10.0; Chris@133: Chris@143: if (weight < 0) weight = 0; Chris@143: else if (weight > 1) weight = 1; Chris@26: Chris@143: distance = d / sum * weight; Chris@143: Chris@143: } else { Chris@143: Chris@143: distance = d; Chris@143: } Chris@143: Chris@143: return distance; Chris@26: } Chris@26: