| 214 | } |
| 215 | |
| 216 | bool SpectralDataManager::Worker::SnappingProcessor(SpectrumTransformer &transformer) { |
| 217 | auto &worker = static_cast<Worker &>(transformer); |
| 218 | // Compute power spectrum in the newest window |
| 219 | { |
| 220 | MyWindow &record = worker.NthWindow(0); |
| 221 | float *pSpectrum = &record.mSpectrums[0]; |
| 222 | const double dc = record.mRealFFTs[0]; |
| 223 | *pSpectrum++ = dc * dc; |
| 224 | float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1]; |
| 225 | for (size_t nn = worker.mSpectrumSize - 2; nn--;) { |
| 226 | const double re = *pReal++, im = *pImag++; |
| 227 | *pSpectrum++ = re * re + im * im; |
| 228 | } |
| 229 | const double nyquist = record.mImagFFTs[0]; |
| 230 | *pSpectrum = nyquist * nyquist; |
| 231 | |
| 232 | const double &sr = worker.mSnapSamplingRate; |
| 233 | const double nyquistRate = sr / 2; |
| 234 | const double &threshold = worker.mSnapThreshold; |
| 235 | const double &spectrumSize = worker.mSpectrumSize; |
| 236 | const int &targetBin = worker.mSnapTargetFreqBin; |
| 237 | |
| 238 | int binBound = spectrumSize * threshold; |
| 239 | float maxValue = std::numeric_limits<float>::min(); |
| 240 | |
| 241 | // Skip the first and last bin |
| 242 | for(int i = -binBound; i < binBound; i++){ |
| 243 | int idx = std::clamp(targetBin + i, 0, static_cast<int>(spectrumSize - 1)); |
| 244 | if(record.mSpectrums[idx] > maxValue){ |
| 245 | maxValue = record.mSpectrums[idx]; |
| 246 | // Update the return frequency |
| 247 | worker.mSnapReturnFreqBin = idx; |
| 248 | } |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | return true; |
| 253 | } |
| 254 | |
| 255 | bool SpectralDataManager::Worker::OvertonesProcessor(SpectrumTransformer &transformer) { |
| 256 | auto &worker = static_cast<Worker &>(transformer); |