svcore  1.9
FFTFileCacheReader.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-2009 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_READER_H_
00017 #define _FFT_FILE_CACHE_READER_H_
00018 
00019 #include "data/fileio/MatrixFile.h"
00020 #include "FFTCacheReader.h"
00021 #include "FFTCacheStorageType.h"
00022 
00023 class FFTFileCacheWriter;
00024 
00025 class FFTFileCacheReader : public FFTCacheReader
00026 {
00027 public:
00028     FFTFileCacheReader(FFTFileCacheWriter *);
00029     ~FFTFileCacheReader();
00030 
00031     int getWidth() const;
00032     int getHeight() const;
00033         
00034     float getMagnitudeAt(int x, int y) const;
00035     float getNormalizedMagnitudeAt(int x, int y) const;
00036     float getMaximumMagnitudeAt(int x) const;
00037     float getPhaseAt(int x, int y) const;
00038 
00039     void getValuesAt(int x, int y, float &real, float &imag) const;
00040     void getMagnitudesAt(int x, float *values, int minbin, int count, int step) const;
00041 
00042     bool haveSetColumnAt(int x) const;
00043 
00044     static int getCacheSize(int width, int height,
00045                                FFTCache::StorageType type);
00046 
00047     FFTCache::StorageType getStorageType() const { return m_storageType; }
00048 
00049 protected:
00050     mutable char *m_readbuf;
00051     mutable int m_readbufCol;
00052     mutable int m_readbufWidth;
00053     mutable bool m_readbufGood;
00054 
00055     float getFromReadBufStandard(int x, int y) const {
00056         float v;
00057         if (m_readbuf &&
00058             (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00059             v = ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00060             return v;
00061         } else {
00062             populateReadBuf(x);
00063             v = getFromReadBufStandard(x, y);
00064             return v;
00065         }
00066     }
00067 
00068     float getFromReadBufCompactUnsigned(int x, int y) const {
00069         float v;
00070         if (m_readbuf &&
00071             (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00072             v = ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00073             return v;
00074         } else {
00075             populateReadBuf(x);
00076             v = getFromReadBufCompactUnsigned(x, y);
00077             return v;
00078         }
00079     }
00080 
00081     float getFromReadBufCompactSigned(int x, int y) const {
00082         float v;
00083         if (m_readbuf &&
00084             (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
00085             v = ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
00086             return v;
00087         } else {
00088             populateReadBuf(x);
00089             v = getFromReadBufCompactSigned(x, y);
00090             return v;
00091         }
00092     }
00093 
00094     void populateReadBuf(int x) const;
00095 
00096     float getNormalizationFactor(int col) const {
00097         int h = m_mfc->getHeight();
00098         if (h < m_factorSize) return 0;
00099         if (m_storageType != FFTCache::Compact) {
00100             return getFromReadBufStandard(col, h - 1);
00101         } else {
00102             union {
00103                 float f;
00104                 uint16_t u[2];
00105             } factor;
00106             if (!m_readbuf ||
00107                 !(m_readbufCol == col ||
00108                   (m_readbufWidth > 1 && m_readbufCol+1 == col))) {
00109                 populateReadBuf(col);
00110             }
00111             int ix = (col - m_readbufCol) * m_mfc->getHeight() + h;
00112             factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2];
00113             factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1];
00114             return factor.f;
00115         }
00116     }
00117  
00118     FFTCache::StorageType m_storageType;
00119     int m_factorSize;
00120     MatrixFile *m_mfc;
00121 };
00122 
00123 #endif