00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "FFTMemoryCache.h"
00017 #include "system/System.h"
00018
00019 #include <iostream>
00020
00021
00022
00023 FFTMemoryCache::FFTMemoryCache(StorageType storageType) :
00024 m_width(0),
00025 m_height(0),
00026 m_magnitude(0),
00027 m_phase(0),
00028 m_fmagnitude(0),
00029 m_fphase(0),
00030 m_freal(0),
00031 m_fimag(0),
00032 m_factor(0),
00033 m_storageType(storageType)
00034 {
00035 #ifdef DEBUG_FFT_MEMORY_CACHE
00036 std::cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
00037 << m_storageType << ")" << std::endl;
00038 #endif
00039 }
00040
00041 FFTMemoryCache::~FFTMemoryCache()
00042 {
00043 #ifdef DEBUG_FFT_MEMORY_CACHE
00044 std::cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << std::endl;
00045 #endif
00046
00047 for (size_t i = 0; i < m_width; ++i) {
00048 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
00049 if (m_phase && m_phase[i]) free(m_phase[i]);
00050 if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
00051 if (m_fphase && m_fphase[i]) free(m_fphase[i]);
00052 if (m_freal && m_freal[i]) free(m_freal[i]);
00053 if (m_fimag && m_fimag[i]) free(m_fimag[i]);
00054 }
00055
00056 if (m_magnitude) free(m_magnitude);
00057 if (m_phase) free(m_phase);
00058 if (m_fmagnitude) free(m_fmagnitude);
00059 if (m_fphase) free(m_fphase);
00060 if (m_freal) free(m_freal);
00061 if (m_fimag) free(m_fimag);
00062 if (m_factor) free(m_factor);
00063 }
00064
00065 void
00066 FFTMemoryCache::resize(size_t width, size_t height)
00067 {
00068 #ifdef DEBUG_FFT_MEMORY_CACHE
00069 std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
00070 #endif
00071
00072 if (m_width == width && m_height == height) return;
00073
00074 if (m_storageType == Compact) {
00075 resize(m_magnitude, width, height);
00076 resize(m_phase, width, height);
00077 } else if (m_storageType == Polar) {
00078 resize(m_fmagnitude, width, height);
00079 resize(m_fphase, width, height);
00080 } else {
00081 resize(m_freal, width, height);
00082 resize(m_fimag, width, height);
00083 }
00084
00085 m_colset.resize(width);
00086
00087 m_factor = (float *)realloc(m_factor, width * sizeof(float));
00088
00089 m_width = width;
00090 m_height = height;
00091
00092 #ifdef DEBUG_FFT_MEMORY_CACHE
00093 std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
00094 #endif
00095 }
00096
00097 void
00098 FFTMemoryCache::resize(uint16_t **&array, size_t width, size_t height)
00099 {
00100 for (size_t i = width; i < m_width; ++i) {
00101 free(array[i]);
00102 }
00103
00104 if (width != m_width) {
00105 array = (uint16_t **)realloc(array, width * sizeof(uint16_t *));
00106 if (!array) throw std::bad_alloc();
00107 MUNLOCK(array, width * sizeof(uint16_t *));
00108 }
00109
00110 for (size_t i = m_width; i < width; ++i) {
00111 array[i] = 0;
00112 }
00113
00114 for (size_t i = 0; i < width; ++i) {
00115 array[i] = (uint16_t *)realloc(array[i], height * sizeof(uint16_t));
00116 if (!array[i]) throw std::bad_alloc();
00117 MUNLOCK(array[i], height * sizeof(uint16_t));
00118 }
00119 }
00120
00121 void
00122 FFTMemoryCache::resize(float **&array, size_t width, size_t height)
00123 {
00124 for (size_t i = width; i < m_width; ++i) {
00125 free(array[i]);
00126 }
00127
00128 if (width != m_width) {
00129 array = (float **)realloc(array, width * sizeof(float *));
00130 if (!array) throw std::bad_alloc();
00131 MUNLOCK(array, width * sizeof(float *));
00132 }
00133
00134 for (size_t i = m_width; i < width; ++i) {
00135 array[i] = 0;
00136 }
00137
00138 for (size_t i = 0; i < width; ++i) {
00139 array[i] = (float *)realloc(array[i], height * sizeof(float));
00140 if (!array[i]) throw std::bad_alloc();
00141 MUNLOCK(array[i], height * sizeof(float));
00142 }
00143 }
00144
00145 void
00146 FFTMemoryCache::reset()
00147 {
00148 switch (m_storageType) {
00149
00150 case Compact:
00151 for (size_t x = 0; x < m_width; ++x) {
00152 for (size_t y = 0; y < m_height; ++y) {
00153 m_magnitude[x][y] = 0;
00154 m_phase[x][y] = 0;
00155 }
00156 m_factor[x] = 1.0;
00157 }
00158 break;
00159
00160 case Polar:
00161 for (size_t x = 0; x < m_width; ++x) {
00162 for (size_t y = 0; y < m_height; ++y) {
00163 m_fmagnitude[x][y] = 0;
00164 m_fphase[x][y] = 0;
00165 }
00166 m_factor[x] = 1.0;
00167 }
00168 break;
00169
00170 case Rectangular:
00171 for (size_t x = 0; x < m_width; ++x) {
00172 for (size_t y = 0; y < m_height; ++y) {
00173 m_freal[x][y] = 0;
00174 m_fimag[x][y] = 0;
00175 }
00176 m_factor[x] = 1.0;
00177 }
00178 break;
00179 }
00180 }
00181
00182 void
00183 FFTMemoryCache::setColumnAt(size_t x, float *mags, float *phases, float factor)
00184 {
00185 setNormalizationFactor(x, factor);
00186
00187 if (m_storageType == Rectangular) {
00188 for (size_t y = 0; y < m_height; ++y) {
00189 m_freal[x][y] = mags[y] * cosf(phases[y]);
00190 m_fimag[x][y] = mags[y] * sinf(phases[y]);
00191 }
00192 } else {
00193 for (size_t y = 0; y < m_height; ++y) {
00194 setMagnitudeAt(x, y, mags[y]);
00195 setPhaseAt(x, y, phases[y]);
00196 }
00197 }
00198
00199 m_colset.set(x);
00200 }
00201
00202 void
00203 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
00204 {
00205 float max = 0.0;
00206
00207 switch (m_storageType) {
00208
00209 case Rectangular:
00210 for (size_t y = 0; y < m_height; ++y) {
00211 m_freal[x][y] = reals[y];
00212 m_fimag[x][y] = imags[y];
00213 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
00214 if (mag > max) max = mag;
00215 }
00216 break;
00217
00218 case Compact:
00219 case Polar:
00220 for (size_t y = 0; y < m_height; ++y) {
00221 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
00222 float phase = atan2f(imags[y], reals[y]);
00223 phase = princargf(phase);
00224 reals[y] = mag;
00225 imags[y] = phase;
00226 if (mag > max) max = mag;
00227 }
00228 break;
00229 };
00230
00231 if (m_storageType == Rectangular) {
00232 m_factor[x] = max;
00233 m_colset.set(x);
00234 } else {
00235 setColumnAt(x, reals, imags, max);
00236 }
00237 }
00238
00239 size_t
00240 FFTMemoryCache::getCacheSize(size_t width, size_t height, StorageType type)
00241 {
00242 size_t sz = 0;
00243
00244 switch (type) {
00245
00246 case Compact:
00247 sz = (height * 2 + 1) * width * sizeof(uint16_t);
00248
00249 case Polar:
00250 case Rectangular:
00251 sz = (height * 2 + 1) * width * sizeof(float);
00252 }
00253
00254 return sz;
00255 }
00256