Chris@103
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@103
|
2
|
Chris@103
|
3 /*
|
Chris@103
|
4 Vamp feature extraction plugin using the MATCH audio alignment
|
Chris@103
|
5 algorithm.
|
Chris@103
|
6
|
Chris@103
|
7 Centre for Digital Music, Queen Mary, University of London.
|
Chris@236
|
8 Copyright (c) 2007-2020 Simon Dixon, Chris Cannam, and Queen Mary
|
Chris@230
|
9 University of London, Copyright (c) 2014-2015 Tido GmbH.
|
Chris@103
|
10
|
Chris@103
|
11 This program is free software; you can redistribute it and/or
|
Chris@103
|
12 modify it under the terms of the GNU General Public License as
|
Chris@103
|
13 published by the Free Software Foundation; either version 2 of the
|
Chris@103
|
14 License, or (at your option) any later version. See the file
|
Chris@103
|
15 COPYING included with this distribution for more information.
|
Chris@103
|
16 */
|
Chris@103
|
17
|
Chris@103
|
18 #include "FeatureConditioner.h"
|
Chris@103
|
19
|
Chris@103
|
20 #include <iostream>
|
Chris@130
|
21 #include <cmath>
|
Chris@103
|
22
|
Chris@103
|
23 using namespace std;
|
Chris@103
|
24
|
Chris@140
|
25 //#define DEBUG_FEATURE_CONDITIONER 1
|
Chris@140
|
26
|
Chris@140
|
27 FeatureConditioner::FeatureConditioner(Parameters parameters) :
|
Chris@140
|
28 m_params(parameters),
|
Chris@140
|
29 m_ltAverage(0.0)
|
Chris@140
|
30 {
|
Chris@140
|
31 #ifdef DEBUG_FEATURE_CONDITIONER
|
Chris@140
|
32 cerr << "*** FeatureConditioner: norm = " << parameters.norm
|
Chris@140
|
33 << ", order = " << parameters.order
|
Chris@140
|
34 << ", silenceThreshold = " << parameters.silenceThreshold
|
Chris@140
|
35 << ", decay = " << parameters.decay << endl;
|
Chris@140
|
36 #endif
|
Chris@140
|
37 }
|
Chris@140
|
38
|
Chris@185
|
39 feature_t
|
Chris@185
|
40 FeatureConditioner::process(const feature_t &feature)
|
Chris@103
|
41 {
|
Chris@103
|
42 if (m_prev.empty()) {
|
Chris@103
|
43 m_prev.resize(feature.size(), 0.0);
|
Chris@103
|
44 }
|
Chris@103
|
45 if (m_prev.size() != feature.size()) {
|
Chris@103
|
46 cerr << "ERROR: FeatureConditioner::process: feature size "
|
Chris@103
|
47 << feature.size() << " differs from previous feature size "
|
Chris@103
|
48 << m_prev.size() << endl;
|
Chris@103
|
49 return feature;
|
Chris@103
|
50 }
|
Chris@103
|
51
|
Chris@180
|
52 int size = static_cast<int>(feature.size());
|
Chris@103
|
53
|
Chris@185
|
54 feature_t out(size, 0.0);
|
Chris@103
|
55
|
Chris@103
|
56 double totalEnergy = 0;
|
Chris@116
|
57
|
Chris@116
|
58 switch (m_params.order) {
|
Chris@116
|
59
|
Chris@116
|
60 case OutputRectifiedDerivative:
|
Chris@103
|
61 for (int i = 0; i < size; i++) {
|
Chris@103
|
62 totalEnergy += feature[i];
|
Chris@103
|
63 if (feature[i] > m_prev[i]) {
|
Chris@103
|
64 out[i] = feature[i] - m_prev[i];
|
Chris@103
|
65 } else {
|
Chris@103
|
66 out[i] = 0;
|
Chris@103
|
67 }
|
Chris@103
|
68 }
|
Chris@116
|
69 break;
|
Chris@116
|
70
|
Chris@116
|
71 case OutputDerivative:
|
Chris@103
|
72 for (int i = 0; i < size; i++) {
|
Chris@116
|
73 totalEnergy += feature[i];
|
Chris@130
|
74 out[i] = fabs(feature[i] - m_prev[i]);
|
Chris@116
|
75 }
|
Chris@116
|
76 break;
|
Chris@116
|
77
|
Chris@116
|
78 case OutputFeatures:
|
Chris@116
|
79 for (int i = 0; i < size; i++) {
|
Chris@116
|
80 totalEnergy += feature[i];
|
Chris@103
|
81 out[i] = feature[i];
|
Chris@103
|
82 }
|
Chris@116
|
83 break;
|
Chris@103
|
84 }
|
Chris@103
|
85
|
Chris@139
|
86 if (m_ltAverage == 0.0) {
|
Chris@103
|
87 m_ltAverage = totalEnergy;
|
Chris@103
|
88 } else {
|
Chris@103
|
89 double decay = m_params.decay;
|
Chris@103
|
90 m_ltAverage = m_ltAverage * decay + totalEnergy * (1.0 - decay);
|
Chris@103
|
91 }
|
Chris@103
|
92
|
Chris@103
|
93 if (totalEnergy <= m_params.silenceThreshold) {
|
Chris@103
|
94 for (int i = 0; i < size; i++) {
|
Chris@103
|
95 out[i] = 0;
|
Chris@103
|
96 }
|
Chris@103
|
97 } else if (m_params.norm == NormaliseToSum1) {
|
Chris@103
|
98 for (int i = 0; i < size; i++) {
|
Chris@185
|
99 out[i] = featurebin_t(out[i] / totalEnergy);
|
Chris@103
|
100 }
|
Chris@103
|
101 } else if (m_params.norm == NormaliseToLTAverage) {
|
Chris@103
|
102 for (int i = 0; i < size; i++) {
|
Chris@185
|
103 out[i] = featurebin_t(out[i] / m_ltAverage);
|
Chris@103
|
104 }
|
Chris@103
|
105 }
|
Chris@103
|
106
|
Chris@103
|
107 m_prev = feature;
|
Chris@103
|
108 return out;
|
Chris@103
|
109 }
|
Chris@103
|
110
|