Mercurial > hg > qm-vamp-plugins
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 |