annotate data/fft/FFTMemoryCache.cpp @ 299:576be0d0d218

* Merge transform directory from sv-match-alignment branch (the previous comment included notes for this stuff, but I missed it in the actual merge) * Fix crash when a transform fails to create an output model and the thread that created the transform then deletes its input model thinking it's no longer needed, even though the transform run thread is still using it -- fix is to wait() on the transform before returning the null output model
author Chris Cannam
date Fri, 28 Sep 2007 16:15:06 +0000
parents 260032c26c4f
children aa8dbac62024
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@264 28 m_factor(0),
Chris@264 29 m_storageType(storageType)
Chris@159 30 {
Chris@264 31 std::cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
Chris@264 32 << m_storageType << ")" << std::endl;
Chris@159 33 }
Chris@159 34
Chris@159 35 FFTMemoryCache::~FFTMemoryCache()
Chris@159 36 {
Chris@264 37 // std::cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << std::endl;
Chris@159 38
Chris@159 39 for (size_t i = 0; i < m_width; ++i) {
Chris@159 40 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
Chris@159 41 if (m_phase && m_phase[i]) free(m_phase[i]);
Chris@264 42 if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
Chris@264 43 if (m_fphase && m_fphase[i]) free(m_fphase[i]);
Chris@159 44 }
Chris@159 45
Chris@159 46 if (m_magnitude) free(m_magnitude);
Chris@159 47 if (m_phase) free(m_phase);
Chris@264 48 if (m_fmagnitude) free(m_fmagnitude);
Chris@264 49 if (m_fphase) free(m_fphase);
Chris@159 50 if (m_factor) free(m_factor);
Chris@159 51 }
Chris@159 52
Chris@159 53 void
Chris@159 54 FFTMemoryCache::resize(size_t width, size_t height)
Chris@159 55 {
Chris@243 56 // std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
Chris@159 57
Chris@159 58 if (m_width == width && m_height == height) return;
Chris@159 59
Chris@264 60 if (m_storageType == Compact) {
Chris@264 61 resize(m_magnitude, width, height);
Chris@264 62 resize(m_phase, width, height);
Chris@264 63 } else {
Chris@264 64 resize(m_fmagnitude, width, height);
Chris@264 65 resize(m_fphase, width, height);
Chris@264 66 }
Chris@264 67
Chris@159 68 m_colset.resize(width);
Chris@159 69
Chris@159 70 m_factor = (float *)realloc(m_factor, width * sizeof(float));
Chris@159 71
Chris@159 72 m_width = width;
Chris@159 73 m_height = height;
Chris@159 74
Chris@243 75 // std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
Chris@159 76 }
Chris@159 77
Chris@159 78 void
Chris@159 79 FFTMemoryCache::resize(uint16_t **&array, size_t width, size_t height)
Chris@159 80 {
Chris@159 81 for (size_t i = width; i < m_width; ++i) {
Chris@159 82 free(array[i]);
Chris@159 83 }
Chris@159 84
Chris@159 85 if (width != m_width) {
Chris@159 86 array = (uint16_t **)realloc(array, width * sizeof(uint16_t *));
Chris@159 87 if (!array) throw std::bad_alloc();
Chris@159 88 MUNLOCK(array, width * sizeof(uint16_t *));
Chris@159 89 }
Chris@159 90
Chris@159 91 for (size_t i = m_width; i < width; ++i) {
Chris@159 92 array[i] = 0;
Chris@159 93 }
Chris@159 94
Chris@159 95 for (size_t i = 0; i < width; ++i) {
Chris@159 96 array[i] = (uint16_t *)realloc(array[i], height * sizeof(uint16_t));
Chris@159 97 if (!array[i]) throw std::bad_alloc();
Chris@159 98 MUNLOCK(array[i], height * sizeof(uint16_t));
Chris@159 99 }
Chris@159 100 }
Chris@159 101
Chris@159 102 void
Chris@264 103 FFTMemoryCache::resize(float **&array, size_t width, size_t height)
Chris@264 104 {
Chris@264 105 for (size_t i = width; i < m_width; ++i) {
Chris@264 106 free(array[i]);
Chris@264 107 }
Chris@264 108
Chris@264 109 if (width != m_width) {
Chris@264 110 array = (float **)realloc(array, width * sizeof(float *));
Chris@264 111 if (!array) throw std::bad_alloc();
Chris@264 112 MUNLOCK(array, width * sizeof(float *));
Chris@264 113 }
Chris@264 114
Chris@264 115 for (size_t i = m_width; i < width; ++i) {
Chris@264 116 array[i] = 0;
Chris@264 117 }
Chris@264 118
Chris@264 119 for (size_t i = 0; i < width; ++i) {
Chris@264 120 array[i] = (float *)realloc(array[i], height * sizeof(float));
Chris@264 121 if (!array[i]) throw std::bad_alloc();
Chris@264 122 MUNLOCK(array[i], height * sizeof(float));
Chris@264 123 }
Chris@264 124 }
Chris@264 125
Chris@264 126 void
Chris@159 127 FFTMemoryCache::reset()
Chris@159 128 {
Chris@264 129 switch (m_storageType) {
Chris@264 130
Chris@264 131 case Compact:
Chris@264 132 for (size_t x = 0; x < m_width; ++x) {
Chris@264 133 for (size_t y = 0; y < m_height; ++y) {
Chris@264 134 m_magnitude[x][y] = 0;
Chris@264 135 m_phase[x][y] = 0;
Chris@264 136 }
Chris@264 137 m_factor[x] = 1.0;
Chris@264 138 }
Chris@264 139 break;
Chris@264 140
Chris@264 141 case Polar:
Chris@264 142 for (size_t x = 0; x < m_width; ++x) {
Chris@264 143 for (size_t y = 0; y < m_height; ++y) {
Chris@264 144 m_fmagnitude[x][y] = 0;
Chris@264 145 m_fphase[x][y] = 0;
Chris@264 146 }
Chris@264 147 m_factor[x] = 1.0;
Chris@264 148 }
Chris@264 149 break;
Chris@159 150 }
Chris@159 151 }
Chris@159 152
Chris@159 153 void
Chris@159 154 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
Chris@159 155 {
Chris@159 156 float max = 0.0;
Chris@159 157
Chris@264 158 switch (m_storageType) {
Chris@264 159
Chris@264 160 case Compact:
Chris@264 161 case Polar:
Chris@264 162 for (size_t y = 0; y < m_height; ++y) {
Chris@264 163 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@264 164 float phase = atan2f(imags[y], reals[y]);
Chris@264 165 phase = princargf(phase);
Chris@264 166 reals[y] = mag;
Chris@264 167 imags[y] = phase;
Chris@264 168 if (mag > max) max = mag;
Chris@264 169 }
Chris@264 170 break;
Chris@264 171 };
Chris@159 172
Chris@159 173 setColumnAt(x, reals, imags, max);
Chris@159 174 }
Chris@159 175
Chris@170 176 size_t
Chris@264 177 FFTMemoryCache::getCacheSize(size_t width, size_t height, StorageType type)
Chris@170 178 {
Chris@264 179 size_t sz = 0;
Chris@264 180
Chris@264 181 switch (type) {
Chris@264 182
Chris@264 183 case Compact:
Chris@264 184 sz = (height * 2 + 1) * width * sizeof(uint16_t);
Chris@264 185
Chris@264 186 case Polar:
Chris@264 187 sz = (height * 2 + 1) * width * sizeof(float);
Chris@264 188 }
Chris@264 189
Chris@264 190 return sz;
Chris@170 191 }
Chris@170 192