svcore  1.9
FFTMemoryCache.cpp
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 #include "FFTMemoryCache.h"
17 #include "system/System.h"
18 
19 #include <iostream>
20 #include <cstdlib>
21 
22 //#define DEBUG_FFT_MEMORY_CACHE 1
23 
25  int width, int height) :
26  m_width(width),
27  m_height(height),
28  m_magnitude(0),
29  m_phase(0),
30  m_fmagnitude(0),
31  m_fphase(0),
32  m_freal(0),
33  m_fimag(0),
34  m_factor(0),
35  m_storageType(storageType)
36 {
37 #ifdef DEBUG_FFT_MEMORY_CACHE
38  cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
39  << m_storageType << "), size " << m_width << "x" << m_height << endl;
40 #endif
41 
42  initialise();
43 }
44 
46 {
47 #ifdef DEBUG_FFT_MEMORY_CACHE
48  cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << endl;
49 #endif
50 
51  for (int i = 0; i < m_width; ++i) {
52  if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
53  if (m_phase && m_phase[i]) free(m_phase[i]);
54  if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
55  if (m_fphase && m_fphase[i]) free(m_fphase[i]);
56  if (m_freal && m_freal[i]) free(m_freal[i]);
57  if (m_fimag && m_fimag[i]) free(m_fimag[i]);
58  }
59 
60  if (m_magnitude) free(m_magnitude);
61  if (m_phase) free(m_phase);
62  if (m_fmagnitude) free(m_fmagnitude);
63  if (m_fphase) free(m_fphase);
64  if (m_freal) free(m_freal);
65  if (m_fimag) free(m_fimag);
66  if (m_factor) free(m_factor);
67 }
68 
69 void
71 {
72  Profiler profiler("FFTMemoryCache::initialise");
73 
74  int width = m_width, height = m_height;
75 
76 #ifdef DEBUG_FFT_MEMORY_CACHE
77  cerr << "FFTMemoryCache[" << this << "]::initialise(" << width << "x" << height << " = " << width*height << ")" << endl;
78 #endif
79 
83  } else if (m_storageType == FFTCache::Polar) {
86  } else {
89  }
90 
91  m_colset.resize(width);
92 
93  m_factor = (float *)realloc(m_factor, width * sizeof(float));
94 
95  m_width = width;
96  m_height = height;
97 
98 #ifdef DEBUG_FFT_MEMORY_CACHE
99  cerr << "done, width = " << m_width << " height = " << m_height << endl;
100 #endif
101 }
102 
103 void
104 FFTMemoryCache::initialise(uint16_t **&array)
105 {
106  array = (uint16_t **)malloc(m_width * sizeof(uint16_t *));
107  if (!array) throw std::bad_alloc();
108  MUNLOCK(array, m_width * sizeof(uint16_t *));
109 
110  for (int i = 0; i < m_width; ++i) {
111  array[i] = (uint16_t *)malloc(m_height * sizeof(uint16_t));
112  if (!array[i]) throw std::bad_alloc();
113  MUNLOCK(array[i], m_height * sizeof(uint16_t));
114  }
115 }
116 
117 void
119 {
120  array = (float **)malloc(m_width * sizeof(float *));
121  if (!array) throw std::bad_alloc();
122  MUNLOCK(array, m_width * sizeof(float *));
123 
124  for (int i = 0; i < m_width; ++i) {
125  array[i] = (float *)malloc(m_height * sizeof(float));
126  if (!array[i]) throw std::bad_alloc();
127  MUNLOCK(array[i], m_height * sizeof(float));
128  }
129 }
130 
131 void
132 FFTMemoryCache::setColumnAt(int x, float *mags, float *phases, float factor)
133 {
134  Profiler profiler("FFTMemoryCache::setColumnAt: from polar");
135 
136  setNormalizationFactor(x, factor);
137 
139  Profiler subprof("FFTMemoryCache::setColumnAt: polar to cart");
140  for (int y = 0; y < m_height; ++y) {
141  m_freal[x][y] = mags[y] * cosf(phases[y]);
142  m_fimag[x][y] = mags[y] * sinf(phases[y]);
143  }
144  } else {
145  for (int y = 0; y < m_height; ++y) {
146  setMagnitudeAt(x, y, mags[y]);
147  setPhaseAt(x, y, phases[y]);
148  }
149  }
150 
151  m_colsetLock.lockForWrite();
152  m_colset.set(x);
153  m_colsetLock.unlock();
154 }
155 
156 void
157 FFTMemoryCache::setColumnAt(int x, float *reals, float *imags)
158 {
159  Profiler profiler("FFTMemoryCache::setColumnAt: from cart");
160 
161  float max = 0.0;
162 
163  switch (m_storageType) {
164 
166  for (int y = 0; y < m_height; ++y) {
167  m_freal[x][y] = reals[y];
168  m_fimag[x][y] = imags[y];
169  float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
170  if (mag > max) max = mag;
171  }
172  break;
173 
174  case FFTCache::Compact:
175  case FFTCache::Polar:
176  {
177  Profiler subprof("FFTMemoryCache::setColumnAt: cart to polar");
178  for (int y = 0; y < m_height; ++y) {
179  float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
180  float phase = atan2f(imags[y], reals[y]);
181  reals[y] = mag;
182  imags[y] = phase;
183  if (mag > max) max = mag;
184  }
185  break;
186  }
187  };
188 
190  m_factor[x] = max;
191  m_colsetLock.lockForWrite();
192  m_colset.set(x);
193  m_colsetLock.unlock();
194  } else {
195  setColumnAt(x, reals, imags, max);
196  }
197 }
198 
199 int
201 {
202  int sz = 0;
203 
204  switch (type) {
205 
206  case FFTCache::Compact:
207  sz = (height * 2 + 1) * width * sizeof(uint16_t);
208  break;
209 
210  case FFTCache::Polar:
212  sz = (height * 2 + 1) * width * sizeof(float);
213  break;
214  }
215 
216  return sz;
217 }
218 
FFTMemoryCache(FFTCache::StorageType storageType, int width, int height)
uint16_t ** m_phase
uint16_t ** m_magnitude
#define MUNLOCK(a, b)
Definition: System.h:80
void resize(size_t size)
static int getCacheSize(int width, int height, FFTCache::StorageType type)
float ** m_fmagnitude
void setMagnitudeAt(int x, int y, float mag)
void setColumnAt(int x, float *mags, float *phases, float factor)
void setPhaseAt(int x, int y, float phase)
QReadWriteLock m_colsetLock
ResizeableBitset m_colset
void setNormalizationFactor(int x, float factor)
void set(size_t column)
FFTCache::StorageType m_storageType
Profile point instance class.
Definition: Profiler.h:86