Mercurial > hg > qm-vamp-plugins
changeset 110:be419e04899a
* Update to use BlockAllocator, and a few other bits & pieces
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 14 May 2009 12:45:27 +0000 |
parents | 0dd97d053053 |
children | a8292af48062 |
files | plugins/AdaptiveSpectrogram.cpp plugins/AdaptiveSpectrogram.h |
diffstat | 2 files changed, 62 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/AdaptiveSpectrogram.cpp Wed May 13 17:41:41 2009 +0000 +++ b/plugins/AdaptiveSpectrogram.cpp Thu May 14 12:45:27 2009 +0000 @@ -41,7 +41,8 @@ } m_cutThreads.clear(); - for (FFTMap::iterator i = m_fftThreads.begin(); i != m_fftThreads.end(); ++i) { + for (FFTMap::iterator i = m_fftThreads.begin(); + i != m_fftThreads.end(); ++i) { delete i->second; } m_fftThreads.clear(); @@ -157,7 +158,7 @@ ParameterDescriptor desc3; desc3.identifier = "threaded"; desc3.name = "Multi-threaded processing"; - desc3.description = "Perform calculations in several threads in parallel"; + desc3.description = "Perform calculations using several threads in parallel"; desc3.unit = ""; desc3.minValue = 0; desc3.maxValue = 1; @@ -262,7 +263,9 @@ m_threadsInUse = false; - Cutting *cutting = cut(s, maxwid/2, 0, 0, maxwid/2); +// std::cerr << "maxwid/2 = " << maxwid/2 << ", minwid/2 = " << minwid/2 << ", n+1 = " << m_n+1 << ", 2^(n+1) = " << (2<<m_n) << std::endl; + + Cutting *cutting = cut(s, maxwid/2, 0, 0, maxwid/2, 0); #ifdef DEBUG_VERBOSE printCutting(cutting, " "); @@ -275,7 +278,7 @@ assemble(s, cutting, rmat, 0, 0, maxwid/minwid, maxwid/2); - delete cutting; + cutting->erase(); for (int i = 0; i < rmat.size(); ++i) { Feature f; @@ -324,15 +327,13 @@ } // Cut threads 0 and 1 calculate the top and bottom halves; - // threads 2 and 3 calculate left and right. + // threads 2 and 3 calculate left and right. See notes in + // unthreaded code below for more information. - // The "vertical" division is a top/bottom split. - // Splitting this way keeps us in the same resolution, - // but with two vertical subregions of height h/2. - m_cutThreads[0]->cut(s, res, x, y + h/2, h/2); // top - m_cutThreads[1]->cut(s, res, x, y, h/2); // bottom - m_cutThreads[2]->cut(s, res/2, 2 * x, y/2, h/2); // left - m_cutThreads[3]->cut(s, res/2, 2 * x + 1, y/2, h/2); // right + m_cutThreads[0]->cut(s, res, x, y + h/2, h/2); // top + m_cutThreads[1]->cut(s, res, x, y, h/2); // bottom + m_cutThreads[2]->cut(s, res/2, 2 * x, y/2, h/2); // left + m_cutThreads[3]->cut(s, res/2, 2 * x + 1, y/2, h/2); // right top = m_cutThreads[0]->get(); bottom = m_cutThreads[1]->get(); @@ -341,32 +342,42 @@ } else { - // unthreaded + // Unthreaded version // The "vertical" division is a top/bottom split. // Splitting this way keeps us in the same resolution, // but with two vertical subregions of height h/2. - top = cut(s, res, x, y + h/2, h/2); - bottom = cut(s, res, x, y, h/2); + top = cut(s, res, x, y + h/2, h/2, 0); + bottom = cut(s, res, x, y, h/2, 0); // The "horizontal" division is a left/right split. Splitting // this way places us in resolution res/2, which has lower // vertical resolution but higher horizontal resolution. We // need to double x accordingly. - left = cut(s, res/2, 2 * x, y/2, h/2); - right = cut(s, res/2, 2 * x + 1, y/2, h/2); + left = cut(s, res/2, 2 * x, y/2, h/2, 0); + right = cut(s, res/2, 2 * x + 1, y/2, h/2, 0); } } AdaptiveSpectrogram::Cutting * AdaptiveSpectrogram::cut(const Spectrograms &s, int res, - int x, int y, int h) const + int x, int y, int h, + BlockAllocator *allocator) const { // cerr << "res = " << res << ", x = " << x << ", y = " << y << ", h = " << h << endl; + Cutting *cutting; + if (allocator) { + cutting = (Cutting *)(allocator->allocate()); + cutting->allocator = allocator; + } else { + cutting = new Cutting; + cutting->allocator = 0; + } + if (h > 1 && res > s.minres) { Cutting *top = 0, *bottom = 0, *left = 0, *right = 0; @@ -389,27 +400,23 @@ if (vcost > hcost) { // cut horizontally (left/right) - - Cutting *cutting = new Cutting; cutting->cut = Cutting::Horizontal; cutting->first = left; cutting->second = right; cutting->cost = hcost; - cutting->value = left->value + right->value; - delete top; - delete bottom; + top->erase(); + bottom->erase(); return cutting; } else { - Cutting *cutting = new Cutting; + // cut vertically (top/bottom) cutting->cut = Cutting::Vertical; cutting->first = top; cutting->second = bottom; cutting->cost = vcost; - cutting->value = top->value + bottom->value; - delete left; - delete right; + left->erase(); + right->erase(); return cutting; } @@ -417,7 +424,6 @@ // no cuts possible from this level - Cutting *cutting = new Cutting; cutting->cut = Cutting::Finished; cutting->first = 0; cutting->second = 0;
--- a/plugins/AdaptiveSpectrogram.h Wed May 13 17:41:41 2009 +0000 +++ b/plugins/AdaptiveSpectrogram.h Thu May 14 12:45:27 2009 +0000 @@ -18,6 +18,8 @@ #include <base/Window.h> #include "thread/Thread.h" +#include "thread/AsynchronousTask.h" +#include "thread/BlockAllocator.h" class AdaptiveSpectrogram : public Vamp::Plugin { @@ -107,10 +109,21 @@ Cutting *second; double cost; double value; + BlockAllocator *allocator; ~Cutting() { - delete first; - delete second; + if (first) first->erase(); + if (second) second->erase(); + } + + void erase() { + if (allocator) { + if (first) first->erase(); + if (second) second->erase(); + allocator->deallocate(this); + } else { + delete this; + } } }; @@ -189,8 +202,12 @@ class CutThread : public AsynchronousTask { public: - CutThread(const AdaptiveSpectrogram *as) : m_as(as), m_result(0) { } - ~CutThread() { } + CutThread(const AdaptiveSpectrogram *as) : m_as(as), m_result(0) { + m_allocator = new BlockAllocator(sizeof(Cutting)); + } + ~CutThread() { + delete m_allocator; + } void cut(const Spectrograms &s, int res, int x, int y, int h) { m_s = &s; @@ -208,11 +225,12 @@ protected: void performTask() { - m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h); + m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h, m_allocator); } private: const AdaptiveSpectrogram *m_as; + BlockAllocator *m_allocator; const Spectrograms *m_s; int m_res; int m_x; @@ -224,20 +242,21 @@ mutable std::vector<CutThread *> m_cutThreads; mutable bool m_threadsInUse; - double xlogx(double x) const { + inline double xlogx(double x) const { if (x == 0.0) return 0.0; else return x * log(x); } - double cost(const Spectrogram &s, int x, int y) const { + inline double cost(const Spectrogram &s, int x, int y) const { return xlogx(s.data[x][y]); } - double value(const Spectrogram &s, int x, int y) const { + inline double value(const Spectrogram &s, int x, int y) const { return s.data[x][y]; } - Cutting *cut(const Spectrograms &, int res, int x, int y, int h) const; + Cutting *cut(const Spectrograms &, int res, int x, int y, int h, + BlockAllocator *allocator) const; void getSubCuts(const Spectrograms &, int res, int x, int y, int h, Cutting *&top, Cutting *&bottom,