annotate data/fft/FFTFileCache.h @ 299:576be0d0d218

* Merge transform directory from sv-match-alignment branch (the previous comment included notes for this stuff, but I missed it in the actual merge) * Fix crash when a transform fails to create an output model and the thread that created the transform then deletes its input model thinking it's no longer needed, even though the transform run thread is still using it -- fix is to wait() on the transform before returning the null output model
author Chris Cannam
date Fri, 28 Sep 2007 16:15:06 +0000
parents 2268963dabd1
children 02d2ad95ea52
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@148 61 protected:
Chris@148 62 char *m_writebuf;
Chris@148 63 mutable char *m_readbuf;
Chris@148 64 mutable size_t m_readbufCol;
Chris@148 65 mutable size_t m_readbufWidth;
Chris@148 66
Chris@148 67 float getFromReadBufStandard(size_t x, size_t y) const {
Chris@148 68 if (m_readbuf &&
Chris@148 69 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 70 return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 71 } else {
Chris@148 72 populateReadBuf(x);
Chris@148 73 return getFromReadBufStandard(x, y);
Chris@148 74 }
Chris@148 75 }
Chris@148 76
Chris@148 77 float getFromReadBufCompactUnsigned(size_t x, size_t y) const {
Chris@148 78 if (m_readbuf &&
Chris@148 79 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 80 return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 81 } else {
Chris@148 82 populateReadBuf(x);
Chris@148 83 return getFromReadBufCompactUnsigned(x, y);
Chris@148 84 }
Chris@148 85 }
Chris@148 86
Chris@148 87 float getFromReadBufCompactSigned(size_t x, size_t y) const {
Chris@148 88 if (m_readbuf &&
Chris@148 89 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@148 90 return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@148 91 } else {
Chris@148 92 populateReadBuf(x);
Chris@148 93 return getFromReadBufCompactSigned(x, y);
Chris@148 94 }
Chris@148 95 }
Chris@148 96
Chris@183 97 void populateReadBuf(size_t x) const;
Chris@148 98
Chris@148 99 float getNormalizationFactor(size_t col) const {
Chris@266 100 size_t h = m_mfc->getHeight();
Chris@266 101 if (h < m_factorSize) return 0;
Chris@148 102 if (m_storageType != Compact) {
Chris@266 103 return getFromReadBufStandard(col, h - 1);
Chris@148 104 } else {
Chris@266 105 union {
Chris@266 106 float f;
Chris@266 107 uint16_t u[2];
Chris@266 108 } factor;
Chris@266 109 if (!m_readbuf ||
Chris@266 110 !(m_readbufCol == col ||
Chris@266 111 (m_readbufWidth > 1 && m_readbufCol+1 == col))) {
Chris@266 112 populateReadBuf(col);
Chris@266 113 }
Chris@266 114 size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h;
Chris@266 115 factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2];
Chris@266 116 factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1];
Chris@266 117 return factor.f;
Chris@148 118 }
Chris@148 119 }
Chris@148 120
Chris@266 121 void setNormalizationFactorToWritebuf(float newfactor) {
Chris@266 122 size_t h = m_mfc->getHeight();
Chris@266 123 if (h < m_factorSize) return;
Chris@266 124 if (m_storageType != Compact) {
Chris@266 125 ((float *)m_writebuf)[h - 1] = newfactor;
Chris@266 126 } else {
Chris@266 127 union {
Chris@266 128 float f;
Chris@266 129 uint16_t u[2];
Chris@266 130 } factor;
Chris@266 131 factor.f = newfactor;
Chris@266 132 ((uint16_t *)m_writebuf)[h - 2] = factor.u[0];
Chris@266 133 ((uint16_t *)m_writebuf)[h - 1] = factor.u[1];
Chris@266 134 }
Chris@266 135 }
Chris@266 136
Chris@148 137 MatrixFile *m_mfc;
Chris@148 138 QMutex m_writeMutex;
Chris@148 139 StorageType m_storageType;
Chris@266 140 size_t m_factorSize;
Chris@148 141 };
Chris@148 142
Chris@148 143 #endif