annotate data/model/FFTModel.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_MODEL_H_
lbajardsilogic@0 17 #define _FFT_MODEL_H_
lbajardsilogic@0 18
lbajardsilogic@0 19 #include "data/fft/FFTDataServer.h"
lbajardsilogic@0 20 #include "DenseThreeDimensionalModel.h"
lbajardsilogic@0 21
lbajardsilogic@0 22 /**
lbajardsilogic@0 23 * An implementation of DenseThreeDimensionalModel that makes FFT data
lbajardsilogic@0 24 * derived from a DenseTimeValueModel available as a generic data grid.
lbajardsilogic@0 25 * The FFT data is acquired using FFTDataServer.
lbajardsilogic@0 26 */
lbajardsilogic@0 27
lbajardsilogic@0 28 class FFTModel : public DenseThreeDimensionalModel
lbajardsilogic@0 29 {
lbajardsilogic@0 30 Q_OBJECT
lbajardsilogic@0 31
lbajardsilogic@0 32 public:
lbajardsilogic@0 33 /**
lbajardsilogic@0 34 * Construct an FFT model derived from the given
lbajardsilogic@0 35 * DenseTimeValueModel, with the given window parameters and FFT
lbajardsilogic@0 36 * size (which may exceed the window size, for zero-padded FFTs).
lbajardsilogic@0 37 *
lbajardsilogic@0 38 * If the model has multiple channels use only the given channel,
lbajardsilogic@0 39 * unless the channel is -1 in which case merge all available
lbajardsilogic@0 40 * channels.
lbajardsilogic@0 41 *
lbajardsilogic@0 42 * If polar is true, the data will normally be retrieved from the
lbajardsilogic@0 43 * FFT model in magnitude/phase form; otherwise it will normally
lbajardsilogic@0 44 * be retrieved in "cartesian" real/imaginary form. The results
lbajardsilogic@0 45 * should be the same either way, but a "polar" model addressed in
lbajardsilogic@0 46 * "cartesian" form or vice versa may suffer a performance
lbajardsilogic@0 47 * penalty.
lbajardsilogic@0 48 *
lbajardsilogic@0 49 * The fillFromColumn argument gives a hint that the FFT data
lbajardsilogic@0 50 * server should aim to start calculating FFT data at that column
lbajardsilogic@0 51 * number if possible, as that is likely to be requested first.
lbajardsilogic@0 52 */
lbajardsilogic@0 53 FFTModel(const DenseTimeValueModel *model,
lbajardsilogic@0 54 int channel,
lbajardsilogic@0 55 WindowType windowType,
lbajardsilogic@0 56 size_t windowSize,
lbajardsilogic@0 57 size_t windowIncrement,
lbajardsilogic@0 58 size_t fftSize,
lbajardsilogic@0 59 bool polar,
lbajardsilogic@0 60 size_t fillFromColumn = 0);
lbajardsilogic@0 61 ~FFTModel();
lbajardsilogic@0 62
lbajardsilogic@0 63 float getMagnitudeAt(size_t x, size_t y) {
lbajardsilogic@0 64 return m_server->getMagnitudeAt(x << m_xshift, y << m_yshift);
lbajardsilogic@0 65 }
lbajardsilogic@0 66 float getNormalizedMagnitudeAt(size_t x, size_t y) {
lbajardsilogic@0 67 return m_server->getNormalizedMagnitudeAt(x << m_xshift, y << m_yshift);
lbajardsilogic@0 68 }
lbajardsilogic@0 69 float getMaximumMagnitudeAt(size_t x) {
lbajardsilogic@0 70 return m_server->getMaximumMagnitudeAt(x << m_xshift);
lbajardsilogic@0 71 }
lbajardsilogic@0 72 float getPhaseAt(size_t x, size_t y) {
lbajardsilogic@0 73 return m_server->getPhaseAt(x << m_xshift, y << m_yshift);
lbajardsilogic@0 74 }
lbajardsilogic@0 75 void getValuesAt(size_t x, size_t y, float &real, float &imaginary) {
lbajardsilogic@0 76 m_server->getValuesAt(x << m_xshift, y << m_yshift, real, imaginary);
lbajardsilogic@0 77 }
lbajardsilogic@0 78 bool isColumnAvailable(size_t x) const {
lbajardsilogic@0 79 return m_server->isColumnReady(x << m_xshift);
lbajardsilogic@0 80 }
lbajardsilogic@0 81
lbajardsilogic@0 82 size_t getFillExtent() const { return m_server->getFillExtent(); }
lbajardsilogic@0 83
lbajardsilogic@0 84 // DenseThreeDimensionalModel and Model methods:
lbajardsilogic@0 85 //
lbajardsilogic@0 86 virtual size_t getWidth() const {
lbajardsilogic@0 87 return m_server->getWidth() >> m_xshift;
lbajardsilogic@0 88 }
lbajardsilogic@0 89 virtual size_t getHeight() const {
lbajardsilogic@0 90 // If there is no y-shift, the server's height (based on its
lbajardsilogic@0 91 // fftsize/2 + 1) is correct. If there is a shift, then the
lbajardsilogic@0 92 // server is using a larger fft size than we want, so we shift
lbajardsilogic@0 93 // it right as many times as necessary, but then we need to
lbajardsilogic@0 94 // re-add the "+1" part (because ((fftsize*2)/2 + 1) / 2 !=
lbajardsilogic@0 95 // fftsize/2 + 1).
lbajardsilogic@0 96 return (m_server->getHeight() >> m_yshift) + (m_yshift > 0 ? 1 : 0);
lbajardsilogic@0 97 }
lbajardsilogic@0 98 virtual float getValueAt(size_t x, size_t y) const {
lbajardsilogic@0 99 return const_cast<FFTModel *>(this)->getMagnitudeAt(x, y);
lbajardsilogic@0 100 }
lbajardsilogic@0 101 virtual bool isOK() const {
lbajardsilogic@0 102 return m_server && m_server->getModel();
lbajardsilogic@0 103 }
lbajardsilogic@0 104 virtual size_t getStartFrame() const {
lbajardsilogic@0 105 return 0;
lbajardsilogic@0 106 }
lbajardsilogic@0 107 virtual size_t getEndFrame() const {
lbajardsilogic@0 108 return getWidth() * getResolution() + getResolution();
lbajardsilogic@0 109 }
lbajardsilogic@0 110 virtual size_t getSampleRate() const;
lbajardsilogic@0 111 virtual size_t getResolution() const {
lbajardsilogic@0 112 return m_server->getWindowIncrement() << m_xshift;
lbajardsilogic@0 113 }
lbajardsilogic@0 114 virtual size_t getYBinCount() const {
lbajardsilogic@0 115 return getHeight();
lbajardsilogic@0 116 }
lbajardsilogic@0 117 virtual float getMinimumLevel() const {
lbajardsilogic@0 118 return 0.f; // Can't provide
lbajardsilogic@0 119 }
lbajardsilogic@0 120 virtual float getMaximumLevel() const {
lbajardsilogic@0 121 return 1.f; // Can't provide
lbajardsilogic@0 122 }
lbajardsilogic@0 123 virtual void getColumn(size_t x, Column &result) const;
lbajardsilogic@0 124 virtual QString getBinName(size_t n) const;
lbajardsilogic@0 125
lbajardsilogic@0 126 virtual int getCompletion() const { return m_server->getFillCompletion(); }
lbajardsilogic@0 127
lbajardsilogic@0 128 virtual Model *clone() const;
lbajardsilogic@0 129
lbajardsilogic@0 130 virtual void suspend() { m_server->suspend(); }
lbajardsilogic@0 131 virtual void suspendWrites() { m_server->suspendWrites(); }
lbajardsilogic@0 132 virtual void resume() { m_server->resume(); }
lbajardsilogic@0 133
lbajardsilogic@0 134 private:
lbajardsilogic@0 135 FFTModel(const FFTModel &);
lbajardsilogic@0 136 FFTModel &operator=(const FFTModel &); // not implemented
lbajardsilogic@0 137
lbajardsilogic@0 138 FFTDataServer *m_server;
lbajardsilogic@0 139 int m_xshift;
lbajardsilogic@0 140 int m_yshift;
lbajardsilogic@0 141 };
lbajardsilogic@0 142
lbajardsilogic@0 143 #endif