Mercurial > hg > svcore
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 |