30#define TAG "fft_mt_r2iq_def"
33 TracePrintln(TAG,
"%p", th);
34 DebugPrintln(TAG,
"Initialization...");
36 const int deci_ratio = decimation_ratio[decimation];
38 const int deci_fft_scrap_size = (BASE_FFT_SCRAP_SIZE / 2) / deci_ratio;
39 const int fft_output_size = this->fft_size_per_decimation[decimation];
40 const int fft_output_half_size = fft_output_size / 2;
41 const int fft_useful_size = fft_output_size - deci_fft_scrap_size;
43 DebugPrintln(TAG,
"Decimation : %d (index %d)", deci_ratio, decimation);
44 DebugPrintln(TAG,
"Scrap size : %d", deci_fft_scrap_size);
45 DebugPrintln(TAG,
"FFT output size : %d", fft_output_size);
46 DebugPrintln(TAG,
"FFT useful output size : %d", fft_useful_size);
47 DebugPrintln(TAG,
"Initialization done");
49 const fftwf_complex* filter = filterHw[decimation];
50 const auto filter2 = &filter[BASE_FFT_HALF_SIZE - fft_output_half_size];
52 plan_freq2time = &plan_freq2time_per_decimation[decimation];
53 int decimate_count = 0;
55 std::vector<float> iq_output(inputbuffer_block_size);
56 size_t output_buffer_offset = 0;
59 std::vector<int16_t> input_current_block;
62 std::vector<int16_t> last_block_end(BASE_FFT_SCRAP_SIZE);
67 std::unique_lock<std::mutex> lk(mutexR2iqControl);
68 input_current_block = inputbuffer->pop();
79 std::pair<int16_t, int16_t> blockMinMax = std::make_pair<int16_t, int16_t>(0, 0);
84 last_block_end.data(),
89 auto minmax = std::minmax_element(input_current_block, input_current_block + inputbuffer_block_size);
90 blockMinMax.first = *minmax.first;
91 blockMinMax.second = *minmax.second;
94 input_current_block.data(),
95 th->ADCinTime + BASE_FFT_SCRAP_SIZE,
96 inputbuffer_block_size
102 last_block_end.data(),
107 input_current_block.data(),
108 th->ADCinTime + BASE_FFT_SCRAP_SIZE,
109 inputbuffer_block_size
113 last_block_end = std::vector<int16_t>(
114 input_current_block.data() + inputbuffer_block_size - BASE_FFT_SCRAP_SIZE,
115 input_current_block.data() + inputbuffer_block_size
119 th->MinValue = std::min(blockMinMax.first, th->MinValue);
120 th->MaxValue = std::max(blockMinMax.second, th->MaxValue);
121 ++th->MinMaxBlockCount;
122 if (th->MinMaxBlockCount * processor_count / 3 >= DEFAULT_TRANSFERS_PER_SEC )
124 float minBits = (th->MinValue < 0) ? (log10f((
float)(-th->MinValue)) / log10f(2.0f)) : -1.0f;
125 float maxBits = (th->MaxValue > 0) ? (log10f((
float)(th->MaxValue)) / log10f(2.0f)) : -1.0f;
126 printf(
"r2iq: min = %d (%.1f bits) %.2f%%, max = %d (%.1f bits) %.2f%%\n",
127 (
int)th->MinValue, minBits, th->MinValue *-100.0f / 32768.0f,
128 (
int)th->MaxValue, maxBits, th->MaxValue * 100.0f / 32768.0f);
131 th->MinMaxBlockCount = 0;
137 const int _center_frequency_bin = this->center_frequency_bin;
141 const auto upper_frequencies_source = &th->ADCinFreq[_center_frequency_bin];
142 const auto upper_frequencies_len = std::min(
143 BASE_FFT_HALF_SIZE - _center_frequency_bin,
149 const auto lower_frequencies_source = &th->ADCinFreq[_center_frequency_bin - fft_output_half_size];
150 const auto lower_frequencies_start = std::max(
151 fft_output_half_size - _center_frequency_bin,
157 for (
int k = 0; k < ffts_per_blocks; k++)
159 size_t start_address = k * BASE_FFT_USEFUL_SIZE;
160 size_t scrap_size = BASE_FFT_SCRAP_SIZE;
161 if(start_address + BASE_FFT_SIZE > inputbuffer_block_size + BASE_FFT_SCRAP_SIZE)
163 size_t new_address = (inputbuffer_block_size + BASE_FFT_SCRAP_SIZE) - BASE_FFT_SIZE;
164 scrap_size += start_address - new_address;
165 start_address = new_address;
167 scrap_size /= (deci_ratio*2);
179 fftwf_execute_dft_r2c(plan_time2freq_r2c, th->ADCinTime + start_address, th->ADCinFreq);
186 upper_frequencies_source,
189 upper_frequencies_len
193 if(fft_output_half_size != upper_frequencies_len)
194 memset(th->inFreqTmp[upper_frequencies_len], 0, (fft_output_half_size - upper_frequencies_len) *
sizeof(fftwf_complex));
198 &th->inFreqTmp[fft_output_half_size],
199 lower_frequencies_source,
201 lower_frequencies_start,
205 if (lower_frequencies_start != 0)
206 memset(th->inFreqTmp[fft_output_half_size], 0, lower_frequencies_start *
sizeof(fftwf_complex));
213 fftwf_execute_dft(*plan_freq2time, th->inFreqTmp, th->inFreqTmp);
237 size_t begin = scrap_size-deci_fft_scrap_size;
238 size_t len = (fft_output_size - scrap_size);
241 if (this->getSideband())
244 copy<true>((fftwf_complex*)&iq_output.data()[output_buffer_offset*2], &th->inFreqTmp[begin], len);
248 copy<false>((fftwf_complex*)&iq_output.data()[output_buffer_offset*2], &th->inFreqTmp[begin], len);
251 output_buffer_offset += len;
254 decimate_count = (decimate_count + 1) & (deci_ratio - 1);
255 if (decimate_count == 0) {
256 outputbuffer->push(iq_output);
257 output_buffer_offset = 0;