comparison data/fft/FFTMemoryCache.cpp @ 264:260032c26c4f

* don't store fft values scaled by fftsize/2; that's a special requirement for the spectrogram, and other applications will not expect it -- make the spectrogram do that scaling itself * add a higher-resolution memory cache (still polar, though) as an alternative to the 16-bit compact cache * don't use the memory cache if we want rectangular coords (unless the disc cache is totally infeasible) as conversion slows it down anyway * avoid redundant rectangular -> polar -> rectangular conversion when storing values in a rectangular-mode disc cache
author Chris Cannam
date Fri, 01 Jun 2007 13:56:35 +0000
parents ff46f251139e
children aa8dbac62024
comparison
equal deleted inserted replaced
263:71dfc6ab3b54 264:260032c26c4f
16 #include "FFTMemoryCache.h" 16 #include "FFTMemoryCache.h"
17 #include "system/System.h" 17 #include "system/System.h"
18 18
19 #include <iostream> 19 #include <iostream>
20 20
21 FFTMemoryCache::FFTMemoryCache() : 21 FFTMemoryCache::FFTMemoryCache(StorageType storageType) :
22 m_width(0), 22 m_width(0),
23 m_height(0), 23 m_height(0),
24 m_magnitude(0), 24 m_magnitude(0),
25 m_phase(0), 25 m_phase(0),
26 m_factor(0) 26 m_fmagnitude(0),
27 m_fphase(0),
28 m_factor(0),
29 m_storageType(storageType)
27 { 30 {
31 std::cerr << "FFTMemoryCache[" << this << "]::FFTMemoryCache (type "
32 << m_storageType << ")" << std::endl;
28 } 33 }
29 34
30 FFTMemoryCache::~FFTMemoryCache() 35 FFTMemoryCache::~FFTMemoryCache()
31 { 36 {
32 // std::cerr << "FFTMemoryCache[" << this << "]::~Cache" << std::endl; 37 // std::cerr << "FFTMemoryCache[" << this << "]::~FFTMemoryCache" << std::endl;
33 38
34 for (size_t i = 0; i < m_width; ++i) { 39 for (size_t i = 0; i < m_width; ++i) {
35 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]); 40 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
36 if (m_phase && m_phase[i]) free(m_phase[i]); 41 if (m_phase && m_phase[i]) free(m_phase[i]);
42 if (m_fmagnitude && m_fmagnitude[i]) free(m_fmagnitude[i]);
43 if (m_fphase && m_fphase[i]) free(m_fphase[i]);
37 } 44 }
38 45
39 if (m_magnitude) free(m_magnitude); 46 if (m_magnitude) free(m_magnitude);
40 if (m_phase) free(m_phase); 47 if (m_phase) free(m_phase);
48 if (m_fmagnitude) free(m_fmagnitude);
49 if (m_fphase) free(m_fphase);
41 if (m_factor) free(m_factor); 50 if (m_factor) free(m_factor);
42 } 51 }
43 52
44 void 53 void
45 FFTMemoryCache::resize(size_t width, size_t height) 54 FFTMemoryCache::resize(size_t width, size_t height)
46 { 55 {
47 // std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl; 56 // std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
48 57
49 if (m_width == width && m_height == height) return; 58 if (m_width == width && m_height == height) return;
50 59
51 resize(m_magnitude, width, height); 60 if (m_storageType == Compact) {
52 resize(m_phase, width, height); 61 resize(m_magnitude, width, height);
62 resize(m_phase, width, height);
63 } else {
64 resize(m_fmagnitude, width, height);
65 resize(m_fphase, width, height);
66 }
67
53 m_colset.resize(width); 68 m_colset.resize(width);
54 69
55 m_factor = (float *)realloc(m_factor, width * sizeof(float)); 70 m_factor = (float *)realloc(m_factor, width * sizeof(float));
56 71
57 m_width = width; 72 m_width = width;
83 MUNLOCK(array[i], height * sizeof(uint16_t)); 98 MUNLOCK(array[i], height * sizeof(uint16_t));
84 } 99 }
85 } 100 }
86 101
87 void 102 void
103 FFTMemoryCache::resize(float **&array, size_t width, size_t height)
104 {
105 for (size_t i = width; i < m_width; ++i) {
106 free(array[i]);
107 }
108
109 if (width != m_width) {
110 array = (float **)realloc(array, width * sizeof(float *));
111 if (!array) throw std::bad_alloc();
112 MUNLOCK(array, width * sizeof(float *));
113 }
114
115 for (size_t i = m_width; i < width; ++i) {
116 array[i] = 0;
117 }
118
119 for (size_t i = 0; i < width; ++i) {
120 array[i] = (float *)realloc(array[i], height * sizeof(float));
121 if (!array[i]) throw std::bad_alloc();
122 MUNLOCK(array[i], height * sizeof(float));
123 }
124 }
125
126 void
88 FFTMemoryCache::reset() 127 FFTMemoryCache::reset()
89 { 128 {
90 for (size_t x = 0; x < m_width; ++x) { 129 switch (m_storageType) {
91 for (size_t y = 0; y < m_height; ++y) { 130
92 m_magnitude[x][y] = 0; 131 case Compact:
93 m_phase[x][y] = 0; 132 for (size_t x = 0; x < m_width; ++x) {
94 } 133 for (size_t y = 0; y < m_height; ++y) {
95 m_factor[x] = 1.0; 134 m_magnitude[x][y] = 0;
135 m_phase[x][y] = 0;
136 }
137 m_factor[x] = 1.0;
138 }
139 break;
140
141 case Polar:
142 for (size_t x = 0; x < m_width; ++x) {
143 for (size_t y = 0; y < m_height; ++y) {
144 m_fmagnitude[x][y] = 0;
145 m_fphase[x][y] = 0;
146 }
147 m_factor[x] = 1.0;
148 }
149 break;
96 } 150 }
97 } 151 }
98 152
99 void 153 void
100 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags) 154 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
101 { 155 {
102 float max = 0.0; 156 float max = 0.0;
103 157
104 for (size_t y = 0; y < m_height; ++y) { 158 switch (m_storageType) {
105 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]); 159
106 float phase = atan2f(imags[y], reals[y]); 160 case Compact:
107 phase = princargf(phase); 161 case Polar:
108 reals[y] = mag; 162 for (size_t y = 0; y < m_height; ++y) {
109 imags[y] = phase; 163 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
110 if (mag > max) max = mag; 164 float phase = atan2f(imags[y], reals[y]);
111 } 165 phase = princargf(phase);
166 reals[y] = mag;
167 imags[y] = phase;
168 if (mag > max) max = mag;
169 }
170 break;
171 };
112 172
113 setColumnAt(x, reals, imags, max); 173 setColumnAt(x, reals, imags, max);
114 } 174 }
115 175
116 size_t 176 size_t
117 FFTMemoryCache::getCacheSize(size_t width, size_t height) 177 FFTMemoryCache::getCacheSize(size_t width, size_t height, StorageType type)
118 { 178 {
119 return (height * 2 + 1) * width * sizeof(uint16_t); 179 size_t sz = 0;
180
181 switch (type) {
182
183 case Compact:
184 sz = (height * 2 + 1) * width * sizeof(uint16_t);
185
186 case Polar:
187 sz = (height * 2 + 1) * width * sizeof(float);
188 }
189
190 return sz;
120 } 191 }
121 192