diff data/fft/FFTFileCache.h @ 148:1a42221a1522

* Reorganising code base. This revision will not compile.
author Chris Cannam
date Mon, 31 Jul 2006 11:49:58 +0000
parents
children 4b2ea82fd0ed
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/fft/FFTFileCache.h	Mon Jul 31 11:49:58 2006 +0000
@@ -0,0 +1,125 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef _FFT_FILE_CACHE_H_
+#define _FFT_FILE_CACHE_H_
+
+#include "FFTCache.h"
+#include "MatrixFile.h"
+
+#include <QMutex>
+
+class FFTFileCache : public FFTCache
+{
+public:
+    enum StorageType {
+        Compact, // 16 bits normalized polar
+        Rectangular, // floating point real+imag
+        Polar, // floating point mag+phase
+    };
+
+    FFTFileCache(QString fileBase, MatrixFile::Mode mode,
+                 StorageType storageType);
+    virtual ~FFTFileCache();
+
+    MatrixFile::Mode getMode() const { return m_mfc->getMode(); }
+
+    virtual size_t getWidth() const;
+    virtual size_t getHeight() const;
+	
+    virtual void resize(size_t width, size_t height);
+    virtual void reset(); // zero-fill or 1-fill as appropriate without changing size
+	
+    virtual float getMagnitudeAt(size_t x, size_t y) const;
+    virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const;
+    virtual float getMaximumMagnitudeAt(size_t x) const;
+    virtual float getPhaseAt(size_t x, size_t y) const;
+
+    virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const;
+
+    virtual bool haveSetColumnAt(size_t x) const;
+
+    virtual void setColumnAt(size_t x, float *mags, float *phases, float factor);
+    virtual void setColumnAt(size_t x, float *reals, float *imags);
+
+    virtual void suspend() { m_mfc->suspend(); }
+
+protected:
+    char *m_writebuf;
+    mutable char *m_readbuf;
+    mutable size_t m_readbufCol;
+    mutable size_t m_readbufWidth;
+
+    float getFromReadBufStandard(size_t x, size_t y) const {
+        if (m_readbuf &&
+            (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
+            return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
+        } else {
+            populateReadBuf(x);
+            return getFromReadBufStandard(x, y);
+        }
+    }
+
+    float getFromReadBufCompactUnsigned(size_t x, size_t y) const {
+        if (m_readbuf &&
+            (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
+            return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
+        } else {
+            populateReadBuf(x);
+            return getFromReadBufCompactUnsigned(x, y);
+        }
+    }
+
+    float getFromReadBufCompactSigned(size_t x, size_t y) const {
+        if (m_readbuf &&
+            (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
+            return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
+        } else {
+            populateReadBuf(x);
+            return getFromReadBufCompactSigned(x, y);
+        }
+    }
+
+    void populateReadBuf(size_t x) const {
+        if (!m_readbuf) {
+            m_readbuf = new char[m_mfc->getHeight() * 2 * m_mfc->getCellSize()];
+        }
+        m_mfc->getColumnAt(x, m_readbuf);
+        if (m_mfc->haveSetColumnAt(x + 1)) {
+            m_mfc->getColumnAt
+                (x + 1, m_readbuf + m_mfc->getCellSize() * m_mfc->getHeight());
+            m_readbufWidth = 2;
+        } else {
+            m_readbufWidth = 1;
+        }
+        m_readbufCol = x;
+    }
+
+    float getNormalizationFactor(size_t col) const {
+        if (m_storageType != Compact) {
+            return getFromReadBufStandard(col, m_mfc->getHeight() - 1);
+        } else {
+            float factor;
+            factor = getFromReadBufCompactUnsigned(col, m_mfc->getHeight() - 1);
+            return factor / 65535.0;
+        }
+    }
+
+    MatrixFile *m_mfc;
+    QMutex m_writeMutex;
+    StorageType m_storageType;
+};
+
+#endif