Mercurial > hg > svcore
comparison data/fft/FFTDataServer.cpp @ 408:115f60df1e4d
* Speed up spectrogram painting by releasing mutex in FFTDataServer
while calculating data prior to writing it, and by adding whole-column
value query methods to FFT objects
* Add paint cache to Thumbwheel -- repaints of this widget were slowing
down the whole spectrogram repaint
* More uses of MutexLocker (named and with debug) and more profile
points
* Make startup much quicker some of the time, with OSC server in place
author | Chris Cannam |
---|---|
date | Thu, 08 May 2008 14:46:22 +0000 |
parents | 7aa1de571880 |
children | 52303ec15cd2 |
comparison
equal
deleted
inserted
replaced
407:88ad01799040 | 408:115f60df1e4d |
---|---|
60 fftSize, | 60 fftSize, |
61 polar); | 61 polar); |
62 | 62 |
63 FFTDataServer *server = 0; | 63 FFTDataServer *server = 0; |
64 | 64 |
65 MutexLocker locker(&m_serverMapMutex, "FFTDataServer::m_serverMapMutex[getInstance]"); | 65 MutexLocker locker(&m_serverMapMutex, "FFTDataServer::getInstance::m_serverMapMutex"); |
66 | 66 |
67 if ((server = findServer(n))) { | 67 if ((server = findServer(n))) { |
68 return server; | 68 return server; |
69 } | 69 } |
70 | 70 |
137 // multiple of the smaller (e.g. even though in principle you can | 137 // multiple of the smaller (e.g. even though in principle you can |
138 // draw the results at increment 256 from those at increment 768 | 138 // draw the results at increment 256 from those at increment 768 |
139 // or 1536, the model doesn't support this). | 139 // or 1536, the model doesn't support this). |
140 | 140 |
141 { | 141 { |
142 MutexLocker locker(&m_serverMapMutex, "FFTDataServer::m_serverMapMutex[getFuzzyInstance]"); | 142 MutexLocker locker(&m_serverMapMutex, "FFTDataServer::getFuzzyInstance::m_serverMapMutex"); |
143 | 143 |
144 ServerMap::iterator best = m_servers.end(); | 144 ServerMap::iterator best = m_servers.end(); |
145 int bestdist = -1; | 145 int bestdist = -1; |
146 | 146 |
147 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { | 147 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { |
256 | 256 |
257 void | 257 void |
258 FFTDataServer::claimInstance(FFTDataServer *server, bool needLock) | 258 FFTDataServer::claimInstance(FFTDataServer *server, bool needLock) |
259 { | 259 { |
260 MutexLocker locker(needLock ? &m_serverMapMutex : 0, | 260 MutexLocker locker(needLock ? &m_serverMapMutex : 0, |
261 "FFTDataServer::m_serverMapMutex[claimInstance]"); | 261 "FFTDataServer::claimInstance::m_serverMapMutex"); |
262 | 262 |
263 #ifdef DEBUG_FFT_SERVER | 263 #ifdef DEBUG_FFT_SERVER |
264 std::cerr << "FFTDataServer::claimInstance(" << server << ")" << std::endl; | 264 std::cerr << "FFTDataServer::claimInstance(" << server << ")" << std::endl; |
265 #endif | 265 #endif |
266 | 266 |
301 | 301 |
302 void | 302 void |
303 FFTDataServer::releaseInstance(FFTDataServer *server, bool needLock) | 303 FFTDataServer::releaseInstance(FFTDataServer *server, bool needLock) |
304 { | 304 { |
305 MutexLocker locker(needLock ? &m_serverMapMutex : 0, | 305 MutexLocker locker(needLock ? &m_serverMapMutex : 0, |
306 "FFTDataServer::m_serverMapMutex[releaseInstance]"); | 306 "FFTDataServer::releaseInstance::m_serverMapMutex"); |
307 | 307 |
308 #ifdef DEBUG_FFT_SERVER | 308 #ifdef DEBUG_FFT_SERVER |
309 std::cerr << "FFTDataServer::releaseInstance(" << server << ")" << std::endl; | 309 std::cerr << "FFTDataServer::releaseInstance(" << server << ")" << std::endl; |
310 #endif | 310 #endif |
311 | 311 |
429 | 429 |
430 void | 430 void |
431 FFTDataServer::modelAboutToBeDeleted(Model *model) | 431 FFTDataServer::modelAboutToBeDeleted(Model *model) |
432 { | 432 { |
433 MutexLocker locker(&m_serverMapMutex, | 433 MutexLocker locker(&m_serverMapMutex, |
434 "FFTDataServer::m_serverMapMutex[modelAboutToBeDeleted]"); | 434 "FFTDataServer::modelAboutToBeDeleted::m_serverMapMutex"); |
435 | 435 |
436 #ifdef DEBUG_FFT_SERVER | 436 #ifdef DEBUG_FFT_SERVER |
437 std::cerr << "FFTDataServer::modelAboutToBeDeleted(" << model << ")" | 437 std::cerr << "FFTDataServer::modelAboutToBeDeleted(" << model << ")" |
438 << std::endl; | 438 << std::endl; |
439 #endif | 439 #endif |
596 m_fillThread->wait(); | 596 m_fillThread->wait(); |
597 delete m_fillThread; | 597 delete m_fillThread; |
598 } | 598 } |
599 | 599 |
600 MutexLocker locker(&m_writeMutex, | 600 MutexLocker locker(&m_writeMutex, |
601 "FFTDataServer::m_writeMutex[~FFTDataServer]"); | 601 "FFTDataServer::~FFTDataServer::m_writeMutex"); |
602 | 602 |
603 for (CacheVector::iterator i = m_caches.begin(); i != m_caches.end(); ++i) { | 603 for (CacheVector::iterator i = m_caches.begin(); i != m_caches.end(); ++i) { |
604 | 604 |
605 if (*i) { | 605 if (*i) { |
606 delete *i; | 606 delete *i; |
632 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspend" << std::endl; | 632 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspend" << std::endl; |
633 #endif | 633 #endif |
634 Profiler profiler("FFTDataServer::suspend", false); | 634 Profiler profiler("FFTDataServer::suspend", false); |
635 | 635 |
636 MutexLocker locker(&m_writeMutex, | 636 MutexLocker locker(&m_writeMutex, |
637 "FFTDataServer::m_writeMutex[suspend]"); | 637 "FFTDataServer::suspend::m_writeMutex"); |
638 m_suspended = true; | 638 m_suspended = true; |
639 for (CacheVector::iterator i = m_caches.begin(); i != m_caches.end(); ++i) { | 639 for (CacheVector::iterator i = m_caches.begin(); i != m_caches.end(); ++i) { |
640 if (*i) (*i)->suspend(); | 640 if (*i) (*i)->suspend(); |
641 } | 641 } |
642 } | 642 } |
738 #ifdef DEBUG_FFT_SERVER | 738 #ifdef DEBUG_FFT_SERVER |
739 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "])::getCacheAux" << std::endl; | 739 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "])::getCacheAux" << std::endl; |
740 #endif | 740 #endif |
741 | 741 |
742 MutexLocker locker(&m_writeMutex, | 742 MutexLocker locker(&m_writeMutex, |
743 "FFTDataServer::m_writeMutex[getCacheAux]"); | 743 "FFTDataServer::getCacheAux::m_writeMutex"); |
744 | 744 |
745 if (m_lastUsedCache == -1) { | 745 if (m_lastUsedCache == -1) { |
746 m_fillThread->start(); | 746 m_fillThread->start(); |
747 } | 747 } |
748 | 748 |
873 size_t col; | 873 size_t col; |
874 FFTCache *cache = getCache(x, col); | 874 FFTCache *cache = getCache(x, col); |
875 if (!cache) return 0; | 875 if (!cache) return 0; |
876 | 876 |
877 if (!cache->haveSetColumnAt(col)) { | 877 if (!cache->haveSetColumnAt(col)) { |
878 Profiler profiler("FFTDataServer::getMagnitudeAt: filling"); | |
878 #ifdef DEBUG_FFT_SERVER | 879 #ifdef DEBUG_FFT_SERVER |
879 std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn(" | 880 std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn(" |
880 << x << ")" << std::endl; | 881 << x << ")" << std::endl; |
881 #endif | 882 #endif |
882 fillColumn(x); | 883 // hold mutex so that write thread doesn't mess with class |
884 // member data in fillColumn | |
885 MutexLocker locker(&m_writeMutex, | |
886 "FFTDataServer::getMagnitudeAt: m_writeMutex"); | |
887 fillColumn(x, true); | |
883 } | 888 } |
884 return cache->getMagnitudeAt(col, y); | 889 return cache->getMagnitudeAt(col, y); |
890 } | |
891 | |
892 bool | |
893 FFTDataServer::getMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) | |
894 { | |
895 Profiler profiler("FFTDataServer::getMagnitudesAt", false); | |
896 | |
897 if (x >= m_width) return false; | |
898 | |
899 if (minbin >= m_height) minbin = m_height - 1; | |
900 if (count == 0) count = (m_height - minbin) / step; | |
901 else if (minbin + count * step > m_height) { | |
902 count = (m_height - minbin) / step; | |
903 } | |
904 | |
905 size_t col; | |
906 FFTCache *cache = getCache(x, col); | |
907 if (!cache) return false; | |
908 | |
909 if (!cache->haveSetColumnAt(col)) { | |
910 Profiler profiler("FFTDataServer::getMagnitudesAt: filling"); | |
911 MutexLocker locker(&m_writeMutex, | |
912 "FFTDataServer::getMagnitudesAt: m_writeMutex"); | |
913 fillColumn(x, true); | |
914 } | |
915 | |
916 for (size_t i = 0; i < count; ++i) { | |
917 values[i] = cache->getMagnitudeAt(col, i * step + minbin); | |
918 } | |
919 | |
920 return true; | |
885 } | 921 } |
886 | 922 |
887 float | 923 float |
888 FFTDataServer::getNormalizedMagnitudeAt(size_t x, size_t y) | 924 FFTDataServer::getNormalizedMagnitudeAt(size_t x, size_t y) |
889 { | 925 { |
894 size_t col; | 930 size_t col; |
895 FFTCache *cache = getCache(x, col); | 931 FFTCache *cache = getCache(x, col); |
896 if (!cache) return 0; | 932 if (!cache) return 0; |
897 | 933 |
898 if (!cache->haveSetColumnAt(col)) { | 934 if (!cache->haveSetColumnAt(col)) { |
899 fillColumn(x); | 935 Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt: filling"); |
936 // hold mutex so that write thread doesn't mess with class | |
937 // member data in fillColumn | |
938 MutexLocker locker(&m_writeMutex, | |
939 "FFTDataServer::getNormalizedMagnitudeAt: m_writeMutex"); | |
940 fillColumn(x, true); | |
900 } | 941 } |
901 return cache->getNormalizedMagnitudeAt(col, y); | 942 return cache->getNormalizedMagnitudeAt(col, y); |
943 } | |
944 | |
945 bool | |
946 FFTDataServer::getNormalizedMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) | |
947 { | |
948 Profiler profiler("FFTDataServer::getNormalizedMagnitudesAt", false); | |
949 | |
950 if (x >= m_width) return false; | |
951 | |
952 if (minbin >= m_height) minbin = m_height - 1; | |
953 if (count == 0) count = (m_height - minbin) / step; | |
954 else if (minbin + count * step > m_height) { | |
955 count = (m_height - minbin) / step; | |
956 } | |
957 | |
958 size_t col; | |
959 FFTCache *cache = getCache(x, col); | |
960 if (!cache) return false; | |
961 | |
962 if (!cache->haveSetColumnAt(col)) { | |
963 Profiler profiler("FFTDataServer::getNormalizedMagnitudesAt: filling"); | |
964 MutexLocker locker(&m_writeMutex, | |
965 "FFTDataServer::getNormalizedMagnitudesAt: m_writeMutex"); | |
966 fillColumn(x, true); | |
967 } | |
968 | |
969 for (size_t i = 0; i < count; ++i) { | |
970 values[i] = cache->getNormalizedMagnitudeAt(col, i * step + minbin); | |
971 } | |
972 | |
973 return true; | |
902 } | 974 } |
903 | 975 |
904 float | 976 float |
905 FFTDataServer::getMaximumMagnitudeAt(size_t x) | 977 FFTDataServer::getMaximumMagnitudeAt(size_t x) |
906 { | 978 { |
911 size_t col; | 983 size_t col; |
912 FFTCache *cache = getCache(x, col); | 984 FFTCache *cache = getCache(x, col); |
913 if (!cache) return 0; | 985 if (!cache) return 0; |
914 | 986 |
915 if (!cache->haveSetColumnAt(col)) { | 987 if (!cache->haveSetColumnAt(col)) { |
916 fillColumn(x); | 988 Profiler profiler("FFTDataServer::getMaximumMagnitudeAt: filling"); |
989 // hold mutex so that write thread doesn't mess with class | |
990 // member data in fillColumn | |
991 MutexLocker locker(&m_writeMutex, | |
992 "FFTDataServer::getMaximumMagnitudeAt: m_writeMutex"); | |
993 fillColumn(x, true); | |
917 } | 994 } |
918 return cache->getMaximumMagnitudeAt(col); | 995 return cache->getMaximumMagnitudeAt(col); |
919 } | 996 } |
920 | 997 |
921 float | 998 float |
928 size_t col; | 1005 size_t col; |
929 FFTCache *cache = getCache(x, col); | 1006 FFTCache *cache = getCache(x, col); |
930 if (!cache) return 0; | 1007 if (!cache) return 0; |
931 | 1008 |
932 if (!cache->haveSetColumnAt(col)) { | 1009 if (!cache->haveSetColumnAt(col)) { |
933 fillColumn(x); | 1010 Profiler profiler("FFTDataServer::getPhaseAt: filling"); |
1011 // hold mutex so that write thread doesn't mess with class | |
1012 // member data in fillColumn | |
1013 MutexLocker locker(&m_writeMutex, | |
1014 "FFTDataServer::getPhaseAt: m_writeMutex"); | |
1015 fillColumn(x, true); | |
934 } | 1016 } |
935 return cache->getPhaseAt(col, y); | 1017 return cache->getPhaseAt(col, y); |
1018 } | |
1019 | |
1020 bool | |
1021 FFTDataServer::getPhasesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) | |
1022 { | |
1023 Profiler profiler("FFTDataServer::getPhasesAt", false); | |
1024 | |
1025 if (x >= m_width) return false; | |
1026 | |
1027 if (minbin >= m_height) minbin = m_height - 1; | |
1028 if (count == 0) count = (m_height - minbin) / step; | |
1029 else if (minbin + count * step > m_height) { | |
1030 count = (m_height - minbin) / step; | |
1031 } | |
1032 | |
1033 size_t col; | |
1034 FFTCache *cache = getCache(x, col); | |
1035 if (!cache) return false; | |
1036 | |
1037 if (!cache->haveSetColumnAt(col)) { | |
1038 Profiler profiler("FFTDataServer::getPhasesAt: filling"); | |
1039 MutexLocker locker(&m_writeMutex, | |
1040 "FFTDataServer::getPhasesAt: m_writeMutex"); | |
1041 fillColumn(x, true); | |
1042 } | |
1043 | |
1044 for (size_t i = 0; i < count; ++i) { | |
1045 values[i] = cache->getPhaseAt(col, i * step + minbin); | |
1046 } | |
1047 | |
1048 return true; | |
936 } | 1049 } |
937 | 1050 |
938 void | 1051 void |
939 FFTDataServer::getValuesAt(size_t x, size_t y, float &real, float &imaginary) | 1052 FFTDataServer::getValuesAt(size_t x, size_t y, float &real, float &imaginary) |
940 { | 1053 { |
954 imaginary = 0; | 1067 imaginary = 0; |
955 return; | 1068 return; |
956 } | 1069 } |
957 | 1070 |
958 if (!cache->haveSetColumnAt(col)) { | 1071 if (!cache->haveSetColumnAt(col)) { |
1072 Profiler profiler("FFTDataServer::getValuesAt: filling"); | |
959 #ifdef DEBUG_FFT_SERVER | 1073 #ifdef DEBUG_FFT_SERVER |
960 std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl; | 1074 std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl; |
961 #endif | 1075 #endif |
962 fillColumn(x); | 1076 // hold mutex so that write thread doesn't mess with class |
1077 // member data in fillColumn | |
1078 MutexLocker locker(&m_writeMutex, | |
1079 "FFTDataServer::getValuesAt: m_writeMutex"); | |
1080 fillColumn(x, true); | |
963 } | 1081 } |
964 | 1082 |
965 cache->getValuesAt(col, y, real, imaginary); | 1083 cache->getValuesAt(col, y, real, imaginary); |
966 } | 1084 } |
967 | 1085 |
989 | 1107 |
990 return cache->haveSetColumnAt(col); | 1108 return cache->haveSetColumnAt(col); |
991 } | 1109 } |
992 | 1110 |
993 void | 1111 void |
994 FFTDataServer::fillColumn(size_t x) | 1112 FFTDataServer::fillColumn(size_t x, bool lockHeld) |
995 { | 1113 { |
996 Profiler profiler("FFTDataServer::fillColumn", false); | 1114 Profiler profiler("FFTDataServer::fillColumn", false); |
997 | 1115 |
998 if (!m_model->isReady()) { | 1116 if (!m_model->isReady()) { |
999 std::cerr << "WARNING: FFTDataServer::fillColumn(" | 1117 std::cerr << "WARNING: FFTDataServer::fillColumn(" |
1020 std::cout << "FFTDataServer::fillColumn(" << x << ")" << std::endl; | 1138 std::cout << "FFTDataServer::fillColumn(" << x << ")" << std::endl; |
1021 #endif | 1139 #endif |
1022 FFTCache *cache = getCache(x, col); | 1140 FFTCache *cache = getCache(x, col); |
1023 if (!cache) return; | 1141 if (!cache) return; |
1024 | 1142 |
1025 MutexLocker locker(&m_writeMutex, | 1143 { |
1026 "FFTDataServer::m_writeMutex[fillColumn]"); | 1144 MutexLocker locker(lockHeld ? 0 : &m_writeMutex, |
1027 | 1145 "FFTDataServer::fillColumn::m_writeMutex [1]"); |
1028 if (cache->haveSetColumnAt(col)) return; | 1146 |
1147 if (cache->haveSetColumnAt(col)) return; | |
1148 } | |
1149 | |
1150 int winsize = m_windowSize; | |
1151 int fftsize = m_fftSize; | |
1152 int hs = fftsize/2; | |
1153 | |
1154 int pfx = 0; | |
1155 int off = (fftsize - winsize) / 2; | |
1029 | 1156 |
1030 int startFrame = m_windowIncrement * x; | 1157 int startFrame = m_windowIncrement * x; |
1031 int endFrame = startFrame + m_windowSize; | 1158 int endFrame = startFrame + m_windowSize; |
1032 | 1159 |
1033 startFrame -= int(m_windowSize) / 2; | 1160 startFrame -= winsize / 2; |
1034 endFrame -= int(m_windowSize) / 2; | 1161 endFrame -= winsize / 2; |
1035 size_t pfx = 0; | 1162 |
1036 | 1163 for (int i = 0; i < off; ++i) { |
1037 size_t off = (m_fftSize - m_windowSize) / 2; | |
1038 | |
1039 for (size_t i = 0; i < off; ++i) { | |
1040 m_fftInput[i] = 0.0; | 1164 m_fftInput[i] = 0.0; |
1041 m_fftInput[m_fftSize - i - 1] = 0.0; | 1165 } |
1166 | |
1167 for (int i = 0; i < off; ++i) { | |
1168 m_fftInput[fftsize - i - 1] = 0.0; | |
1042 } | 1169 } |
1043 | 1170 |
1044 if (startFrame < 0) { | 1171 if (startFrame < 0) { |
1045 pfx = size_t(-startFrame); | 1172 pfx = -startFrame; |
1046 for (size_t i = 0; i < pfx; ++i) { | 1173 for (int i = 0; i < pfx; ++i) { |
1047 m_fftInput[off + i] = 0.0; | 1174 m_fftInput[off + i] = 0.0; |
1048 } | 1175 } |
1049 } | 1176 } |
1050 | 1177 |
1051 #ifdef DEBUG_FFT_SERVER_FILL | 1178 #ifdef DEBUG_FFT_SERVER_FILL |
1055 << off + pfx << " in buffer of size " << m_fftSize | 1182 << off + pfx << " in buffer of size " << m_fftSize |
1056 << " with window size " << m_windowSize | 1183 << " with window size " << m_windowSize |
1057 << " from channel " << m_channel << std::endl; | 1184 << " from channel " << m_channel << std::endl; |
1058 #endif | 1185 #endif |
1059 | 1186 |
1060 size_t count = 0; | 1187 int count = 0; |
1061 if (endFrame > startFrame + pfx) count = endFrame - (startFrame + pfx); | 1188 if (endFrame > startFrame + pfx) count = endFrame - (startFrame + pfx); |
1062 | 1189 |
1063 size_t got = m_model->getData(m_channel, startFrame + pfx, | 1190 int got = m_model->getData(m_channel, startFrame + pfx, |
1064 count, m_fftInput + off + pfx); | 1191 count, m_fftInput + off + pfx); |
1065 | 1192 |
1066 while (got + pfx < m_windowSize) { | 1193 while (got + pfx < winsize) { |
1067 m_fftInput[off + got + pfx] = 0.0; | 1194 m_fftInput[off + got + pfx] = 0.0; |
1068 ++got; | 1195 ++got; |
1069 } | 1196 } |
1070 | 1197 |
1071 if (m_channel == -1) { | 1198 if (m_channel == -1) { |
1072 int channels = m_model->getChannelCount(); | 1199 int channels = m_model->getChannelCount(); |
1073 if (channels > 1) { | 1200 if (channels > 1) { |
1074 for (size_t i = 0; i < m_windowSize; ++i) { | 1201 for (int i = 0; i < winsize; ++i) { |
1075 m_fftInput[off + i] /= channels; | 1202 m_fftInput[off + i] /= channels; |
1076 } | 1203 } |
1077 } | 1204 } |
1078 } | 1205 } |
1079 | 1206 |
1080 m_windower.cut(m_fftInput + off); | 1207 m_windower.cut(m_fftInput + off); |
1081 | 1208 |
1082 for (size_t i = 0; i < m_fftSize/2; ++i) { | 1209 for (int i = 0; i < hs; ++i) { |
1083 fftsample temp = m_fftInput[i]; | 1210 fftsample temp = m_fftInput[i]; |
1084 m_fftInput[i] = m_fftInput[i + m_fftSize/2]; | 1211 m_fftInput[i] = m_fftInput[i + hs]; |
1085 m_fftInput[i + m_fftSize/2] = temp; | 1212 m_fftInput[i + hs] = temp; |
1086 } | 1213 } |
1087 | 1214 |
1088 fftf_execute(m_fftPlan); | 1215 fftf_execute(m_fftPlan); |
1089 | 1216 |
1090 fftsample factor = 0.0; | 1217 // If our cache uses polar storage, it's more friendly for us to |
1091 | 1218 // do the conversion before taking the write mutex |
1092 for (size_t i = 0; i <= m_fftSize/2; ++i) { | 1219 |
1093 | 1220 float factor = 0.f; |
1094 m_workbuffer[i] = m_fftOutput[i][0]; | 1221 |
1095 m_workbuffer[i + m_fftSize/2 + 1] = m_fftOutput[i][1]; | 1222 if (cache->getStorageType() == FFTCache::Compact || |
1096 } | 1223 cache->getStorageType() == FFTCache::Polar) { |
1097 | 1224 |
1098 cache->setColumnAt(col, | 1225 for (int i = 0; i <= hs; ++i) { |
1099 m_workbuffer, | 1226 fftsample real = m_fftOutput[i][0]; |
1100 m_workbuffer + m_fftSize/2+1); | 1227 fftsample imag = m_fftOutput[i][1]; |
1228 float mag = sqrtf(real * real + imag * imag); | |
1229 m_workbuffer[i] = mag; | |
1230 m_workbuffer[i + hs + 1] = atan2f(imag, real); | |
1231 if (mag > factor) factor = mag; | |
1232 } | |
1233 | |
1234 } else { | |
1235 | |
1236 for (int i = 0; i <= hs; ++i) { | |
1237 m_workbuffer[i] = m_fftOutput[i][0]; | |
1238 m_workbuffer[i + hs + 1] = m_fftOutput[i][1]; | |
1239 } | |
1240 } | |
1241 | |
1242 Profiler subprof("FFTDataServer::fillColumn: set to cache"); | |
1243 | |
1244 { | |
1245 MutexLocker locker(lockHeld ? 0 : &m_writeMutex, | |
1246 "FFTDataServer::fillColumn: m_writeMutex [2]"); | |
1247 | |
1248 if (cache->getStorageType() == FFTCache::Compact || | |
1249 cache->getStorageType() == FFTCache::Polar) { | |
1250 | |
1251 cache->setColumnAt(col, | |
1252 m_workbuffer, | |
1253 m_workbuffer + hs + 1, | |
1254 factor); | |
1255 | |
1256 } else { | |
1257 | |
1258 cache->setColumnAt(col, | |
1259 m_workbuffer, | |
1260 m_workbuffer + hs + 1); | |
1261 } | |
1262 } | |
1101 | 1263 |
1102 if (m_suspended) { | 1264 if (m_suspended) { |
1103 // std::cerr << "FFTDataServer::fillColumn(" << x << "): calling resume" << std::endl; | 1265 // std::cerr << "FFTDataServer::fillColumn(" << x << "): calling resume" << std::endl; |
1104 // resume(); | 1266 // resume(); |
1105 } | 1267 } |
1172 | 1334 |
1173 if (m_fillFrom > start) { | 1335 if (m_fillFrom > start) { |
1174 | 1336 |
1175 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) { | 1337 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) { |
1176 | 1338 |
1177 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); | 1339 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement), |
1340 false); | |
1178 | 1341 |
1179 if (m_server.m_exiting) return; | 1342 if (m_server.m_exiting) return; |
1180 | 1343 |
1181 while (m_server.m_suspended) { | 1344 while (m_server.m_suspended) { |
1182 #ifdef DEBUG_FFT_SERVER | 1345 #ifdef DEBUG_FFT_SERVER |
1183 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspended, waiting..." << std::endl; | 1346 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspended, waiting..." << std::endl; |
1184 #endif | 1347 #endif |
1185 { | 1348 { |
1186 MutexLocker locker(&m_server.m_writeMutex, | 1349 MutexLocker locker(&m_server.m_writeMutex, |
1187 "FFTDataServer::m_writeMutex[run/1]"); | 1350 "FFTDataServer::run::m_writeMutex [1]"); |
1188 m_server.m_condition.wait(&m_server.m_writeMutex, 10000); | 1351 m_server.m_condition.wait(&m_server.m_writeMutex, 10000); |
1189 } | 1352 } |
1190 #ifdef DEBUG_FFT_SERVER | 1353 #ifdef DEBUG_FFT_SERVER |
1191 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): waited" << std::endl; | 1354 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): waited" << std::endl; |
1192 #endif | 1355 #endif |
1212 | 1375 |
1213 size_t baseCompletion = m_completion; | 1376 size_t baseCompletion = m_completion; |
1214 | 1377 |
1215 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) { | 1378 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) { |
1216 | 1379 |
1217 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); | 1380 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement), |
1381 false); | |
1218 | 1382 |
1219 if (m_server.m_exiting) return; | 1383 if (m_server.m_exiting) return; |
1220 | 1384 |
1221 while (m_server.m_suspended) { | 1385 while (m_server.m_suspended) { |
1222 #ifdef DEBUG_FFT_SERVER | 1386 #ifdef DEBUG_FFT_SERVER |
1223 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspended, waiting..." << std::endl; | 1387 std::cerr << "FFTDataServer(" << this << " [" << (void *)QThread::currentThreadId() << "]): suspended, waiting..." << std::endl; |
1224 #endif | 1388 #endif |
1225 { | 1389 { |
1226 MutexLocker locker(&m_server.m_writeMutex, | 1390 MutexLocker locker(&m_server.m_writeMutex, |
1227 "FFTDataServer::m_writeMutex[run/2]"); | 1391 "FFTDataServer::run::m_writeMutex [2]"); |
1228 m_server.m_condition.wait(&m_server.m_writeMutex, 10000); | 1392 m_server.m_condition.wait(&m_server.m_writeMutex, 10000); |
1229 } | 1393 } |
1230 if (m_server.m_exiting) return; | 1394 if (m_server.m_exiting) return; |
1231 } | 1395 } |
1232 | 1396 |