# HG changeset patch # User cannam # Date 1200667220 0 # Node ID dfe38135e4c72f1d384ea2d20062b6e4fbe5a9d0 # Parent a251fb0de594051cb59ea2c7bf423af96f024e76 * Add cosine distance and the self-similarity matrix used for SB rhythmic similarity * Pull out SB timbral similarity KL divergence into its own file diff -r a251fb0de594 -r dfe38135e4c7 dsp/rhythm/BeatSpectrum.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsp/rhythm/BeatSpectrum.cpp Fri Jan 18 14:40:20 2008 +0000 @@ -0,0 +1,55 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2008 Kurt Jacobson and QMUL. + All rights reserved. +*/ + +#include "BeatSpectrum.h" + +#include "maths/CosineDistance.h" + +using std::vector; + +vector BeatSpectrum::process(const vector > &m) +{ + int origin = 0; + int sz = m.size()/2; + + int i, j, k; + + vector v(sz); + for (i = 0; i < sz; ++i) v[i] = 0.0; + + CosineDistance cd; + + for (i = origin; i < origin + sz; ++i) { + + k = 0; + + for (j = i + 1; j < i + sz + 1; ++j) { + + v[k++] += cd.distance(m[i], m[j]); + } + } + + // normalize + + double max = 0.0; + + for (i = 0; i < sz; ++i) { + if (v[i] > max) max = v[i]; + } + + if (max > 0.0) { + for (i = 0; i < sz; ++i) { + v[i] /= max; + } + } + + return v; +} + diff -r a251fb0de594 -r dfe38135e4c7 dsp/rhythm/BeatSpectrum.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsp/rhythm/BeatSpectrum.h Fri Jan 18 14:40:20 2008 +0000 @@ -0,0 +1,35 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2008 Kurt Jacobson and QMUL. + All rights reserved. +*/ + +#ifndef BEATSPECTRUM_H +#define BEATSPECTRUM_H + +#include + +/** + * Given a matrix of "feature values", calculate a self-similarity + * vector. The resulting vector will have half as many elements as + * the number of columns in the matrix. This is based on the + * SoundBite rhythmic similarity code. + */ + +class BeatSpectrum +{ +public: + BeatSpectrum(); + ~BeatSpectrum(); + + std::vector process(const std::vector > &inmatrix); + +}; + +#endif + + diff -r a251fb0de594 -r dfe38135e4c7 maths/CosineDistance.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maths/CosineDistance.cpp Fri Jan 18 14:40:20 2008 +0000 @@ -0,0 +1,47 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2008 Kurt Jacobson. + All rights reserved. +*/ + +#include "CosineDistance.h" + +#include +#include + +using std::cerr; + +double CosineDistance::distance(const vector &v1, + const vector &v2) +{ + dist = 1.0; dDenTot = 0; dDen1 = 0; dDen2 = 0; dSum1 =0; + + //check if v1, v2 same size + if (v1.size() != v2.size()) + { + cerr << "CosineDistance::distance: ERROR: vectors not the same size\n"; + return 1.0; + } + else + { + for(int i=0; i +#include + +using std::vector; + +class CosineDistance +{ +public: + CosineDistance() { } + ~CosineDistance() { } + + double distance(const vector &v1, const vector &v2); + +protected: + double dist, dDenTot, dDen1, dDen2, dSum1; +}; + +#endif + diff -r a251fb0de594 -r dfe38135e4c7 maths/KLDivergence.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maths/KLDivergence.cpp Fri Jan 18 14:40:20 2008 +0000 @@ -0,0 +1,30 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2008 QMUL + All rights reserved. +*/ + +#include "KLDivergence.h" + +double KLDivergence::distance(const vector &m1, + const vector &v1, + const vector &m2, + const vector &v2) +{ + int sz = m1.size(); + + double d = -2.0 * sz; + + for (int k = 0; k < sz; ++k) { + d += v1[k] / v2[k] + v2[k] / v1[k]; + d += (m1[k] - m2[k]) * (1.0 / v1[k] + 1.0 / v2[k]) * (m1[k] - m2[k]); + } + + d /= 2.0; + + return d; +} diff -r a251fb0de594 -r dfe38135e4c7 maths/KLDivergence.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maths/KLDivergence.h Fri Jan 18 14:40:20 2008 +0000 @@ -0,0 +1,37 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2008 QMUL + All rights reserved. +*/ + +#ifndef KLDIVERGENCE_H +#define KLDIVERGENCE_H + +#include + +using std::vector; + +/** + * Calculate a symmetrised Kullback-Leibler divergence of Gaussian + * models based on mean and variance vectors. All input vectors must + * be of equal size. + */ + +class KLDivergence +{ +public: + KLDivergence() { } + ~KLDivergence() { } + + double distance(const vector &means1, + const vector &variances1, + const vector &means2, + const vector &variances2); +}; + +#endif + diff -r a251fb0de594 -r dfe38135e4c7 qm-dsp.pro --- a/qm-dsp.pro Fri Jan 18 13:24:12 2008 +0000 +++ b/qm-dsp.pro Fri Jan 18 14:40:20 2008 +0000 @@ -31,6 +31,7 @@ dsp/onsets/PeakPicking.h \ dsp/phasevocoder/PhaseVocoder.h \ dsp/rateconversion/Decimator.h \ + dsp/rhythm/BeatSpectrum.h \ dsp/segmentation/cluster_melt.h \ dsp/segmentation/ClusterMeltSegmenter.h \ dsp/segmentation/cluster_segmenter.h \ @@ -48,7 +49,9 @@ dsp/transforms/FFT.h \ hmm/hmm.h \ maths/Correlation.h \ + maths/CosineDistance.h \ maths/Histogram.h \ + maths/KLDivergence.h \ maths/MathAliases.h \ maths/MathUtilities.h \ maths/Polyfit.h \ @@ -63,6 +66,7 @@ dsp/onsets/PeakPicking.cpp \ dsp/phasevocoder/PhaseVocoder.cpp \ dsp/rateconversion/Decimator.cpp \ + dsp/rhythm/BeatSpectrum.cpp \ dsp/segmentation/cluster_melt.c \ dsp/segmentation/ClusterMeltSegmenter.cpp \ dsp/segmentation/cluster_segmenter.c \ @@ -79,5 +83,7 @@ dsp/transforms/FFT.cpp \ hmm/hmm.c \ maths/Correlation.cpp \ + maths/CosineDistance.cpp \ + maths/KLDivergence.cpp \ maths/MathUtilities.cpp \ maths/pca/pca.c