annotate data/fft/FFTMemoryCache.cpp @ 575:8688430850d6

* either I'm going mad or the compiler is... valgrind and sizeof both seem to think that reading or writing m_size is reading beyond the end of the object, unless I add m_spare padding... why?
author Chris Cannam
date Mon, 16 Mar 2009 16:32:02 +0000
parents 1469caaa8e67
children e802e550a1f2
rev   line source
Chris@159 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@159 2
Chris@159 3 /*
Chris@159 4 Sonic Visualiser
Chris@159 5 An audio file viewer and annotation editor.
Chris@159 6 Centre for Digital Music, Queen Mary, University of London.
Chris@159 7 This file copyright 2006 Chris Cannam.
Chris@159 8
Chris@159 9 This program is free software; you can redistribute it and/or
Chris@159 10 modify it under the terms of the GNU General Public License as
Chris@159 11 published by the Free Software Foundation; either version 2 of the
Chris@159 12 License, or (at your option) any later version. See the file
Chris@159 13 COPYING included with this distribution for more information.
Chris@159 14 */
Chris@159 15
Chris@159 16 #include "FFTMemoryCache.h"
Chris@159 17 #include "system/System.h"
Chris@159 18
Chris@159 19 #include <iostream>
Chris@537 20 #include <cstdlib>
Chris@159 21
Chris@374 22 //#define DEBUG_FFT_MEMORY_CACHE 1
Chris@374 23
Chris@537 24 FFTMemoryCache::FFTMemoryCache(FFTCache::StorageType storageType,
Chris@537 25 size_t width, size_t height) :
Chris@537 26 m_width(width),
Chris@537 27 m_height(height),
Chris@159 28 m_magnitude(0),
Chris@159 29 m_phase(0),
Chris@264 30 m_fmagnitude(0),
Chris@264 31 m_fphase(0),
Chris@334 32 m_freal(0),
Chris@334 33 m_fimag(0),
Chris@264 34 m_factor(0),
Chris@264 35 m_storageType(storageType)
Chris@159 36 {
Chris@374 37 #ifdef DEBUG_FFT_MEMORY_CACHE
Chris@264 38 std::cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
Chris@537 39 << m_storageType << "), size " << m_width << "x" << m_height << std::endl;
Chris@374 40 #endif
Chris@537 41
Chris@537 42 initialise();
Chris@159 43 }
Chris@159 44
Chris@159 45 FFTMemoryCache::~FFTMemoryCache()
Chris@159 46 {
Chris@374 47 #ifdef DEBUG_FFT_MEMORY_CACHE
Chris@374 48 std::cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << std::endl;
Chris@374 49 #endif
Chris@159 50
Chris@159 51 for (size_t i = 0; i < m_width; ++i) {
Chris@159 52 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
Chris@159 53 if (m_phase && m_phase[i]) free(m_phase[i]);
Chris@264 54 if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
Chris@264 55 if (m_fphase && m_fphase[i]) free(m_fphase[i]);
Chris@334 56 if (m_freal && m_freal[i]) free(m_freal[i]);
Chris@334 57 if (m_fimag && m_fimag[i]) free(m_fimag[i]);
Chris@159 58 }
Chris@159 59
Chris@159 60 if (m_magnitude) free(m_magnitude);
Chris@159 61 if (m_phase) free(m_phase);
Chris@264 62 if (m_fmagnitude) free(m_fmagnitude);
Chris@264 63 if (m_fphase) free(m_fphase);
Chris@334 64 if (m_freal) free(m_freal);
Chris@334 65 if (m_fimag) free(m_fimag);
Chris@159 66 if (m_factor) free(m_factor);
Chris@159 67 }
Chris@159 68
Chris@159 69 void
Chris@537 70 FFTMemoryCache::initialise()
Chris@159 71 {
Chris@537 72 Profiler profiler("FFTMemoryCache::initialise");
Chris@537 73
Chris@537 74 size_t width = m_width, height = m_height;
Chris@408 75
Chris@374 76 #ifdef DEBUG_FFT_MEMORY_CACHE
Chris@537 77 std::cerr << "FFTMemoryCache[" << this << "]::initialise(" << width << "x" << height << " = " << width*height << ")" << std::endl;
Chris@374 78 #endif
Chris@159 79
Chris@537 80 if (m_storageType == FFTCache::Compact) {
Chris@537 81 initialise(m_magnitude);
Chris@537 82 initialise(m_phase);
Chris@537 83 } else if (m_storageType == FFTCache::Polar) {
Chris@537 84 initialise(m_fmagnitude);
Chris@537 85 initialise(m_fphase);
Chris@334 86 } else {
Chris@537 87 initialise(m_freal);
Chris@537 88 initialise(m_fimag);
Chris@264 89 }
Chris@264 90
Chris@159 91 m_colset.resize(width);
Chris@159 92
Chris@159 93 m_factor = (float *)realloc(m_factor, width * sizeof(float));
Chris@159 94
Chris@159 95 m_width = width;
Chris@159 96 m_height = height;
Chris@159 97
Chris@374 98 #ifdef DEBUG_FFT_MEMORY_CACHE
Chris@374 99 std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
Chris@374 100 #endif
Chris@159 101 }
Chris@159 102
Chris@159 103 void
Chris@537 104 FFTMemoryCache::initialise(uint16_t **&array)
Chris@159 105 {
Chris@537 106 array = (uint16_t **)malloc(m_width * sizeof(uint16_t *));
Chris@537 107 if (!array) throw std::bad_alloc();
Chris@537 108 MUNLOCK(array, m_width * sizeof(uint16_t *));
Chris@159 109
Chris@537 110 for (size_t i = 0; i < m_width; ++i) {
Chris@537 111 array[i] = (uint16_t *)malloc(m_height * sizeof(uint16_t));
Chris@159 112 if (!array[i]) throw std::bad_alloc();
Chris@537 113 MUNLOCK(array[i], m_height * sizeof(uint16_t));
Chris@159 114 }
Chris@159 115 }
Chris@159 116
Chris@159 117 void
Chris@537 118 FFTMemoryCache::initialise(float **&array)
Chris@264 119 {
Chris@537 120 array = (float **)malloc(m_width * sizeof(float *));
Chris@537 121 if (!array) throw std::bad_alloc();
Chris@537 122 MUNLOCK(array, m_width * sizeof(float *));
Chris@264 123
Chris@537 124 for (size_t i = 0; i < m_width; ++i) {
Chris@537 125 array[i] = (float *)malloc(m_height * sizeof(float));
Chris@264 126 if (!array[i]) throw std::bad_alloc();
Chris@537 127 MUNLOCK(array[i], m_height * sizeof(float));
Chris@264 128 }
Chris@264 129 }
Chris@264 130
Chris@264 131 void
Chris@334 132 FFTMemoryCache::setColumnAt(size_t x, float *mags, float *phases, float factor)
Chris@334 133 {
Chris@408 134 Profiler profiler("FFTMemoryCache::setColumnAt: from polar");
Chris@408 135
Chris@334 136 setNormalizationFactor(x, factor);
Chris@334 137
Chris@537 138 if (m_storageType == FFTCache::Rectangular) {
Chris@408 139 Profiler subprof("FFTMemoryCache::setColumnAt: polar to cart");
Chris@334 140 for (size_t y = 0; y < m_height; ++y) {
Chris@334 141 m_freal[x][y] = mags[y] * cosf(phases[y]);
Chris@334 142 m_fimag[x][y] = mags[y] * sinf(phases[y]);
Chris@334 143 }
Chris@334 144 } else {
Chris@334 145 for (size_t y = 0; y < m_height; ++y) {
Chris@334 146 setMagnitudeAt(x, y, mags[y]);
Chris@334 147 setPhaseAt(x, y, phases[y]);
Chris@334 148 }
Chris@334 149 }
Chris@334 150
Chris@548 151 m_colsetLock.lockForWrite();
Chris@334 152 m_colset.set(x);
Chris@548 153 m_colsetLock.unlock();
Chris@334 154 }
Chris@334 155
Chris@334 156 void
Chris@159 157 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
Chris@159 158 {
Chris@408 159 Profiler profiler("FFTMemoryCache::setColumnAt: from cart");
Chris@408 160
Chris@159 161 float max = 0.0;
Chris@159 162
Chris@264 163 switch (m_storageType) {
Chris@264 164
Chris@537 165 case FFTCache::Rectangular:
Chris@334 166 for (size_t y = 0; y < m_height; ++y) {
Chris@334 167 m_freal[x][y] = reals[y];
Chris@334 168 m_fimag[x][y] = imags[y];
Chris@334 169 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@334 170 if (mag > max) max = mag;
Chris@334 171 }
Chris@334 172 break;
Chris@334 173
Chris@537 174 case FFTCache::Compact:
Chris@537 175 case FFTCache::Polar:
Chris@408 176 {
Chris@408 177 Profiler subprof("FFTMemoryCache::setColumnAt: cart to polar");
Chris@264 178 for (size_t y = 0; y < m_height; ++y) {
Chris@264 179 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@264 180 float phase = atan2f(imags[y], reals[y]);
Chris@264 181 reals[y] = mag;
Chris@264 182 imags[y] = phase;
Chris@264 183 if (mag > max) max = mag;
Chris@264 184 }
Chris@264 185 break;
Chris@408 186 }
Chris@264 187 };
Chris@159 188
Chris@537 189 if (m_storageType == FFTCache::Rectangular) {
Chris@334 190 m_factor[x] = max;
Chris@548 191 m_colsetLock.lockForWrite();
Chris@334 192 m_colset.set(x);
Chris@548 193 m_colsetLock.unlock();
Chris@334 194 } else {
Chris@334 195 setColumnAt(x, reals, imags, max);
Chris@334 196 }
Chris@159 197 }
Chris@159 198
Chris@170 199 size_t
Chris@537 200 FFTMemoryCache::getCacheSize(size_t width, size_t height, FFTCache::StorageType type)
Chris@170 201 {
Chris@264 202 size_t sz = 0;
Chris@264 203
Chris@264 204 switch (type) {
Chris@264 205
Chris@537 206 case FFTCache::Compact:
Chris@264 207 sz = (height * 2 + 1) * width * sizeof(uint16_t);
Chris@264 208
Chris@537 209 case FFTCache::Polar:
Chris@537 210 case FFTCache::Rectangular:
Chris@264 211 sz = (height * 2 + 1) * width * sizeof(float);
Chris@264 212 }
Chris@264 213
Chris@264 214 return sz;
Chris@170 215 }
Chris@170 216