annotate data/fft/FFTMemoryCache.cpp @ 337:a6fab10ff9e6 spectrogram-cache-rejig

* Merge last fix from trunk
author Chris Cannam
date Thu, 15 Nov 2007 14:03:56 +0000
parents 02d2ad95ea52
children 7cc6b7b0d819
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@159 20
Chris@264 21 FFTMemoryCache::FFTMemoryCache(StorageType storageType) :
Chris@159 22 m_width(0),
Chris@159 23 m_height(0),
Chris@159 24 m_magnitude(0),
Chris@159 25 m_phase(0),
Chris@264 26 m_fmagnitude(0),
Chris@264 27 m_fphase(0),
Chris@334 28 m_freal(0),
Chris@334 29 m_fimag(0),
Chris@264 30 m_factor(0),
Chris@264 31 m_storageType(storageType)
Chris@159 32 {
Chris@264 33 std::cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
Chris@264 34 << m_storageType << ")" << std::endl;
Chris@159 35 }
Chris@159 36
Chris@159 37 FFTMemoryCache::~FFTMemoryCache()
Chris@159 38 {
Chris@264 39 // std::cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << std::endl;
Chris@159 40
Chris@159 41 for (size_t i = 0; i < m_width; ++i) {
Chris@159 42 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
Chris@159 43 if (m_phase && m_phase[i]) free(m_phase[i]);
Chris@264 44 if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
Chris@264 45 if (m_fphase && m_fphase[i]) free(m_fphase[i]);
Chris@334 46 if (m_freal && m_freal[i]) free(m_freal[i]);
Chris@334 47 if (m_fimag && m_fimag[i]) free(m_fimag[i]);
Chris@159 48 }
Chris@159 49
Chris@159 50 if (m_magnitude) free(m_magnitude);
Chris@159 51 if (m_phase) free(m_phase);
Chris@264 52 if (m_fmagnitude) free(m_fmagnitude);
Chris@264 53 if (m_fphase) free(m_fphase);
Chris@334 54 if (m_freal) free(m_freal);
Chris@334 55 if (m_fimag) free(m_fimag);
Chris@159 56 if (m_factor) free(m_factor);
Chris@159 57 }
Chris@159 58
Chris@159 59 void
Chris@159 60 FFTMemoryCache::resize(size_t width, size_t height)
Chris@159 61 {
Chris@335 62 std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
Chris@159 63
Chris@159 64 if (m_width == width && m_height == height) return;
Chris@159 65
Chris@264 66 if (m_storageType == Compact) {
Chris@264 67 resize(m_magnitude, width, height);
Chris@264 68 resize(m_phase, width, height);
Chris@334 69 } else if (m_storageType == Polar) {
Chris@264 70 resize(m_fmagnitude, width, height);
Chris@264 71 resize(m_fphase, width, height);
Chris@334 72 } else {
Chris@334 73 resize(m_freal, width, height);
Chris@334 74 resize(m_fimag, width, height);
Chris@264 75 }
Chris@264 76
Chris@159 77 m_colset.resize(width);
Chris@159 78
Chris@159 79 m_factor = (float *)realloc(m_factor, width * sizeof(float));
Chris@159 80
Chris@159 81 m_width = width;
Chris@159 82 m_height = height;
Chris@159 83
Chris@243 84 // std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
Chris@159 85 }
Chris@159 86
Chris@159 87 void
Chris@159 88 FFTMemoryCache::resize(uint16_t **&array, size_t width, size_t height)
Chris@159 89 {
Chris@159 90 for (size_t i = width; i < m_width; ++i) {
Chris@159 91 free(array[i]);
Chris@159 92 }
Chris@159 93
Chris@159 94 if (width != m_width) {
Chris@159 95 array = (uint16_t **)realloc(array, width * sizeof(uint16_t *));
Chris@159 96 if (!array) throw std::bad_alloc();
Chris@159 97 MUNLOCK(array, width * sizeof(uint16_t *));
Chris@159 98 }
Chris@159 99
Chris@159 100 for (size_t i = m_width; i < width; ++i) {
Chris@159 101 array[i] = 0;
Chris@159 102 }
Chris@159 103
Chris@159 104 for (size_t i = 0; i < width; ++i) {
Chris@159 105 array[i] = (uint16_t *)realloc(array[i], height * sizeof(uint16_t));
Chris@159 106 if (!array[i]) throw std::bad_alloc();
Chris@159 107 MUNLOCK(array[i], height * sizeof(uint16_t));
Chris@159 108 }
Chris@159 109 }
Chris@159 110
Chris@159 111 void
Chris@264 112 FFTMemoryCache::resize(float **&array, size_t width, size_t height)
Chris@264 113 {
Chris@264 114 for (size_t i = width; i < m_width; ++i) {
Chris@264 115 free(array[i]);
Chris@264 116 }
Chris@264 117
Chris@264 118 if (width != m_width) {
Chris@264 119 array = (float **)realloc(array, width * sizeof(float *));
Chris@264 120 if (!array) throw std::bad_alloc();
Chris@264 121 MUNLOCK(array, width * sizeof(float *));
Chris@264 122 }
Chris@264 123
Chris@264 124 for (size_t i = m_width; i < width; ++i) {
Chris@264 125 array[i] = 0;
Chris@264 126 }
Chris@264 127
Chris@264 128 for (size_t i = 0; i < width; ++i) {
Chris@264 129 array[i] = (float *)realloc(array[i], height * sizeof(float));
Chris@264 130 if (!array[i]) throw std::bad_alloc();
Chris@264 131 MUNLOCK(array[i], height * sizeof(float));
Chris@264 132 }
Chris@264 133 }
Chris@264 134
Chris@264 135 void
Chris@159 136 FFTMemoryCache::reset()
Chris@159 137 {
Chris@264 138 switch (m_storageType) {
Chris@264 139
Chris@264 140 case Compact:
Chris@264 141 for (size_t x = 0; x < m_width; ++x) {
Chris@264 142 for (size_t y = 0; y < m_height; ++y) {
Chris@264 143 m_magnitude[x][y] = 0;
Chris@264 144 m_phase[x][y] = 0;
Chris@264 145 }
Chris@264 146 m_factor[x] = 1.0;
Chris@264 147 }
Chris@264 148 break;
Chris@264 149
Chris@264 150 case Polar:
Chris@264 151 for (size_t x = 0; x < m_width; ++x) {
Chris@264 152 for (size_t y = 0; y < m_height; ++y) {
Chris@264 153 m_fmagnitude[x][y] = 0;
Chris@264 154 m_fphase[x][y] = 0;
Chris@264 155 }
Chris@264 156 m_factor[x] = 1.0;
Chris@264 157 }
Chris@264 158 break;
Chris@334 159
Chris@334 160 case Rectangular:
Chris@334 161 for (size_t x = 0; x < m_width; ++x) {
Chris@334 162 for (size_t y = 0; y < m_height; ++y) {
Chris@334 163 m_freal[x][y] = 0;
Chris@334 164 m_fimag[x][y] = 0;
Chris@334 165 }
Chris@334 166 m_factor[x] = 1.0;
Chris@334 167 }
Chris@334 168 break;
Chris@159 169 }
Chris@159 170 }
Chris@159 171
Chris@159 172 void
Chris@334 173 FFTMemoryCache::setColumnAt(size_t x, float *mags, float *phases, float factor)
Chris@334 174 {
Chris@334 175 setNormalizationFactor(x, factor);
Chris@334 176
Chris@334 177 if (m_storageType == Rectangular) {
Chris@334 178 for (size_t y = 0; y < m_height; ++y) {
Chris@334 179 m_freal[x][y] = mags[y] * cosf(phases[y]);
Chris@334 180 m_fimag[x][y] = mags[y] * sinf(phases[y]);
Chris@334 181 }
Chris@334 182 } else {
Chris@334 183 for (size_t y = 0; y < m_height; ++y) {
Chris@334 184 setMagnitudeAt(x, y, mags[y]);
Chris@334 185 setPhaseAt(x, y, phases[y]);
Chris@334 186 }
Chris@334 187 }
Chris@334 188
Chris@334 189 m_colset.set(x);
Chris@334 190 }
Chris@334 191
Chris@334 192 void
Chris@159 193 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
Chris@159 194 {
Chris@159 195 float max = 0.0;
Chris@159 196
Chris@264 197 switch (m_storageType) {
Chris@264 198
Chris@334 199 case Rectangular:
Chris@334 200 for (size_t y = 0; y < m_height; ++y) {
Chris@334 201 m_freal[x][y] = reals[y];
Chris@334 202 m_fimag[x][y] = imags[y];
Chris@334 203 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@334 204 if (mag > max) max = mag;
Chris@334 205 }
Chris@334 206 break;
Chris@334 207
Chris@264 208 case Compact:
Chris@264 209 case Polar:
Chris@264 210 for (size_t y = 0; y < m_height; ++y) {
Chris@264 211 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@264 212 float phase = atan2f(imags[y], reals[y]);
Chris@264 213 phase = princargf(phase);
Chris@264 214 reals[y] = mag;
Chris@264 215 imags[y] = phase;
Chris@264 216 if (mag > max) max = mag;
Chris@264 217 }
Chris@264 218 break;
Chris@264 219 };
Chris@159 220
Chris@334 221 if (m_storageType == Rectangular) {
Chris@334 222 m_factor[x] = max;
Chris@334 223 m_colset.set(x);
Chris@334 224 } else {
Chris@334 225 setColumnAt(x, reals, imags, max);
Chris@334 226 }
Chris@159 227 }
Chris@159 228
Chris@170 229 size_t
Chris@264 230 FFTMemoryCache::getCacheSize(size_t width, size_t height, StorageType type)
Chris@170 231 {
Chris@264 232 size_t sz = 0;
Chris@264 233
Chris@264 234 switch (type) {
Chris@264 235
Chris@264 236 case Compact:
Chris@264 237 sz = (height * 2 + 1) * width * sizeof(uint16_t);
Chris@264 238
Chris@264 239 case Polar:
Chris@334 240 case Rectangular:
Chris@264 241 sz = (height * 2 + 1) * width * sizeof(float);
Chris@264 242 }
Chris@264 243
Chris@264 244 return sz;
Chris@170 245 }
Chris@170 246