23 class RecBackend :
public RemoteHandlerBackend
26 std::vector<ndsp::DeviceInfo> available_devices;
29 bool is_started =
false;
32 std::shared_ptr<ndsp::DeviceBlock> dev_blk;
34 std::shared_ptr<ndsp::SplitterBlock<complex_t>> splitter;
36 std::shared_ptr<ndsp::FFTPanBlock> fftp;
42 bool recording =
false;
44 std::shared_ptr<ndsp::IQSinkBlock> iq_sink;
47 std::thread metaThread;
48 bool metaThread_r =
true;
55 float buffer_usage = getRatio();
56 push_stream_data(
"buffer_usage", (uint8_t *)&buffer_usage,
sizeof(
float));
58 if (is_started && recording)
59 push_stream_data(
"rec_size", (uint8_t *)&iq_sink->total_written_raw,
sizeof(
size_t));
61 std::this_thread::sleep_for(std::chrono::milliseconds(100));
68 available_devices = ndsp::getDeviceList(ndsp::DeviceBlock::MODE_SINGLE_RX);
70 splitter = std::make_shared<ndsp::SplitterBlock<complex_t>>();
72 fftp = std::make_shared<ndsp::FFTPanBlock>();
73 fftp->set_input(splitter->add_output(
"main_fft"), 0);
74 fftp->on_fft = [
this](
float *p,
size_t s) { push_stream_data(
"fft", (uint8_t *)p, s *
sizeof(
float)); };
76 iq_sink = std::make_shared<ndsp::IQSinkBlock>();
78 metaThread = std::thread(&RecBackend::metaThread_f,
this);
83 if (metaThread.joinable())
89 if (!dev_blk || is_started)
92 fftp->set_fft_settings(fft_size, dev_blk->getStreamSamplerate(0,
false), fft_rate);
94 splitter->link(dev_blk.get(), 0, 0, 100);
105 if (!dev_blk || !is_started)
117 if (!is_started || recording)
120 std::string recording_path = satdump_cfg.main_cfg[
"satdump_directories"][
"recording_path"][
"value"].get<std::string>();
121 iq_sink->set_cfg(
"file", recording_path);
122 iq_sink->set_cfg(
"autogen",
true);
123 iq_sink->set_cfg(
"samplerate", dev_blk->getStreamSamplerate(0,
false));
124 iq_sink->set_cfg(
"frequency", dev_blk->getStreamFrequency(0,
false));
125 iq_sink->set_cfg(
"timestamp", getTime());
126 iq_sink->set_cfg(
"type", rec_type);
127 iq_sink->set_input(splitter->add_output(
"tmp_record",
false), 0);
138 splitter->del_output(
"tmp_record",
true);
147 return (
float)dev_blk->get_outputs()[0].fifo->size_approx() / (float)dev_blk->get_outputs()[0].fifo->max_capacity();
152 nlohmann::ordered_json _get_cfg_list()
154 nlohmann::ordered_json p;
156 p[
"available_devices"][
"type"] =
"json";
157 p[
"current_device"][
"type"] =
"json";
161 p[
"dev/list"][
"type"] =
"json";
162 p[
"dev/cfg"][
"type"] =
"json";
165 p[
"started"][
"type"] =
"bool";
167 p[
"fft/avg_num"][
"type"] =
"float";
168 p[
"fft/size"][
"type"] =
"int";
169 p[
"fft/rate"][
"type"] =
"int";
171 p[
"buffer_usage"][
"type"] =
"float";
173 p[
"rec_type"][
"type"] =
"string";
174 p[
"recording"][
"type"] =
"bool";
175 p[
"rec_size"][
"type"] =
"int";
180 nlohmann::ordered_json _get_cfg(std::string key)
182 if (key ==
"available_devices")
183 return (nlohmann::json)available_devices;
184 else if (key ==
"current_device")
185 return (nlohmann::json)current_device;
186 else if (dev_blk && key ==
"dev/list")
187 return dev_blk->get_cfg_list();
188 else if (dev_blk && key ==
"dev/cfg")
189 return dev_blk->get_cfg();
190 else if (key ==
"started")
192 else if (key ==
"fft/avg_num")
193 return fftp->avg_num;
194 else if (key ==
"fft/size")
196 else if (key ==
"fft/rate")
198 else if (key ==
"buffer_usage")
200 else if (key ==
"rec_type")
202 else if (key ==
"recording")
204 else if (key ==
"rec_size")
205 return iq_sink->total_written_raw;
207 return nlohmann::json();
210 cfg_res_t _set_cfg(std::string key, nlohmann::ordered_json v)
212 if (!is_started && key ==
"current_device")
215 for (
auto &d : available_devices)
216 found |= nlohmann::json(d) == nlohmann::json(v);
222 dev_blk = ndsp::getDeviceInstanceFromInfo(current_device, ndsp::DeviceBlock::MODE_SINGLE_RX);
224 else if (dev_blk && key ==
"dev/cfg")
226 else if (key ==
"started")
229 if (!is_started && val)
231 else if (is_started && !val)
234 else if (key ==
"fft/avg_num")
238 else if (key ==
"fft/size")
244 if (fft_size > 65536 * 8)
245 fft_size = 65536 * 8;
248 fftp->set_fft_settings(fft_size, dev_blk->getStreamSamplerate(0,
false), fft_rate);
250 else if (key ==
"fft/rate")
256 if (fft_rate > 100e3)
260 fftp->set_fft_settings(fft_size, dev_blk->getStreamSamplerate(0,
false), fft_rate);
262 else if (!recording && key ==
"rec_type")
264 rec_type = std::string(v);
266 else if (is_started && key ==
"recording")
269 if (!recording && val)
271 else if (recording && !val)
275 throw satdump_exception(
"Oops");