00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _FFT_FILE_CACHE_H_
00017 #define _FFT_FILE_CACHE_H_
00018
00019 #include "FFTCache.h"
00020 #include "fileio/MatrixFile.h"
00021
00022 #include <QMutex>
00023
00024 class FFTFileCache : public FFTCache
00025 {
00026 public:
00027 enum StorageType {
00028 Compact,
00029 Rectangular,
00030 Polar,
00031 };
00032
00033 FFTFileCache(QString fileBase, MatrixFile::Mode mode,
00034 StorageType storageType);
00035 virtual ~FFTFileCache();
00036
00037 MatrixFile::Mode getMode() const { return m_mfc->getMode(); }
00038
00039 virtual size_t getWidth() const;
00040 virtual size_t getHeight() const;
00041
00042 virtual void resize(size_t width, size_t height);
00043 virtual void reset();
00044
00045 virtual float getMagnitudeAt(size_t x, size_t y) const;
00046 virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const;
00047 virtual float getMaximumMagnitudeAt(size_t x) const;
00048 virtual float getPhaseAt(size_t x, size_t y) const;
00049
00050 virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const;
00051
00052 virtual bool haveSetColumnAt(size_t x) const;
00053
00054 virtual void setColumnAt(size_t x, float *mags, float *phases, float factor);
00055 virtual void setColumnAt(size_t x, float *reals, float *imags);
00056
00057 virtual void suspend() { m_mfc->suspend(); }
00058
00059 static size_t getCacheSize(size_t width, size_t height, StorageType type);
00060
00061 virtual Type getType() { return FileCache; }
00062
00063 protected:
00064 char *m_writebuf;
00065 mutable char *m_readbuf;
00066 mutable size_t m_readbufCol;
00067 mutable size_t m_readbufWidth;
00068
00069 float getFromReadBufStandard(size_t x, size_t y) const {
00070 if (m_readbuf &&
00071 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00072 return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00073 } else {
00074 populateReadBuf(x);
00075 return getFromReadBufStandard(x, y);
00076 }
00077 }
00078
00079 float getFromReadBufCompactUnsigned(size_t x, size_t y) const {
00080 if (m_readbuf &&
00081 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00082 return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00083 } else {
00084 populateReadBuf(x);
00085 return getFromReadBufCompactUnsigned(x, y);
00086 }
00087 }
00088
00089 float getFromReadBufCompactSigned(size_t x, size_t y) const {
00090 if (m_readbuf &&
00091 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00092 return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00093 } else {
00094 populateReadBuf(x);
00095 return getFromReadBufCompactSigned(x, y);
00096 }
00097 }
00098
00099 void populateReadBuf(size_t x) const;
00100
00101 float getNormalizationFactor(size_t col) const {
00102 size_t h = m_mfc->getHeight();
00103 if (h < m_factorSize) return 0;
00104 if (m_storageType != Compact) {
00105 return getFromReadBufStandard(col, h - 1);
00106 } else {
00107 union {
00108 float f;
00109 uint16_t u[2];
00110 } factor;
00111 if (!m_readbuf ||
00112 !(m_readbufCol == col ||
00113 (m_readbufWidth > 1 && m_readbufCol+1 == col))) {
00114 populateReadBuf(col);
00115 }
00116 size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h;
00117 factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2];
00118 factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1];
00119 return factor.f;
00120 }
00121 }
00122
00123 void setNormalizationFactorToWritebuf(float newfactor) {
00124 size_t h = m_mfc->getHeight();
00125 if (h < m_factorSize) return;
00126 if (m_storageType != Compact) {
00127 ((float *)m_writebuf)[h - 1] = newfactor;
00128 } else {
00129 union {
00130 float f;
00131 uint16_t u[2];
00132 } factor;
00133 factor.f = newfactor;
00134 ((uint16_t *)m_writebuf)[h - 2] = factor.u[0];
00135 ((uint16_t *)m_writebuf)[h - 1] = factor.u[1];
00136 }
00137 }
00138
00139 MatrixFile *m_mfc;
00140 QMutex m_writeMutex;
00141 StorageType m_storageType;
00142 size_t m_factorSize;
00143 };
00144
00145 #endif