1#define TAG "fft_mt_r2iq_def"
4 TracePrintln(TAG,
"%p", th);
5 DebugPrintln(TAG,
"Initialization...");
7 const int deci_ratio = decimation_ratio[decimation];
9 const int deci_fft_scrap_size = (BASE_FFT_SCRAP_SIZE / 2) / deci_ratio;
10 const int fft_output_size = this->fft_size_per_decimation[decimation];
11 const int fft_output_half_size = fft_output_size / 2;
12 const int fft_useful_size = fft_output_size - deci_fft_scrap_size;
14 DebugPrintln(TAG,
"Decimation : %d (index %d)", deci_ratio, decimation);
15 DebugPrintln(TAG,
"Scrap size : %d", deci_fft_scrap_size);
16 DebugPrintln(TAG,
"FFT output size : %d", fft_output_size);
17 DebugPrintln(TAG,
"FFT useful output size : %d", fft_useful_size);
18 DebugPrintln(TAG,
"Initialization done");
20 const fftwf_complex* filter = filterHw[decimation];
21 const auto filter2 = &filter[BASE_FFT_HALF_SIZE - fft_output_half_size];
23 plan_freq2time = &plan_freq2time_per_decimation[decimation];
24 int decimate_count = 0;
26 vector<float> iq_output(inputbuffer_block_size);
27 size_t output_buffer_offset = 0;
30 vector<int16_t> input_current_block;
33 vector<int16_t> last_block_end(BASE_FFT_SCRAP_SIZE);
38 std::unique_lock<std::mutex> lk(mutexR2iqControl);
39 input_current_block = inputbuffer->pop();
50 std::pair<int16_t, int16_t> blockMinMax = std::make_pair<int16_t, int16_t>(0, 0);
55 last_block_end.data(),
60 auto minmax = std::minmax_element(input_current_block, input_current_block + inputbuffer_block_size);
61 blockMinMax.first = *minmax.first;
62 blockMinMax.second = *minmax.second;
65 input_current_block.data(),
66 th->ADCinTime + BASE_FFT_SCRAP_SIZE,
67 inputbuffer_block_size
73 last_block_end.data(),
78 input_current_block.data(),
79 th->ADCinTime + BASE_FFT_SCRAP_SIZE,
80 inputbuffer_block_size
84 last_block_end = vector<int16_t>(
85 input_current_block.data() + inputbuffer_block_size - BASE_FFT_SCRAP_SIZE,
86 input_current_block.data() + inputbuffer_block_size
90 th->MinValue = std::min(blockMinMax.first, th->MinValue);
91 th->MaxValue = std::max(blockMinMax.second, th->MaxValue);
92 ++th->MinMaxBlockCount;
93 if (th->MinMaxBlockCount * processor_count / 3 >= DEFAULT_TRANSFERS_PER_SEC )
95 float minBits = (th->MinValue < 0) ? (log10f((
float)(-th->MinValue)) / log10f(2.0f)) : -1.0f;
96 float maxBits = (th->MaxValue > 0) ? (log10f((
float)(th->MaxValue)) / log10f(2.0f)) : -1.0f;
97 printf(
"r2iq: min = %d (%.1f bits) %.2f%%, max = %d (%.1f bits) %.2f%%\n",
98 (
int)th->MinValue, minBits, th->MinValue *-100.0f / 32768.0f,
99 (
int)th->MaxValue, maxBits, th->MaxValue * 100.0f / 32768.0f);
102 th->MinMaxBlockCount = 0;
108 const int _center_frequency_bin = this->center_frequency_bin;
112 const auto upper_frequencies_source = &th->ADCinFreq[_center_frequency_bin];
113 const auto upper_frequencies_len = std::min(
114 BASE_FFT_HALF_SIZE - _center_frequency_bin,
120 const auto lower_frequencies_source = &th->ADCinFreq[_center_frequency_bin - fft_output_half_size];
121 const auto lower_frequencies_start = std::max(
122 fft_output_half_size - _center_frequency_bin,
128 for (
int k = 0; k < ffts_per_blocks; k++)
139 fftwf_execute_dft_r2c(plan_time2freq_r2c, th->ADCinTime + k * (BASE_FFT_SIZE - BASE_FFT_SCRAP_SIZE), th->ADCinFreq);
146 upper_frequencies_source,
149 upper_frequencies_len
153 if(fft_output_half_size != upper_frequencies_len)
154 memset(th->inFreqTmp[upper_frequencies_len], 0, (fft_output_half_size - upper_frequencies_len) *
sizeof(fftwf_complex));
158 &th->inFreqTmp[fft_output_half_size],
159 lower_frequencies_source,
161 lower_frequencies_start,
165 if (lower_frequencies_start != 0)
166 memset(th->inFreqTmp[fft_output_half_size], 0, lower_frequencies_start *
sizeof(fftwf_complex));
173 fftwf_execute_dft(*plan_freq2time, th->inFreqTmp, th->inFreqTmp);
192 size_t len = (k+1) * fft_useful_size + output_buffer_offset > 32768 ? 32768 - (k * fft_useful_size + output_buffer_offset) : fft_useful_size;
194 if (this->getSideband())
197 copy<true>((fftwf_complex*)&iq_output.data()[(k * fft_useful_size + output_buffer_offset)*2], &th->inFreqTmp[0], len);
201 copy<false>((fftwf_complex*)&iq_output.data()[(k * fft_useful_size + output_buffer_offset)*2], &th->inFreqTmp[0], len);
205 decimate_count = (decimate_count + 1) & (deci_ratio - 1);
206 if (decimate_count == 0) {
207 outputbuffer->push(iq_output);
208 output_buffer_offset = 0;
212 output_buffer_offset += fft_output_half_size + fft_useful_size * (ffts_per_blocks-1);