FFTMemoryCache.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.
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_MEMORY_CACHE_H_
00017 #define _FFT_MEMORY_CACHE_H_
00018 
00019 #include "FFTCache.h"
00020 
00021 #include "base/ResizeableBitset.h"
00022 
00042 class FFTMemoryCache : public FFTCache
00043 {
00044 public:
00045     enum StorageType {
00046         Compact, // 16 bits normalized polar
00047         Rectangular, // floating point real+imag
00048         Polar // floating point mag+phase
00049     };
00050 
00051     FFTMemoryCache(StorageType storageType); // of size zero, call resize() before using
00052     virtual ~FFTMemoryCache();
00053         
00054     virtual size_t getWidth() const { return m_width; }
00055     virtual size_t getHeight() const { return m_height; }
00056         
00057     virtual void resize(size_t width, size_t height);
00058     virtual void reset(); // zero-fill or 1-fill as appropriate without changing size
00059     
00060     virtual float getMagnitudeAt(size_t x, size_t y) const {
00061         if (m_storageType == Rectangular) {
00062             return sqrt(m_freal[x][y] * m_freal[x][y] +
00063                         m_fimag[x][y] * m_fimag[x][y]);
00064         } else {
00065             return getNormalizedMagnitudeAt(x, y) * m_factor[x];
00066         }
00067     }
00068     
00069     virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const {
00070         if (m_storageType == Rectangular) return getMagnitudeAt(x, y) / m_factor[x];
00071         else if (m_storageType == Polar) return m_fmagnitude[x][y];
00072         else return float(m_magnitude[x][y]) / 65535.0;
00073     }
00074     
00075     virtual float getMaximumMagnitudeAt(size_t x) const {
00076         return m_factor[x];
00077     }
00078     
00079     virtual float getPhaseAt(size_t x, size_t y) const {
00080         if (m_storageType == Rectangular) {
00081             return atan2f(m_fimag[x][y], m_freal[x][y]);
00082         } else if (m_storageType == Polar) {
00083             return m_fphase[x][y];
00084         } else {
00085             int16_t i = (int16_t)m_phase[x][y];
00086             return (float(i) / 32767.0) * M_PI;
00087         }
00088     }
00089     
00090     virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const {
00091         if (m_storageType == Rectangular) {
00092             real = m_freal[x][y];
00093             imag = m_fimag[x][y];
00094         } else {
00095             float mag = getMagnitudeAt(x, y);
00096             float phase = getPhaseAt(x, y);
00097             real = mag * cosf(phase);
00098             imag = mag * sinf(phase);
00099         }
00100     }
00101 
00102     virtual bool haveSetColumnAt(size_t x) const {
00103         return m_colset.get(x);
00104     }
00105 
00106     virtual void setColumnAt(size_t x, float *mags, float *phases, float factor);
00107 
00108     virtual void setColumnAt(size_t x, float *reals, float *imags);
00109 
00110     static size_t getCacheSize(size_t width, size_t height, StorageType type);
00111 
00112     virtual Type getType() { return MemoryCache; }
00113 
00114 private:
00115     size_t m_width;
00116     size_t m_height;
00117     uint16_t **m_magnitude;
00118     uint16_t **m_phase;
00119     float **m_fmagnitude;
00120     float **m_fphase;
00121     float **m_freal;
00122     float **m_fimag;
00123     float *m_factor;
00124     StorageType m_storageType;
00125     ResizeableBitset m_colset;
00126 
00127     virtual void setNormalizationFactor(size_t x, float factor) {
00128         if (x < m_width) m_factor[x] = factor;
00129     }
00130     
00131     virtual void setMagnitudeAt(size_t x, size_t y, float mag) {
00132          // norm factor must already be set
00133         setNormalizedMagnitudeAt(x, y, mag / m_factor[x]);
00134     }
00135     
00136     virtual void setNormalizedMagnitudeAt(size_t x, size_t y, float norm) {
00137         if (x < m_width && y < m_height) {
00138             if (m_storageType == Polar) m_fmagnitude[x][y] = norm;
00139             else m_magnitude[x][y] = uint16_t(norm * 65535.0);
00140         }
00141     }
00142     
00143     virtual void setPhaseAt(size_t x, size_t y, float phase) {
00144         // phase in range -pi -> pi
00145         if (x < m_width && y < m_height) {
00146             if (m_storageType == Polar) m_fphase[x][y] = phase;
00147             else m_phase[x][y] = uint16_t(int16_t((phase * 32767) / M_PI));
00148         }
00149     }
00150 
00151     void resize(uint16_t **&, size_t, size_t);
00152     void resize(float **&, size_t, size_t);
00153 };
00154 
00155 
00156 #endif
00157 

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