77#include < gnuradio/fft/fft_v.h>
88#include < gnuradio/fft/window.h>
99#include < gnuradio/soapy/source.h>
10+ #include < gnuradio/zeromq/pub_sink.h>
1011#include < logger.h>
1112#include < radio/blocks/decimator.h>
1213#include < radio/blocks/psd.h>
1314#include < radio/blocks/spectrogram.h>
1415
16+ #include < filesystem>
17+
1518constexpr auto LABEL = " sdr" ;
1619
17- SdrDevice::SdrDevice (const Config& config, const Device& device, RemoteController& remoteController, TransmissionNotification& notification, const int recordersCount)
18- : m_sampleRate(device.sample_rate), m_isInitialized(false ), m_frequencyRange({0 , 0 }), m_tb(gr::make_top_block(" sdr" )), m_powerFileSink(nullptr ), m_rawIqFileSink(nullptr ), m_connector(m_tb) {
20+ SdrDevice::SdrDevice (const Config& config, const Device& device, RemoteController& remoteController, TransmissionNotification& notification)
21+ : m_config(config),
22+ m_device(device),
23+ m_zeromq(fmt::format(" ipc://{}/{}_{}_zeromq_stream.sock" , std::filesystem::canonical(m_config.workDir()).string(), device.driver, device.serial)),
24+ m_remoteController(remoteController),
25+ m_sampleRate(device.sample_rate),
26+ m_isInitialized(false ),
27+ m_frequencyRange({0 , 0 }),
28+ m_tb(gr::make_top_block(" sdr" )),
29+ m_powerFileSink(nullptr ),
30+ m_rawIqFileSink(nullptr ),
31+ m_connector(m_tb) {
1932 Logger::info (LABEL, " starting" );
20- Logger::info (
21- LABEL,
22- " driver: {}, serial: {}, sample rate: {}, recorders: {}" ,
23- colored (GREEN, " {}" , device.driver ),
24- colored (GREEN, " {}" , device.serial ),
25- formatFrequency (m_sampleRate),
26- colored (GREEN, " {}" , recordersCount));
33+ Logger::info (LABEL, " driver: {}, serial: {}, sample rate: {}" , colored (GREEN, " {}" , device.driver ), colored (GREEN, " {}" , device.serial ), formatFrequency (m_sampleRate));
34+ Logger::info (LABEL, " zeromq: {}" , colored (GREEN, " {}" , m_zeromq));
2735
2836 m_source = std::make_shared<SdrSource>(device);
2937 setupChains (config, device, remoteController, notification);
3038
31- Logger::info (LABEL, " recording bandwidth: {}" , formatFrequency (config.recordingBandwidth ()));
32- for (int i = 0 ; i < recordersCount; ++i) {
33- m_recorders.push_back (std::make_unique<Recorder>(config, m_tb, m_source, m_sampleRate, std::bind (&RemoteController::sendTransmission, remoteController, device.getName (), std::placeholders::_1)));
34- }
35-
3639 m_tb->start ();
3740 Logger::info (LABEL, " started" );
3841}
@@ -41,6 +44,7 @@ SdrDevice::~SdrDevice() {
4144 Logger::info (LABEL, " stopping" );
4245 m_tb->stop ();
4346 m_tb->wait ();
47+ std::remove (m_zeromq.c_str ());
4448 Logger::info (LABEL, " stopped" );
4549}
4650
@@ -73,66 +77,44 @@ void SdrDevice::setFrequencyRange(FrequencyRange frequencyRange) {
7377}
7478
7579void SdrDevice::updateRecordings (const std::vector<Recording> recordings) {
76- const auto isWaitingForRecording = [&recordings](const Frequency& frequency) {
77- return std::find_if (recordings.begin (), recordings.end (), [frequency](const Recording& recording) {
78- // improve auto formatter
79- return frequency == recording.recordingFrequency ;
80- }) != recordings.end ();
81- };
82- const auto getRecorder = [this ](const Frequency& frequency) {
83- return std::find_if (m_recorders.begin (), m_recorders.end (), [frequency](const std::unique_ptr<Recorder>& recorder) {
80+ const auto findRecorder = [this ](const Recording& recording) {
81+ return std::find_if (m_recorders.begin (), m_recorders.end (), [recording](const std::unique_ptr<Recorder>& recorder) {
8482 // improve auto formatter
85- return frequency == recorder->getRecording ().recordingFrequency ;
83+ return recording. recordingFrequency == recorder->getRecording ().recordingFrequency ;
8684 });
8785 };
88- const auto getFreeRecorder = [this ]() {
89- return std::find_if (m_recorders.begin (), m_recorders.end (), [](const std::unique_ptr<Recorder>& recorder) {
90- // improve auto formatter
91- return !recorder->isRecording ();
92- });
86+
87+ const auto isRecordingActive = [recordings](const Recording& recording1) {
88+ return std::find_if (recordings.begin (), recordings.end (), [recording1](const Recording& recording2) {
89+ // improve auto formatter
90+ return recording1.recordingFrequency == recording2.recordingFrequency ;
91+ }) != recordings.end ();
9392 };
9493
95- for (auto & recorder : m_recorders) {
96- if (recorder->isRecording ()) {
97- if (!isWaitingForRecording (recorder->getRecording ().recordingFrequency )) {
98- recorder->stopRecording ();
99- Logger::info (LABEL, " stop recorder, frequency: {}, time: {} ms" , formatFrequency (recorder->getRecording ().recordingFrequency , RED), recorder->getDuration ().count ());
100- }
101- }
94+ std::erase_if (m_recorders, [isRecordingActive](const std::unique_ptr<Recorder>& recorder) { return !isRecordingActive (recorder->getRecording ()); });
95+
96+ if (m_recorders.size () < static_cast <size_t >(m_config.recordersCount ())) {
97+ ignoredTransmissions.clear ();
10298 }
10399
104100 for (const auto & recording : recordings) {
105- const auto itRecorder = getRecorder (recording.recordingFrequency );
106- if (itRecorder != m_recorders.end ()) {
107- const auto & recorder = *itRecorder;
108- if (!recorder->isRecording ()) {
109- Logger::warn (LABEL, " start recorder that should be already started, frequency: {}" , formatFrequency (recording.recordingFrequency ), GREEN);
110- }
101+ const auto it = findRecorder (recording);
102+ if (it != m_recorders.end ()) {
111103 if (recording.flush ) {
112- recorder ->flush ();
104+ (*it) ->flush ();
113105 }
114106 } else {
115- const auto itFreeRecorder = getFreeRecorder ();
116- if (itFreeRecorder != m_recorders.end ()) {
117- const auto & freeRecorder = *itFreeRecorder;
118- freeRecorder->startRecording (recording);
119- Logger::info (LABEL, " start recorder, frequency: {}" , formatFrequency (recording.recordingFrequency , GREEN));
107+ if (m_recorders.size () < static_cast <size_t >(m_config.recordersCount ())) {
108+ m_recorders.push_back (
109+ std::make_unique<Recorder>(m_config, m_zeromq, m_sampleRate, recording, std::bind (&RemoteController::sendTransmission, m_remoteController, m_device.getName (), std::placeholders::_1)));
120110 } else {
121111 if (!ignoredTransmissions.count (recording.recordingFrequency )) {
122- Logger::info (LABEL, " no recorders available , frequency: {}" , formatFrequency (recording.recordingFrequency , YELLOW ));
112+ Logger::info (LABEL, " maximum recorders limit reached , frequency: {}" , formatFrequency (recording.recordingFrequency , RED ));
123113 ignoredTransmissions.insert (recording.recordingFrequency );
124114 }
125115 }
126116 }
127117 }
128-
129- for (auto it = ignoredTransmissions.begin (); it != ignoredTransmissions.cend ();) {
130- if (isWaitingForRecording (*it)) {
131- it++;
132- } else {
133- ignoredTransmissions.erase (it++);
134- }
135- }
136118}
137119
138120Frequency SdrDevice::getFrequency () const { return m_frequencyRange.center (); }
@@ -169,4 +151,7 @@ void SdrDevice::setupChains(const Config& config, const Device& device, RemoteCo
169151 m_rawIqFileSink = std::make_shared<FileSink<gr_complex>>(1 , false );
170152 m_connector.connect <Block>(m_source, m_rawIqFileSink);
171153 }
154+
155+ auto sink = gr::zeromq::pub_sink::make (sizeof (gr_complex), 1 , const_cast <char *>(m_zeromq.c_str ()));
156+ m_connector.connect <Block>(m_source, sink);
172157}
0 commit comments