diff 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
line wrap: on
line diff
--- a/plugins/AdaptiveSpectrogram.h	Tue May 12 12:01:23 2009 +0000
+++ b/plugins/AdaptiveSpectrogram.h	Tue May 12 17:57:41 2009 +0000
@@ -14,6 +14,8 @@
 #include <cmath>
 #include <vector>
 
+#include "thread/Thread.h"
+
 class AdaptiveSpectrogram : public Vamp::Plugin
 {
 public:
@@ -50,11 +52,6 @@
     int m_w;
     int m_n;
 
-    inline double xlogx(double x) {
-        if (x == 0.0) return 0.0;
-        else return x * log(x);
-    }
-
     struct Spectrogram
     {
         int resolution;
@@ -113,20 +110,138 @@
         }
     };
 
-    double cost(const Spectrogram &s, int x, int y) {
+    class CutThread : public Thread
+    {
+    public:
+        CutThread(const AdaptiveSpectrogram *as) :
+            m_as(as),
+//            m_busy(false),
+//            m_computed(false),
+            m_result(0),
+            m_workToDoC("CutThread: work to do"),
+            m_workToDo(false),
+            m_workDoneC("CutThread: work done"),
+            m_workDone(false),
+            m_finishing(false)
+        { }
+        ~CutThread() { }
+
+        void cut(const Spectrograms &s, int res, int x, int y, int h) {
+            m_workToDoC.lock();
+//            std::cerr << "locked in main thread" << std::endl;
+            m_s = &s;
+            m_res = res;
+            m_x = x;
+            m_y = y;
+            m_h = h;
+//            m_busy = true;
+//            m_computed = false;
+            m_workToDo = true;
+            m_workDone = false;
+            m_workToDoC.signal();
+            m_workDoneC.lock();
+            m_workToDoC.unlock();
+        }
+
+        Cutting *get() {
+//            std::cerr << "about to wait within main thread" << std::endl;
+            // m_workDoneC must be locked from prior call to cut()
+            while (!m_workDone) m_workDoneC.wait();
+//            std::cerr << "waited within main thread" << std::endl;
+//            m_workDoneC.lock();
+//            while (!m_computed) {
+//                std::cerr << "waiting within main thread" << std::endl;
+//                m_condition.wait();
+//            }
+            Cutting *c = m_result;
+            m_result = 0;
+            m_workDoneC.unlock();
+            return c;
+        }
+/*
+        bool busy() {
+            return m_busy;
+        }
+*/
+        void finish() {
+            m_finishing = true;
+            m_workToDoC.signal();
+        }
+
+    protected:
+        virtual void run() {
+            m_workToDoC.lock();
+//            std::cerr << "locked within run function" << std::endl;
+            while (!m_finishing) {
+//                if (!m_busy) {
+//                    std::cerr << "waiting within run function" << std::endl;
+//                    m_condition.wait();
+//                }
+                    while (!m_workToDo && !m_finishing) m_workToDoC.wait();
+//                    std::cerr << "waited within run function" << std::endl;
+                if (m_finishing) {
+                    break;
+                }
+                if (m_workToDo) {
+//                    std::cerr << "cut thread " << this << ": calling cut" << std::endl;
+                    m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h);
+//                    std::cerr << "cut returning" << std::endl;
+//                    m_computed = true;
+//                    m_busy = false;
+                    m_workToDo = false;
+                    m_workDone = true;
+//                    std::cerr << "signalling completion from run function" << std::endl;
+                    m_workDoneC.signal();
+                }
+            }
+            m_workToDoC.unlock();
+        }
+
+        const AdaptiveSpectrogram *m_as;
+        const Spectrograms *m_s;
+        int m_res;
+        int m_x;
+        int m_y;
+        int m_h;
+//        bool m_busy;
+//        bool m_computed;
+        Cutting *m_result;
+        Condition m_workToDoC;
+        bool m_workToDo;
+        Condition m_workDoneC;
+        bool m_workDone;
+        bool m_finishing;
+    };
+    mutable std::vector<CutThread *> m_cutThreads;//!!! mutable blargh
+
+///!!!    Mutex m_threadMutex;
+mutable    bool m_first; //!!! gross
+
+    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 {
         return xlogx(s.data[x][y]);
     }
 
-    double value(const Spectrogram &s, int x, int y) {
+    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);
+    Cutting *cut(const Spectrograms &, int res, int x, int y, int h) const;
 
-    void printCutting(Cutting *, std::string);
+    void getSubCuts(const Spectrograms &, int res, int x, int y, int h,
+                    Cutting *&top, Cutting *&bottom,
+                    Cutting *&left, Cutting *&right) const;
 
-    void assemble(const Spectrograms &, const Cutting *, std::vector<std::vector<float> > &, int x, int y, int w, int h);
-};
+    void printCutting(Cutting *, std::string) const;
+
+    void assemble(const Spectrograms &, const Cutting *,
+                  std::vector<std::vector<float> > &,
+                  int x, int y, int w, int h) const;
+    };
 
 
 #endif