Chris@537: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@537: Chris@537: /* Chris@537: Sonic Visualiser Chris@537: An audio file viewer and annotation editor. Chris@537: Centre for Digital Music, Queen Mary, University of London. Chris@537: This file copyright 2006-2009 Chris Cannam and QMUL. Chris@537: Chris@537: This program is free software; you can redistribute it and/or Chris@537: modify it under the terms of the GNU General Public License as Chris@537: published by the Free Software Foundation; either version 2 of the Chris@537: License, or (at your option) any later version. See the file Chris@537: COPYING included with this distribution for more information. Chris@537: */ Chris@537: Chris@537: #ifndef _FFT_FILE_CACHE_READER_H_ Chris@537: #define _FFT_FILE_CACHE_READER_H_ Chris@537: Chris@537: #include "data/fileio/MatrixFile.h" Chris@537: #include "FFTCacheReader.h" Chris@537: #include "FFTCacheStorageType.h" Chris@537: Chris@537: class FFTFileCacheWriter; Chris@537: Chris@537: class FFTFileCacheReader : public FFTCacheReader Chris@537: { Chris@537: public: Chris@537: FFTFileCacheReader(FFTFileCacheWriter *); Chris@537: ~FFTFileCacheReader(); Chris@537: Chris@537: size_t getWidth() const; Chris@537: size_t getHeight() const; Chris@537: Chris@537: float getMagnitudeAt(size_t x, size_t y) const; Chris@537: float getNormalizedMagnitudeAt(size_t x, size_t y) const; Chris@537: float getMaximumMagnitudeAt(size_t x) const; Chris@537: float getPhaseAt(size_t x, size_t y) const; Chris@537: Chris@537: void getValuesAt(size_t x, size_t y, float &real, float &imag) const; Chris@537: void getMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) const; Chris@537: Chris@537: bool haveSetColumnAt(size_t x) const; Chris@537: Chris@537: static size_t getCacheSize(size_t width, size_t height, Chris@537: FFTCache::StorageType type); Chris@537: Chris@537: FFTCache::StorageType getStorageType() const { return m_storageType; } Chris@537: Chris@537: protected: Chris@537: mutable char *m_readbuf; Chris@537: mutable size_t m_readbufCol; Chris@537: mutable size_t m_readbufWidth; Chris@555: mutable bool m_readbufGood; Chris@537: Chris@537: float getFromReadBufStandard(size_t x, size_t y) const { Chris@537: float v; Chris@537: if (m_readbuf && Chris@537: (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { Chris@537: v = ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; Chris@537: return v; Chris@537: } else { Chris@537: populateReadBuf(x); Chris@537: v = getFromReadBufStandard(x, y); Chris@537: return v; Chris@537: } Chris@537: } Chris@537: Chris@537: float getFromReadBufCompactUnsigned(size_t x, size_t y) const { Chris@537: float v; Chris@537: if (m_readbuf && Chris@537: (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { Chris@537: v = ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; Chris@537: return v; Chris@537: } else { Chris@537: populateReadBuf(x); Chris@537: v = getFromReadBufCompactUnsigned(x, y); Chris@537: return v; Chris@537: } Chris@537: } Chris@537: Chris@537: float getFromReadBufCompactSigned(size_t x, size_t y) const { Chris@537: float v; Chris@537: if (m_readbuf && Chris@537: (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { Chris@537: v = ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; Chris@537: return v; Chris@537: } else { Chris@537: populateReadBuf(x); Chris@537: v = getFromReadBufCompactSigned(x, y); Chris@537: return v; Chris@537: } Chris@537: } Chris@537: Chris@537: void populateReadBuf(size_t x) const; Chris@537: Chris@537: float getNormalizationFactor(size_t col) const { Chris@537: size_t h = m_mfc->getHeight(); Chris@537: if (h < m_factorSize) return 0; Chris@537: if (m_storageType != FFTCache::Compact) { Chris@537: return getFromReadBufStandard(col, h - 1); Chris@537: } else { Chris@537: union { Chris@537: float f; Chris@537: uint16_t u[2]; Chris@537: } factor; Chris@537: if (!m_readbuf || Chris@537: !(m_readbufCol == col || Chris@537: (m_readbufWidth > 1 && m_readbufCol+1 == col))) { Chris@537: populateReadBuf(col); Chris@537: } Chris@537: size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h; Chris@537: factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2]; Chris@537: factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1]; Chris@537: return factor.f; Chris@537: } Chris@537: } Chris@537: Chris@537: FFTCache::StorageType m_storageType; Chris@537: size_t m_factorSize; Chris@537: MatrixFile *m_mfc; Chris@537: }; Chris@537: Chris@537: #endif