annotate data/fft/FFTFileCacheReader.h @ 683:f84f147572b9

Avoid crash when generating/processing a very short file
author Chris Cannam
date Wed, 11 May 2011 11:04:02 +0100
parents 8accc7969c1c
children 59e7fe1b1003
rev   line source
Chris@537 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@537 2
Chris@537 3 /*
Chris@537 4 Sonic Visualiser
Chris@537 5 An audio file viewer and annotation editor.
Chris@537 6 Centre for Digital Music, Queen Mary, University of London.
Chris@537 7 This file copyright 2006-2009 Chris Cannam and QMUL.
Chris@537 8
Chris@537 9 This program is free software; you can redistribute it and/or
Chris@537 10 modify it under the terms of the GNU General Public License as
Chris@537 11 published by the Free Software Foundation; either version 2 of the
Chris@537 12 License, or (at your option) any later version. See the file
Chris@537 13 COPYING included with this distribution for more information.
Chris@537 14 */
Chris@537 15
Chris@537 16 #ifndef _FFT_FILE_CACHE_READER_H_
Chris@537 17 #define _FFT_FILE_CACHE_READER_H_
Chris@537 18
Chris@537 19 #include "data/fileio/MatrixFile.h"
Chris@537 20 #include "FFTCacheReader.h"
Chris@537 21 #include "FFTCacheStorageType.h"
Chris@537 22
Chris@537 23 class FFTFileCacheWriter;
Chris@537 24
Chris@537 25 class FFTFileCacheReader : public FFTCacheReader
Chris@537 26 {
Chris@537 27 public:
Chris@537 28 FFTFileCacheReader(FFTFileCacheWriter *);
Chris@537 29 ~FFTFileCacheReader();
Chris@537 30
Chris@537 31 size_t getWidth() const;
Chris@537 32 size_t getHeight() const;
Chris@537 33
Chris@537 34 float getMagnitudeAt(size_t x, size_t y) const;
Chris@537 35 float getNormalizedMagnitudeAt(size_t x, size_t y) const;
Chris@537 36 float getMaximumMagnitudeAt(size_t x) const;
Chris@537 37 float getPhaseAt(size_t x, size_t y) const;
Chris@537 38
Chris@537 39 void getValuesAt(size_t x, size_t y, float &real, float &imag) const;
Chris@537 40 void getMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) const;
Chris@537 41
Chris@537 42 bool haveSetColumnAt(size_t x) const;
Chris@537 43
Chris@537 44 static size_t getCacheSize(size_t width, size_t height,
Chris@537 45 FFTCache::StorageType type);
Chris@537 46
Chris@537 47 FFTCache::StorageType getStorageType() const { return m_storageType; }
Chris@537 48
Chris@537 49 protected:
Chris@537 50 mutable char *m_readbuf;
Chris@537 51 mutable size_t m_readbufCol;
Chris@537 52 mutable size_t m_readbufWidth;
Chris@555 53 mutable bool m_readbufGood;
Chris@537 54
Chris@537 55 float getFromReadBufStandard(size_t x, size_t y) const {
Chris@537 56 float v;
Chris@537 57 if (m_readbuf &&
Chris@537 58 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@537 59 v = ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@537 60 return v;
Chris@537 61 } else {
Chris@537 62 populateReadBuf(x);
Chris@537 63 v = getFromReadBufStandard(x, y);
Chris@537 64 return v;
Chris@537 65 }
Chris@537 66 }
Chris@537 67
Chris@537 68 float getFromReadBufCompactUnsigned(size_t x, size_t y) const {
Chris@537 69 float v;
Chris@537 70 if (m_readbuf &&
Chris@537 71 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@537 72 v = ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@537 73 return v;
Chris@537 74 } else {
Chris@537 75 populateReadBuf(x);
Chris@537 76 v = getFromReadBufCompactUnsigned(x, y);
Chris@537 77 return v;
Chris@537 78 }
Chris@537 79 }
Chris@537 80
Chris@537 81 float getFromReadBufCompactSigned(size_t x, size_t y) const {
Chris@537 82 float v;
Chris@537 83 if (m_readbuf &&
Chris@537 84 (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) {
Chris@537 85 v = ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y];
Chris@537 86 return v;
Chris@537 87 } else {
Chris@537 88 populateReadBuf(x);
Chris@537 89 v = getFromReadBufCompactSigned(x, y);
Chris@537 90 return v;
Chris@537 91 }
Chris@537 92 }
Chris@537 93
Chris@537 94 void populateReadBuf(size_t x) const;
Chris@537 95
Chris@537 96 float getNormalizationFactor(size_t col) const {
Chris@537 97 size_t h = m_mfc->getHeight();
Chris@537 98 if (h < m_factorSize) return 0;
Chris@537 99 if (m_storageType != FFTCache::Compact) {
Chris@537 100 return getFromReadBufStandard(col, h - 1);
Chris@537 101 } else {
Chris@537 102 union {
Chris@537 103 float f;
Chris@537 104 uint16_t u[2];
Chris@537 105 } factor;
Chris@537 106 if (!m_readbuf ||
Chris@537 107 !(m_readbufCol == col ||
Chris@537 108 (m_readbufWidth > 1 && m_readbufCol+1 == col))) {
Chris@537 109 populateReadBuf(col);
Chris@537 110 }
Chris@537 111 size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h;
Chris@537 112 factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2];
Chris@537 113 factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1];
Chris@537 114 return factor.f;
Chris@537 115 }
Chris@537 116 }
Chris@537 117
Chris@537 118 FFTCache::StorageType m_storageType;
Chris@537 119 size_t m_factorSize;
Chris@537 120 MatrixFile *m_mfc;
Chris@537 121 };
Chris@537 122
Chris@537 123 #endif