FFTFileCache.h

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
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, // 16 bits normalized polar
00029         Rectangular, // floating point real+imag
00030         Polar, // floating point mag+phase
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(); // zero-fill or 1-fill as appropriate without changing size
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

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1