FFTMemoryCache.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "FFTMemoryCache.h"
00017 #include "system/System.h"
00018 
00019 #include <iostream>
00020 
00021 //#define DEBUG_FFT_MEMORY_CACHE 1
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 

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1