ChangeDetectionFunction.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  QM DSP Library
5 
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Martin Gasser.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
17 
19  m_dFilterSigma(0.0), m_iFilterWidth(0)
20 {
22 }
23 
25 {
26 }
27 
29 {
30  m_iFilterWidth = iWidth*2+1;
31 
32  // it is assumed that the gaussian is 0 outside of +/- FWHM
33  // => filter width = 2*FWHM = 2*2.3548*sigma
34  m_dFilterSigma = double(m_iFilterWidth) / double(2*2.3548);
36 
37  double dScale = 1.0 / (m_dFilterSigma*sqrt(2*M_PI));
38 
39  for (int x = -(m_iFilterWidth-1)/2; x <= (m_iFilterWidth-1)/2; x++) {
40  double w = dScale * std::exp ( -(x*x)/(2*m_dFilterSigma*m_dFilterSigma) );
41  m_vaGaussian[x + (m_iFilterWidth-1)/2] = w;
42  }
43 
44 #ifdef DEBUG_CHANGE_DETECTION_FUNCTION
45  std::cerr << "Filter sigma: " << m_dFilterSigma << std::endl;
46  std::cerr << "Filter width: " << m_iFilterWidth << std::endl;
47 #endif
48 }
49 
50 
52 {
53  ChangeDistance retVal;
54  retVal.resize(rTCSGram.getSize(), 0.0);
55 
56  TCSGram smoothedTCSGram;
57 
58  for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) {
59 
60  int iSkipLower = 0;
61 
62  int iLowerPos = iPosition - (m_iFilterWidth-1)/2;
63  int iUpperPos = iPosition + (m_iFilterWidth-1)/2;
64 
65  if (iLowerPos < 0) {
66  iSkipLower = -iLowerPos;
67  iLowerPos = 0;
68  }
69 
70  if (iUpperPos >= rTCSGram.getSize()) {
71  int iMaxIndex = rTCSGram.getSize() - 1;
72  iUpperPos = iMaxIndex;
73  }
74 
75  TCSVector smoothedVector;
76 
77  // for every bin of the vector, calculate the smoothed value
78  for (int iPC = 0; iPC < 6; iPC++) {
79 
80  size_t j = 0;
81  double dSmoothedValue = 0.0;
82  TCSVector rCV;
83 
84  for (int i = iLowerPos; i <= iUpperPos; i++) {
85  rTCSGram.getTCSVector(i, rCV);
86  dSmoothedValue += m_vaGaussian[iSkipLower + j++] * rCV[iPC];
87  }
88 
89  smoothedVector[iPC] = dSmoothedValue;
90  }
91 
92  smoothedTCSGram.addTCSVector(smoothedVector);
93  }
94 
95  for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) {
96 
97  /*
98  TODO: calculate a confidence measure for the current estimation
99  if the current estimate is not confident enough, look further into the future/the past
100  e.g., High frequency content, zero crossing rate, spectral flatness
101  */
102 
103  TCSVector nextTCS;
104  TCSVector previousTCS;
105 
106  int iWindow = 1;
107 
108  // while (previousTCS.magnitude() < 0.1 && (iPosition-iWindow) > 0)
109  {
110  smoothedTCSGram.getTCSVector(iPosition-iWindow, previousTCS);
111  // std::cout << previousTCS.magnitude() << std::endl;
112  iWindow++;
113  }
114 
115  iWindow = 1;
116 
117  // while (nextTCS.magnitude() < 0.1 && (iPosition+iWindow) < (rTCSGram.getSize()-1) )
118  {
119  smoothedTCSGram.getTCSVector(iPosition+iWindow, nextTCS);
120  iWindow++;
121  }
122 
123  double distance = 0.0;
124  // Euclidean distance
125  for (size_t j = 0; j < 6; j++) {
126  distance += std::pow(nextTCS[j] - previousTCS[j], 2.0);
127  }
128 
129  retVal[iPosition] = std::pow(distance, 0.5);
130  }
131 
132  return retVal;
133 }
int getSize() const
Definition: TCSgram.h:37
void addTCSVector(const TCSVector &)
Definition: TCSgram.cpp:52
void getTCSVector(int, TCSVector &) const
Definition: TCSgram.cpp:35
std::valarray< double > ChangeDistance
void setFilterWidth(const int iWidth)
std::valarray< double > m_vaGaussian
ChangeDistance process(const TCSGram &rTCSGram)