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