annotate data/fft/FFTFileCache.h @ 335:02d2ad95ea52 spectrogram-cache-rejig

* Get storage advice for each cache in an FFT data server. Allows us to be more confident about the actual memory situation and cut over from memory to disc part way through an FFT calculation if necessary. StorageAdviser is now a bit too optimistic though (it's too keen to allocate large numbers of small blocks in memory).
author Chris Cannam
date Tue, 13 Nov 2007 13:54:10 +0000
parents 2268963dabd1
children 115f60df1e4d
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #ifndef _FFT_FILE_CACHE_H_
Chris@148 17 #define _FFT_FILE_CACHE_H_
Chris@148 18
Chris@152 19 #include "FFTCache.h"
Chris@150 20 #include "fileio/MatrixFile.h"
Chris@148 21
Chris@148 22 #include <QMutex>
Chris@148 23
Chris@148 24 class FFTFileCache : public FFTCache
Chris@148 25 {
Chris@148 26 public:
Chris@148 27 enum StorageType {
Chris@148 28 Compact, // 16 bits normalized polar
Chris@148 29 Rectangular, // floating point real+imag
Chris@148 30 Polar, // floating point mag+phase
Chris@148 31 };
Chris@148 32
Chris@148 33 FFTFileCache(QString fileBase, MatrixFile::Mode mode,
Chris@148 34 StorageType storageType);
Chris@148 35 virtual ~FFTFileCache();
Chris@148 36
Chris@148 37 MatrixFile::Mode getMode() const { return m_mfc->getMode(); }
Chris@148 38
Chris@148 39 virtual size_t getWidth() const;
Chris@148 40 virtual size_t getHeight() const;
Chris@148 41
Chris@148 42 virtual void resize(size_t width, size_t height);
Chris@148 43 virtual void reset(); // zero-fill or 1-fill as appropriate without changing size
Chris@148 44
Chris@148 45 virtual float getMagnitudeAt(size_t x, size_t y) const;
Chris@148 46 virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const;
Chris@148 47 virtual float getMaximumMagnitudeAt(size_t x) const;
Chris@148 48 virtual float getPhaseAt(size_t x, size_t y) const;
Chris@148 49
Chris@148 50 virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const;
Chris@148 51
Chris@148 52 virtual bool haveSetColumnAt(size_t x) const;
Chris@148 53
Chris@148 54 virtual void setColumnAt(size_t x, float *mags, float *phases, float factor);
Chris@148 55 virtual void setColumnAt(size_t x, float *reals, float *imags);
Chris@148 56
Chris@148 57 virtual void suspend() { m_mfc->suspend(); }
Chris@148 58
Chris@170 59 static size_t getCacheSize(size_t width, size_t height, StorageType type);
Chris@170 60
Chris@335 61 virtual Type getType() { return FileCache; }
Chris@335 62
Chris@148 63 protected:
Chris@148 64 char *m_writebuf;
Chris@148 65 mutable char *m_readbuf;
Chris@148 66 mutable size_t m_readbufCol;
Chris@148 67 mutable size_t m_readbufWidth;
Chris@148 68
Chris@148 69 float getFromReadBufStandard(size_t x, size_t y) const {
Chris@148 70 if (m_readbuf &&
Chris@148 71 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 72 return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 73 } else {
Chris@148 74 populateReadBuf(x);
Chris@148 75 return getFromReadBufStandard(x, y);
Chris@148 76 }
Chris@148 77 }
Chris@148 78
Chris@148 79 float getFromReadBufCompactUnsigned(size_t x, size_t y) const {
Chris@148 80 if (m_readbuf &&
Chris@148 81 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 82 return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 83 } else {
Chris@148 84 populateReadBuf(x);
Chris@148 85 return getFromReadBufCompactUnsigned(x, y);
Chris@148 86 }
Chris@148 87 }
Chris@148 88
Chris@148 89 float getFromReadBufCompactSigned(size_t x, size_t y) const {
Chris@148 90 if (m_readbuf &&
Chris@148 91 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 92 return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 93 } else {
Chris@148 94 populateReadBuf(x);
Chris@148 95 return getFromReadBufCompactSigned(x, y);
Chris@148 96 }
Chris@148 97 }
Chris@148 98
Chris@183 99 void populateReadBuf(size_t x) const;
Chris@148 100
Chris@148 101 float getNormalizationFactor(size_t col) const {
Chris@266 102 size_t h = m_mfc->getHeight();
Chris@266 103 if (h < m_factorSize) return 0;
Chris@148 104 if (m_storageType != Compact) {
Chris@266 105 return getFromReadBufStandard(col, h - 1);
Chris@148 106 } else {
Chris@266 107 union {
Chris@266 108 float f;
Chris@266 109 uint16_t u[2];
Chris@266 110 } factor;
Chris@266 111 if (!m_readbuf ||
Chris@266 112 !(m_readbufCol == col ||
Chris@266 113 (m_readbufWidth > 1 && m_readbufCol+1 == col))) {
Chris@266 114 populateReadBuf(col);
Chris@266 115 }
Chris@266 116 size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h;
Chris@266 117 factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2];
Chris@266 118 factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1];
Chris@266 119 return factor.f;
Chris@148 120 }
Chris@148 121 }
Chris@148 122
Chris@266 123 void setNormalizationFactorToWritebuf(float newfactor) {
Chris@266 124 size_t h = m_mfc->getHeight();
Chris@266 125 if (h < m_factorSize) return;
Chris@266 126 if (m_storageType != Compact) {
Chris@266 127 ((float *)m_writebuf)[h - 1] = newfactor;
Chris@266 128 } else {
Chris@266 129 union {
Chris@266 130 float f;
Chris@266 131 uint16_t u[2];
Chris@266 132 } factor;
Chris@266 133 factor.f = newfactor;
Chris@266 134 ((uint16_t *)m_writebuf)[h - 2] = factor.u[0];
Chris@266 135 ((uint16_t *)m_writebuf)[h - 1] = factor.u[1];
Chris@266 136 }
Chris@266 137 }
Chris@266 138
Chris@148 139 MatrixFile *m_mfc;
Chris@148 140 QMutex m_writeMutex;
Chris@148 141 StorageType m_storageType;
Chris@266 142 size_t m_factorSize;
Chris@148 143 };
Chris@148 144
Chris@148 145 #endif