comparison dsp/tonal/ChangeDetectionFunction.cpp @ 505:930b5b0f707d

Merge branch 'codestyle-and-tidy'
author Chris Cannam <cannam@all-day-breakfast.com>
date Wed, 05 Jun 2019 12:55:15 +0100
parents 7992d0923626
children
comparison
equal deleted inserted replaced
471:e3335cb213da 505:930b5b0f707d
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #include "ChangeDetectionFunction.h" 16 #include "ChangeDetectionFunction.h"
17 17
18 #ifndef PI
19 #define PI (3.14159265358979232846)
20 #endif
21
22
23
24 ChangeDetectionFunction::ChangeDetectionFunction(ChangeDFConfig config) : 18 ChangeDetectionFunction::ChangeDetectionFunction(ChangeDFConfig config) :
25 m_dFilterSigma(0.0), m_iFilterWidth(0) 19 m_dFilterSigma(0.0), m_iFilterWidth(0)
26 { 20 {
27 setFilterWidth(config.smoothingWidth); 21 setFilterWidth(config.smoothingWidth);
28 } 22 }
29 23
30 ChangeDetectionFunction::~ChangeDetectionFunction() 24 ChangeDetectionFunction::~ChangeDetectionFunction()
31 { 25 {
32 } 26 }
33 27
34 void ChangeDetectionFunction::setFilterWidth(const int iWidth) 28 void ChangeDetectionFunction::setFilterWidth(const int iWidth)
35 { 29 {
36 m_iFilterWidth = iWidth*2+1; 30 m_iFilterWidth = iWidth*2+1;
37 31
38 // it is assumed that the gaussian is 0 outside of +/- FWHM 32 // it is assumed that the gaussian is 0 outside of +/- FWHM
39 // => filter width = 2*FWHM = 2*2.3548*sigma 33 // => filter width = 2*FWHM = 2*2.3548*sigma
40 m_dFilterSigma = double(m_iFilterWidth) / double(2*2.3548); 34 m_dFilterSigma = double(m_iFilterWidth) / double(2*2.3548);
41 m_vaGaussian.resize(m_iFilterWidth); 35 m_vaGaussian.resize(m_iFilterWidth);
42 36
43 double dScale = 1.0 / (m_dFilterSigma*sqrt(2*PI)); 37 double dScale = 1.0 / (m_dFilterSigma*sqrt(2*M_PI));
44 38
45 for (int x = -(m_iFilterWidth-1)/2; x <= (m_iFilterWidth-1)/2; x++) 39 for (int x = -(m_iFilterWidth-1)/2; x <= (m_iFilterWidth-1)/2; x++) {
46 { 40 double w = dScale * std::exp ( -(x*x)/(2*m_dFilterSigma*m_dFilterSigma) );
47 double w = dScale * std::exp ( -(x*x)/(2*m_dFilterSigma*m_dFilterSigma) ); 41 m_vaGaussian[x + (m_iFilterWidth-1)/2] = w;
48 m_vaGaussian[x + (m_iFilterWidth-1)/2] = w; 42 }
49 } 43
50
51 #ifdef DEBUG_CHANGE_DETECTION_FUNCTION 44 #ifdef DEBUG_CHANGE_DETECTION_FUNCTION
52 std::cerr << "Filter sigma: " << m_dFilterSigma << std::endl; 45 std::cerr << "Filter sigma: " << m_dFilterSigma << std::endl;
53 std::cerr << "Filter width: " << m_iFilterWidth << std::endl; 46 std::cerr << "Filter width: " << m_iFilterWidth << std::endl;
54 #endif 47 #endif
55 } 48 }
56 49
57 50
58 ChangeDistance ChangeDetectionFunction::process(const TCSGram& rTCSGram) 51 ChangeDistance ChangeDetectionFunction::process(const TCSGram& rTCSGram)
59 { 52 {
60 ChangeDistance retVal; 53 ChangeDistance retVal;
61 retVal.resize(rTCSGram.getSize(), 0.0); 54 retVal.resize(rTCSGram.getSize(), 0.0);
62 55
63 TCSGram smoothedTCSGram; 56 TCSGram smoothedTCSGram;
64 57
65 for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) 58 for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) {
66 { 59
67 int iSkipLower = 0; 60 int iSkipLower = 0;
68 61
69 int iLowerPos = iPosition - (m_iFilterWidth-1)/2; 62 int iLowerPos = iPosition - (m_iFilterWidth-1)/2;
70 int iUpperPos = iPosition + (m_iFilterWidth-1)/2; 63 int iUpperPos = iPosition + (m_iFilterWidth-1)/2;
71 64
72 if (iLowerPos < 0) 65 if (iLowerPos < 0) {
73 { 66 iSkipLower = -iLowerPos;
74 iSkipLower = -iLowerPos; 67 iLowerPos = 0;
75 iLowerPos = 0; 68 }
76 } 69
77 70 if (iUpperPos >= rTCSGram.getSize()) {
78 if (iUpperPos >= rTCSGram.getSize()) 71 int iMaxIndex = rTCSGram.getSize() - 1;
79 { 72 iUpperPos = iMaxIndex;
80 int iMaxIndex = rTCSGram.getSize() - 1; 73 }
81 iUpperPos = iMaxIndex; 74
82 } 75 TCSVector smoothedVector;
83
84 TCSVector smoothedVector;
85 76
86 // for every bin of the vector, calculate the smoothed value 77 // for every bin of the vector, calculate the smoothed value
87 for (int iPC = 0; iPC < 6; iPC++) 78 for (int iPC = 0; iPC < 6; iPC++) {
88 {
89 size_t j = 0;
90 double dSmoothedValue = 0.0;
91 TCSVector rCV;
92
93 for (int i = iLowerPos; i <= iUpperPos; i++)
94 {
95 rTCSGram.getTCSVector(i, rCV);
96 dSmoothedValue += m_vaGaussian[iSkipLower + j++] * rCV[iPC];
97 }
98 79
99 smoothedVector[iPC] = dSmoothedValue; 80 size_t j = 0;
100 } 81 double dSmoothedValue = 0.0;
101 82 TCSVector rCV;
102 smoothedTCSGram.addTCSVector(smoothedVector); 83
103 } 84 for (int i = iLowerPos; i <= iUpperPos; i++) {
85 rTCSGram.getTCSVector(i, rCV);
86 dSmoothedValue += m_vaGaussian[iSkipLower + j++] * rCV[iPC];
87 }
104 88
105 for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) 89 smoothedVector[iPC] = dSmoothedValue;
106 { 90 }
107 /* 91
108 TODO: calculate a confidence measure for the current estimation 92 smoothedTCSGram.addTCSVector(smoothedVector);
109 if the current estimate is not confident enough, look further into the future/the past 93 }
110 e.g., High frequency content, zero crossing rate, spectral flatness
111 */
112
113 TCSVector nextTCS;
114 TCSVector previousTCS;
115
116 int iWindow = 1;
117 94
118 // while (previousTCS.magnitude() < 0.1 && (iPosition-iWindow) > 0) 95 for (int iPosition = 0; iPosition < rTCSGram.getSize(); iPosition++) {
119 { 96
120 smoothedTCSGram.getTCSVector(iPosition-iWindow, previousTCS); 97 /*
121 // std::cout << previousTCS.magnitude() << std::endl; 98 TODO: calculate a confidence measure for the current estimation
122 iWindow++; 99 if the current estimate is not confident enough, look further into the future/the past
123 } 100 e.g., High frequency content, zero crossing rate, spectral flatness
124 101 */
125 iWindow = 1; 102
126 103 TCSVector nextTCS;
127 // while (nextTCS.magnitude() < 0.1 && (iPosition+iWindow) < (rTCSGram.getSize()-1) ) 104 TCSVector previousTCS;
128 { 105
129 smoothedTCSGram.getTCSVector(iPosition+iWindow, nextTCS); 106 int iWindow = 1;
130 iWindow++;
131 }
132 107
133 double distance = 0.0; 108 // while (previousTCS.magnitude() < 0.1 && (iPosition-iWindow) > 0)
134 // Euclidean distance 109 {
135 for (size_t j = 0; j < 6; j++) 110 smoothedTCSGram.getTCSVector(iPosition-iWindow, previousTCS);
136 { 111 // std::cout << previousTCS.magnitude() << std::endl;
137 distance += std::pow(nextTCS[j] - previousTCS[j], 2.0); 112 iWindow++;
138 } 113 }
139 114
140 retVal[iPosition] = std::pow(distance, 0.5); 115 iWindow = 1;
141 } 116
117 // while (nextTCS.magnitude() < 0.1 && (iPosition+iWindow) < (rTCSGram.getSize()-1) )
118 {
119 smoothedTCSGram.getTCSVector(iPosition+iWindow, nextTCS);
120 iWindow++;
121 }
142 122
143 return retVal; 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;
144 } 133 }