comparison plugins/AdaptiveSpectrogram.h @ 104:d8ad747eb907

* first crack at threading cut code
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 12 May 2009 17:57:41 +0000
parents ef22bed1626a
children abbc482aaad2
comparison
equal deleted inserted replaced
103:ef22bed1626a 104:d8ad747eb907
11 #define _ADAPTIVE_SPECTROGRAM_H_ 11 #define _ADAPTIVE_SPECTROGRAM_H_
12 12
13 #include <vamp-sdk/Plugin.h> 13 #include <vamp-sdk/Plugin.h>
14 #include <cmath> 14 #include <cmath>
15 #include <vector> 15 #include <vector>
16
17 #include "thread/Thread.h"
16 18
17 class AdaptiveSpectrogram : public Vamp::Plugin 19 class AdaptiveSpectrogram : public Vamp::Plugin
18 { 20 {
19 public: 21 public:
20 AdaptiveSpectrogram(float inputSampleRate); 22 AdaptiveSpectrogram(float inputSampleRate);
47 FeatureSet getRemainingFeatures(); 49 FeatureSet getRemainingFeatures();
48 50
49 protected: 51 protected:
50 int m_w; 52 int m_w;
51 int m_n; 53 int m_n;
52
53 inline double xlogx(double x) {
54 if (x == 0.0) return 0.0;
55 else return x * log(x);
56 }
57 54
58 struct Spectrogram 55 struct Spectrogram
59 { 56 {
60 int resolution; 57 int resolution;
61 int width; 58 int width;
111 delete first; 108 delete first;
112 delete second; 109 delete second;
113 } 110 }
114 }; 111 };
115 112
116 double cost(const Spectrogram &s, int x, int y) { 113 class CutThread : public Thread
114 {
115 public:
116 CutThread(const AdaptiveSpectrogram *as) :
117 m_as(as),
118 // m_busy(false),
119 // m_computed(false),
120 m_result(0),
121 m_workToDoC("CutThread: work to do"),
122 m_workToDo(false),
123 m_workDoneC("CutThread: work done"),
124 m_workDone(false),
125 m_finishing(false)
126 { }
127 ~CutThread() { }
128
129 void cut(const Spectrograms &s, int res, int x, int y, int h) {
130 m_workToDoC.lock();
131 // std::cerr << "locked in main thread" << std::endl;
132 m_s = &s;
133 m_res = res;
134 m_x = x;
135 m_y = y;
136 m_h = h;
137 // m_busy = true;
138 // m_computed = false;
139 m_workToDo = true;
140 m_workDone = false;
141 m_workToDoC.signal();
142 m_workDoneC.lock();
143 m_workToDoC.unlock();
144 }
145
146 Cutting *get() {
147 // std::cerr << "about to wait within main thread" << std::endl;
148 // m_workDoneC must be locked from prior call to cut()
149 while (!m_workDone) m_workDoneC.wait();
150 // std::cerr << "waited within main thread" << std::endl;
151 // m_workDoneC.lock();
152 // while (!m_computed) {
153 // std::cerr << "waiting within main thread" << std::endl;
154 // m_condition.wait();
155 // }
156 Cutting *c = m_result;
157 m_result = 0;
158 m_workDoneC.unlock();
159 return c;
160 }
161 /*
162 bool busy() {
163 return m_busy;
164 }
165 */
166 void finish() {
167 m_finishing = true;
168 m_workToDoC.signal();
169 }
170
171 protected:
172 virtual void run() {
173 m_workToDoC.lock();
174 // std::cerr << "locked within run function" << std::endl;
175 while (!m_finishing) {
176 // if (!m_busy) {
177 // std::cerr << "waiting within run function" << std::endl;
178 // m_condition.wait();
179 // }
180 while (!m_workToDo && !m_finishing) m_workToDoC.wait();
181 // std::cerr << "waited within run function" << std::endl;
182 if (m_finishing) {
183 break;
184 }
185 if (m_workToDo) {
186 // std::cerr << "cut thread " << this << ": calling cut" << std::endl;
187 m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h);
188 // std::cerr << "cut returning" << std::endl;
189 // m_computed = true;
190 // m_busy = false;
191 m_workToDo = false;
192 m_workDone = true;
193 // std::cerr << "signalling completion from run function" << std::endl;
194 m_workDoneC.signal();
195 }
196 }
197 m_workToDoC.unlock();
198 }
199
200 const AdaptiveSpectrogram *m_as;
201 const Spectrograms *m_s;
202 int m_res;
203 int m_x;
204 int m_y;
205 int m_h;
206 // bool m_busy;
207 // bool m_computed;
208 Cutting *m_result;
209 Condition m_workToDoC;
210 bool m_workToDo;
211 Condition m_workDoneC;
212 bool m_workDone;
213 bool m_finishing;
214 };
215 mutable std::vector<CutThread *> m_cutThreads;//!!! mutable blargh
216
217 ///!!! Mutex m_threadMutex;
218 mutable bool m_first; //!!! gross
219
220 double xlogx(double x) const {
221 if (x == 0.0) return 0.0;
222 else return x * log(x);
223 }
224
225 double cost(const Spectrogram &s, int x, int y) const {
117 return xlogx(s.data[x][y]); 226 return xlogx(s.data[x][y]);
118 } 227 }
119 228
120 double value(const Spectrogram &s, int x, int y) { 229 double value(const Spectrogram &s, int x, int y) const {
121 return s.data[x][y]; 230 return s.data[x][y];
122 } 231 }
123 232
124 Cutting *cut(const Spectrograms &, int res, int x, int y, int h); 233 Cutting *cut(const Spectrograms &, int res, int x, int y, int h) const;
125 234
126 void printCutting(Cutting *, std::string); 235 void getSubCuts(const Spectrograms &, int res, int x, int y, int h,
127 236 Cutting *&top, Cutting *&bottom,
128 void assemble(const Spectrograms &, const Cutting *, std::vector<std::vector<float> > &, int x, int y, int w, int h); 237 Cutting *&left, Cutting *&right) const;
129 }; 238
239 void printCutting(Cutting *, std::string) const;
240
241 void assemble(const Spectrograms &, const Cutting *,
242 std::vector<std::vector<float> > &,
243 int x, int y, int w, int h) const;
244 };
130 245
131 246
132 #endif 247 #endif