svcore  1.9
FFTMemoryCache.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #ifndef _FFT_MEMORY_CACHE_H_
17 #define _FFT_MEMORY_CACHE_H_
18 
19 #include "FFTCacheReader.h"
20 #include "FFTCacheWriter.h"
21 #include "FFTCacheStorageType.h"
22 #include "base/ResizeableBitset.h"
23 #include "base/Profiler.h"
24 
25 #include <QReadWriteLock>
26 
47 {
48 public:
50  int width, int height);
52 
53  int getWidth() const { return m_width; }
54  int getHeight() const { return m_height; }
55 
56  float getMagnitudeAt(int x, int y) const {
58  Profiler profiler("FFTMemoryCache::getMagnitudeAt: cart to polar");
59  return sqrtf(m_freal[x][y] * m_freal[x][y] +
60  m_fimag[x][y] * m_fimag[x][y]);
61  } else {
62  return getNormalizedMagnitudeAt(x, y) * m_factor[x];
63  }
64  }
65 
66  float getNormalizedMagnitudeAt(int x, int y) const {
68  else if (m_storageType == FFTCache::Polar) return m_fmagnitude[x][y];
69  else return float(m_magnitude[x][y]) / 65535.0;
70  }
71 
72  float getMaximumMagnitudeAt(int x) const {
73  return m_factor[x];
74  }
75 
76  float getPhaseAt(int x, int y) const {
78  Profiler profiler("FFTMemoryCache::getValuesAt: cart to polar");
79  return atan2f(m_fimag[x][y], m_freal[x][y]);
80  } else if (m_storageType == FFTCache::Polar) {
81  return m_fphase[x][y];
82  } else {
83  int16_t i = (int16_t)m_phase[x][y];
84  return (float(i) / 32767.0) * M_PI;
85  }
86  }
87 
88  void getValuesAt(int x, int y, float &real, float &imag) const {
90  real = m_freal[x][y];
91  imag = m_fimag[x][y];
92  } else {
93  Profiler profiler("FFTMemoryCache::getValuesAt: polar to cart");
94  float mag = getMagnitudeAt(x, y);
95  float phase = getPhaseAt(x, y);
96  real = mag * cosf(phase);
97  imag = mag * sinf(phase);
98  }
99  }
100 
101  void getMagnitudesAt(int x, float *values, int minbin, int count, int step) const
102  {
104  for (int i = 0; i < count; ++i) {
105  int y = i * step + minbin;
106  values[i] = sqrtf(m_freal[x][y] * m_freal[x][y] +
107  m_fimag[x][y] * m_fimag[x][y]);
108  }
109  } else if (m_storageType == FFTCache::Polar) {
110  for (int i = 0; i < count; ++i) {
111  int y = i * step + minbin;
112  values[i] = m_fmagnitude[x][y] * m_factor[x];
113  }
114  } else {
115  for (int i = 0; i < count; ++i) {
116  int y = i * step + minbin;
117  values[i] = (float(m_magnitude[x][y]) * m_factor[x]) / 65535.0;
118  }
119  }
120  }
121 
122  bool haveSetColumnAt(int x) const {
123  m_colsetLock.lockForRead();
124  bool have = m_colset.get(x);
125  m_colsetLock.unlock();
126  return have;
127  }
128 
129  void setColumnAt(int x, float *mags, float *phases, float factor);
130 
131  void setColumnAt(int x, float *reals, float *imags);
132 
133  void allColumnsWritten() { }
134 
135  static int getCacheSize(int width, int height,
136  FFTCache::StorageType type);
137 
139 
140 private:
141  int m_width;
142  int m_height;
143  uint16_t **m_magnitude;
144  uint16_t **m_phase;
145  float **m_fmagnitude;
146  float **m_fphase;
147  float **m_freal;
148  float **m_fimag;
149  float *m_factor;
152  mutable QReadWriteLock m_colsetLock;
153 
154  void initialise();
155 
156  void setNormalizationFactor(int x, float factor) {
157  if (x < m_width) m_factor[x] = factor;
158  }
159 
160  void setMagnitudeAt(int x, int y, float mag) {
161  // norm factor must already be set
162  setNormalizedMagnitudeAt(x, y, mag / m_factor[x]);
163  }
164 
165  void setNormalizedMagnitudeAt(int x, int y, float norm) {
166  if (x < m_width && y < m_height) {
167  if (m_storageType == FFTCache::Polar) m_fmagnitude[x][y] = norm;
168  else m_magnitude[x][y] = uint16_t(norm * 65535.0);
169  }
170  }
171 
172  void setPhaseAt(int x, int y, float phase) {
173  // phase in range -pi -> pi
174  if (x < m_width && y < m_height) {
175  if (m_storageType == FFTCache::Polar) m_fphase[x][y] = phase;
176  else m_phase[x][y] = uint16_t(int16_t((phase * 32767) / M_PI));
177  }
178  }
179 
180  void initialise(uint16_t **&);
181  void initialise(float **&);
182 };
183 
184 
185 #endif
186 
int getWidth() const
FFTMemoryCache(FFTCache::StorageType storageType, int width, int height)
uint16_t ** m_phase
uint16_t ** m_magnitude
void getValuesAt(int x, int y, float &real, float &imag) const
bool haveSetColumnAt(int x) const
static int getCacheSize(int width, int height, FFTCache::StorageType type)
float getPhaseAt(int x, int y) const
float getMaximumMagnitudeAt(int x) const
float ** m_fmagnitude
void setMagnitudeAt(int x, int y, float mag)
void setColumnAt(int x, float *mags, float *phases, float factor)
bool get(size_t column) const
void setNormalizedMagnitudeAt(int x, int y, float norm)
void setPhaseAt(int x, int y, float phase)
void getMagnitudesAt(int x, float *values, int minbin, int count, int step) const
float getMagnitudeAt(int x, int y) const
void allColumnsWritten()
FFTCache::StorageType getStorageType() const
int getHeight() const
QReadWriteLock m_colsetLock
ResizeableBitset m_colset
void setNormalizationFactor(int x, float factor)
float getNormalizedMagnitudeAt(int x, int y) const
FFTCache::StorageType m_storageType
In-memory FFT cache.
Profile point instance class.
Definition: Profiler.h:86