| 26 | } |
| 27 | |
| 28 | void FFTDataDistributor::process() { |
| 29 | |
| 30 | while (!input->empty()) { |
| 31 | if (!isAnyOutputEmpty()) { |
| 32 | return; |
| 33 | } |
| 34 | DemodulatorThreadIQDataPtr inp; |
| 35 | |
| 36 | if (!input->pop(inp, HEARTBEAT_CHECK_PERIOD_MICROS)) { |
| 37 | continue; |
| 38 | } |
| 39 | |
| 40 | if (inp) { |
| 41 | //Settings have changed, set new values and dump all previous samples stored in inputBuffer: |
| 42 | if (inputBuffer.sampleRate != inp->sampleRate || inputBuffer.frequency != inp->frequency) { |
| 43 | |
| 44 | //bufferMax must be at least fftSize (+ margin), else the waterfall get frozen, because no longer updated. |
| 45 | bufferMax = std::max((size_t)(inp->sampleRate * FFT_DISTRIBUTOR_BUFFER_IN_SECONDS), (size_t)(1.2 * fftSize.load())); |
| 46 | |
| 47 | // std::cout << "Buffer Max: " << bufferMax << std::endl; |
| 48 | bufferOffset = 0; |
| 49 | bufferedItems = 0; |
| 50 | inputBuffer.sampleRate = inp->sampleRate; |
| 51 | inputBuffer.frequency = inp->frequency; |
| 52 | inputBuffer.data.resize(bufferMax); |
| 53 | } |
| 54 | |
| 55 | //adjust (bufferMax ; inputBuffer.data) in case of FFT size change only. |
| 56 | if (bufferMax < (size_t)(1.2 * fftSize.load())) { |
| 57 | bufferMax = (size_t)(1.2 * fftSize.load()); |
| 58 | inputBuffer.data.resize(bufferMax); |
| 59 | } |
| 60 | |
| 61 | size_t nbSamplesToAdd = inp->data.size(); |
| 62 | |
| 63 | //No room left in inputBuffer.data to accept inp->data.size() more samples. |
| 64 | //so make room by sliding left of bufferOffset, which is fine because |
| 65 | //those samples has already been processed. |
| 66 | if ((bufferOffset + bufferedItems + inp->data.size()) > bufferMax) { |
| 67 | memmove(&inputBuffer.data[0], &inputBuffer.data[bufferOffset], bufferedItems*sizeof(liquid_float_complex)); |
| 68 | bufferOffset = 0; |
| 69 | //if there are too much samples, we may even overflow ! |
| 70 | //as a fallback strategy, drop the last incoming new samples not fitting in inputBuffer.data. |
| 71 | if (bufferedItems + inp->data.size() > bufferMax) { |
| 72 | //clamp nbSamplesToAdd |
| 73 | nbSamplesToAdd = bufferMax - bufferedItems; |
| 74 | std::cout << "FFTDataDistributor::process() incoming samples overflow, dropping the last " << (inp->data.size() - nbSamplesToAdd) << " input samples..." << std::endl; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | //store nbSamplesToAdd incoming samples. |
| 79 | memcpy(&inputBuffer.data[bufferOffset+bufferedItems],&inp->data[0], nbSamplesToAdd *sizeof(liquid_float_complex)); |
| 80 | bufferedItems += nbSamplesToAdd; |
| 81 | // |
| 82 | |
| 83 | } else { |
| 84 | //empty inp, wait for another. |
| 85 | continue; |