annotate data/fft/FFTMemoryCache.h @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents fc9323a41f5a
children
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@0 2
lbajardsilogic@0 3 /*
lbajardsilogic@0 4 Sonic Visualiser
lbajardsilogic@0 5 An audio file viewer and annotation editor.
lbajardsilogic@0 6 Centre for Digital Music, Queen Mary, University of London.
lbajardsilogic@0 7 This file copyright 2006 Chris Cannam.
lbajardsilogic@0 8
lbajardsilogic@0 9 This program is free software; you can redistribute it and/or
lbajardsilogic@0 10 modify it under the terms of the GNU General Public License as
lbajardsilogic@0 11 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@0 12 License, or (at your option) any later version. See the file
lbajardsilogic@0 13 COPYING included with this distribution for more information.
lbajardsilogic@0 14 */
lbajardsilogic@0 15
lbajardsilogic@0 16 #ifndef _FFT_MEMORY_CACHE_H_
lbajardsilogic@0 17 #define _FFT_MEMORY_CACHE_H_
lbajardsilogic@0 18
lbajardsilogic@0 19 #include "FFTCache.h"
lbajardsilogic@0 20
lbajardsilogic@0 21 #include "base/ResizeableBitset.h"
lbajardsilogic@0 22
lbajardsilogic@0 23 /**
lbajardsilogic@0 24 * In-memory FFT cache. For this we want to cache magnitude with
lbajardsilogic@0 25 * enough resolution to have gain applied afterwards and determine
lbajardsilogic@0 26 * whether something is a peak or not, and also cache phase rather
lbajardsilogic@0 27 * than only phase-adjusted frequency so that we don't have to
lbajardsilogic@0 28 * recalculate if switching between phase and magnitude displays. At
lbajardsilogic@0 29 * the same time, we don't want to take up too much memory. It's not
lbajardsilogic@0 30 * expected to be accurate enough to be used as input for DSP or
lbajardsilogic@0 31 * resynthesis code.
lbajardsilogic@0 32 *
lbajardsilogic@0 33 * This implies probably 16 bits for a normalized magnitude and at
lbajardsilogic@0 34 * most 16 bits for phase.
lbajardsilogic@0 35 *
lbajardsilogic@0 36 * Each column's magnitudes are expected to be stored normalized
lbajardsilogic@0 37 * to [0,1] with respect to the column, so the normalization
lbajardsilogic@0 38 * factor should be calculated before all values in a column, and
lbajardsilogic@0 39 * set appropriately.
lbajardsilogic@0 40 */
lbajardsilogic@0 41
lbajardsilogic@0 42 class FFTMemoryCache : public FFTCache
lbajardsilogic@0 43 {
lbajardsilogic@0 44 public:
lbajardsilogic@0 45 FFTMemoryCache(); // of size zero, call resize() before using
lbajardsilogic@0 46 virtual ~FFTMemoryCache();
lbajardsilogic@0 47
lbajardsilogic@0 48 virtual size_t getWidth() const { return m_width; }
lbajardsilogic@0 49 virtual size_t getHeight() const { return m_height; }
lbajardsilogic@0 50
lbajardsilogic@0 51 virtual void resize(size_t width, size_t height);
lbajardsilogic@0 52 virtual void reset(); // zero-fill or 1-fill as appropriate without changing size
lbajardsilogic@0 53
lbajardsilogic@0 54 virtual float getMagnitudeAt(size_t x, size_t y) const {
lbajardsilogic@0 55 return getNormalizedMagnitudeAt(x, y) * m_factor[x];
lbajardsilogic@0 56 }
lbajardsilogic@0 57
lbajardsilogic@0 58 virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const {
lbajardsilogic@0 59 return float(m_magnitude[x][y]) / 65535.0;
lbajardsilogic@0 60 }
lbajardsilogic@0 61
lbajardsilogic@0 62 virtual float getMaximumMagnitudeAt(size_t x) const {
lbajardsilogic@0 63 return m_factor[x];
lbajardsilogic@0 64 }
lbajardsilogic@0 65
lbajardsilogic@0 66 virtual float getPhaseAt(size_t x, size_t y) const {
lbajardsilogic@0 67 int16_t i = (int16_t)m_phase[x][y];
lbajardsilogic@0 68 return (float(i) / 32767.0) * M_PI;
lbajardsilogic@0 69 }
lbajardsilogic@0 70
lbajardsilogic@0 71 virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const {
lbajardsilogic@0 72 float mag = getMagnitudeAt(x, y);
lbajardsilogic@0 73 float phase = getPhaseAt(x, y);
lbajardsilogic@0 74 real = mag * cosf(phase);
lbajardsilogic@0 75 imag = mag * sinf(phase);
lbajardsilogic@0 76 }
lbajardsilogic@0 77
lbajardsilogic@0 78 virtual void setNormalizationFactor(size_t x, float factor) {
lbajardsilogic@0 79 if (x < m_width) m_factor[x] = factor;
lbajardsilogic@0 80 }
lbajardsilogic@0 81
lbajardsilogic@0 82 virtual void setMagnitudeAt(size_t x, size_t y, float mag) {
lbajardsilogic@0 83 // norm factor must already be set
lbajardsilogic@0 84 setNormalizedMagnitudeAt(x, y, mag / m_factor[x]);
lbajardsilogic@0 85 }
lbajardsilogic@0 86
lbajardsilogic@0 87 virtual void setNormalizedMagnitudeAt(size_t x, size_t y, float norm) {
lbajardsilogic@0 88 if (x < m_width && y < m_height) {
lbajardsilogic@0 89 m_magnitude[x][y] = uint16_t(norm * 65535.0);
lbajardsilogic@0 90 }
lbajardsilogic@0 91 }
lbajardsilogic@0 92
lbajardsilogic@0 93 virtual void setPhaseAt(size_t x, size_t y, float phase) {
lbajardsilogic@0 94 // phase in range -pi -> pi
lbajardsilogic@0 95 if (x < m_width && y < m_height) {
lbajardsilogic@0 96 m_phase[x][y] = uint16_t(int16_t((phase * 32767) / M_PI));
lbajardsilogic@0 97 }
lbajardsilogic@0 98 }
lbajardsilogic@0 99
lbajardsilogic@0 100 virtual bool haveSetColumnAt(size_t x) const {
lbajardsilogic@0 101 return m_colset.get(x);
lbajardsilogic@0 102 }
lbajardsilogic@0 103
lbajardsilogic@0 104 virtual void setColumnAt(size_t x, float *mags, float *phases, float factor) {
lbajardsilogic@0 105 setNormalizationFactor(x, factor);
lbajardsilogic@0 106 for (size_t y = 0; y < m_height; ++y) {
lbajardsilogic@0 107 setMagnitudeAt(x, y, mags[y]);
lbajardsilogic@0 108 setPhaseAt(x, y, phases[y]);
lbajardsilogic@0 109 }
lbajardsilogic@0 110 m_colset.set(x);
lbajardsilogic@0 111 }
lbajardsilogic@0 112
lbajardsilogic@0 113 virtual void setColumnAt(size_t x, float *reals, float *imags);
lbajardsilogic@0 114
lbajardsilogic@0 115 static size_t getCacheSize(size_t width, size_t height);
lbajardsilogic@0 116
lbajardsilogic@0 117 private:
lbajardsilogic@0 118 size_t m_width;
lbajardsilogic@0 119 size_t m_height;
lbajardsilogic@0 120 uint16_t **m_magnitude;
lbajardsilogic@0 121 uint16_t **m_phase;
lbajardsilogic@0 122 float *m_factor;
lbajardsilogic@0 123 ResizeableBitset m_colset;
lbajardsilogic@0 124
lbajardsilogic@0 125 void resize(uint16_t **&, size_t, size_t);
lbajardsilogic@0 126 };
lbajardsilogic@0 127
lbajardsilogic@0 128
lbajardsilogic@0 129 #endif
lbajardsilogic@0 130