svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #ifndef _FFT_MODEL_H_ 00017 #define _FFT_MODEL_H_ 00018 00019 #include "data/fft/FFTDataServer.h" 00020 #include "DenseThreeDimensionalModel.h" 00021 00022 #include <set> 00023 #include <map> 00024 00033 class FFTModel : public DenseThreeDimensionalModel 00034 { 00035 Q_OBJECT 00036 00037 public: 00058 FFTModel(const DenseTimeValueModel *model, 00059 int channel, 00060 WindowType windowType, 00061 int windowSize, 00062 int windowIncrement, 00063 int fftSize, 00064 bool polar, 00065 StorageAdviser::Criteria criteria = StorageAdviser::NoCriteria, 00066 int fillFromColumn = 0); 00067 ~FFTModel(); 00068 00069 inline float getMagnitudeAt(int x, int y) { 00070 return m_server->getMagnitudeAt(x << m_xshift, y << m_yshift); 00071 } 00072 inline float getNormalizedMagnitudeAt(int x, int y) { 00073 return m_server->getNormalizedMagnitudeAt(x << m_xshift, y << m_yshift); 00074 } 00075 inline float getMaximumMagnitudeAt(int x) { 00076 return m_server->getMaximumMagnitudeAt(x << m_xshift); 00077 } 00078 inline float getPhaseAt(int x, int y) { 00079 return m_server->getPhaseAt(x << m_xshift, y << m_yshift); 00080 } 00081 inline void getValuesAt(int x, int y, float &real, float &imaginary) { 00082 m_server->getValuesAt(x << m_xshift, y << m_yshift, real, imaginary); 00083 } 00084 inline bool isColumnAvailable(int x) const { 00085 return m_server->isColumnReady(x << m_xshift); 00086 } 00087 00088 inline bool getMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) { 00089 return m_server->getMagnitudesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio()); 00090 } 00091 inline bool getNormalizedMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) { 00092 return m_server->getNormalizedMagnitudesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio()); 00093 } 00094 inline bool getPhasesAt(int x, float *values, int minbin = 0, int count = 0) { 00095 return m_server->getPhasesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio()); 00096 } 00097 inline bool getValuesAt(int x, float *reals, float *imaginaries, int minbin = 0, int count = 0) { 00098 return m_server->getValuesAt(x << m_xshift, reals, imaginaries, minbin << m_yshift, count, getYRatio()); 00099 } 00100 00101 inline int getFillExtent() const { return m_server->getFillExtent(); } 00102 00103 // DenseThreeDimensionalModel and Model methods: 00104 // 00105 inline virtual int getWidth() const { 00106 return m_server->getWidth() >> m_xshift; 00107 } 00108 inline virtual int getHeight() const { 00109 // If there is no y-shift, the server's height (based on its 00110 // fftsize/2 + 1) is correct. If there is a shift, then the 00111 // server is using a larger fft size than we want, so we shift 00112 // it right as many times as necessary, but then we need to 00113 // re-add the "+1" part (because ((fftsize*2)/2 + 1) / 2 != 00114 // fftsize/2 + 1). 00115 return (m_server->getHeight() >> m_yshift) + (m_yshift > 0 ? 1 : 0); 00116 } 00117 virtual float getValueAt(int x, int y) const { 00118 return const_cast<FFTModel *>(this)->getMagnitudeAt(x, y); 00119 } 00120 virtual bool isOK() const { 00121 return m_server && m_server->getModel(); 00122 } 00123 virtual int getStartFrame() const { 00124 return 0; 00125 } 00126 virtual int getEndFrame() const { 00127 return getWidth() * getResolution() + getResolution(); 00128 } 00129 virtual int getSampleRate() const; 00130 virtual int getResolution() const { 00131 return m_server->getWindowIncrement() << m_xshift; 00132 } 00133 virtual int getYBinCount() const { 00134 return getHeight(); 00135 } 00136 virtual float getMinimumLevel() const { 00137 return 0.f; // Can't provide 00138 } 00139 virtual float getMaximumLevel() const { 00140 return 1.f; // Can't provide 00141 } 00142 virtual Column getColumn(int x) const; 00143 virtual QString getBinName(int n) const; 00144 00145 virtual bool shouldUseLogValueScale() const { 00146 return true; // Although obviously it's up to the user... 00147 } 00148 00154 virtual bool estimateStableFrequency(int x, int y, float &frequency); 00155 00156 enum PeakPickType 00157 { 00158 AllPeaks, 00159 MajorPeaks, 00160 MajorPitchAdaptivePeaks 00161 }; 00162 00163 typedef std::set<int> PeakLocationSet; // bin 00164 typedef std::map<int, float> PeakSet; // bin -> freq 00165 00170 virtual PeakLocationSet getPeaks(PeakPickType type, int x, 00171 int ymin = 0, int ymax = 0); 00172 00176 virtual PeakSet getPeakFrequencies(PeakPickType type, int x, 00177 int ymin = 0, int ymax = 0); 00178 00179 virtual int getCompletion() const { return m_server->getFillCompletion(); } 00180 virtual QString getError() const { return m_server->getError(); } 00181 00182 virtual Model *clone() const; 00183 00184 virtual void suspend() { m_server->suspend(); } 00185 virtual void suspendWrites() { m_server->suspendWrites(); } 00186 virtual void resume() { m_server->resume(); } 00187 00188 QString getTypeName() const { return tr("FFT"); } 00189 00190 public slots: 00191 void sourceModelAboutToBeDeleted(); 00192 00193 private: 00194 FFTModel(const FFTModel &); // not implemented 00195 FFTModel &operator=(const FFTModel &); // not implemented 00196 00197 FFTDataServer *m_server; 00198 int m_xshift; 00199 int m_yshift; 00200 00201 FFTDataServer *getServer(const DenseTimeValueModel *, 00202 int, WindowType, int, int, int, 00203 bool, StorageAdviser::Criteria, int); 00204 00205 int getPeakPickWindowSize(PeakPickType type, int sampleRate, 00206 int bin, float &percentile) const; 00207 00208 int getYRatio() { 00209 int ys = m_yshift; 00210 int r = 1; 00211 while (ys) { --ys; r <<= 1; } 00212 return r; 00213 } 00214 }; 00215 00216 #endif