5
5
#include < gui/gui.h>
6
6
#include < signal_path/signal_path.h>
7
7
#include < module.h>
8
- #include < filesystem>
9
- #include < dsp/stream.h>
10
- #include < dsp/buffer/reshaper.h>
11
- #include < dsp/multirate/rational_resampler.h>
12
- #include < dsp/sink/handler_sink.h>
13
8
#include < gui/widgets/folder_select.h>
14
- #include < gui/widgets/symbol_diagram.h>
15
- #include < fstream>
16
- #include < chrono>
17
- #include < dsp/demod/quadrature.h>
18
- #include < dsp/clock_recovery/mm.h>
19
- #include < dsp/taps/root_raised_cosine.h>
20
- #include < dsp/correction/dc_blocker.h>
21
- #include < dsp/loop/fast_agc.h>
22
9
#include < utils/optionlist.h>
23
- #include < dsp/digital/binary_slicer.h >
24
- #include < dsp/routing/doubler.h >
25
- #include " pocsag/pocsag .h"
10
+ #include " decoder.h "
11
+ #include " pocsag/decoder.h "
12
+ #include " flex/decoder .h"
26
13
27
14
#define CONCAT (a, b ) ((std::string(a) + b).c_str())
28
15
@@ -34,77 +21,29 @@ SDRPP_MOD_INFO{
34
21
/* Max instances */ -1
35
22
};
36
23
37
- const char * msgTypes[] = {
38
- " Numeric" ,
39
- " Unknown (0b01)" ,
40
- " Unknown (0b10)" ,
41
- " Alphanumeric" ,
42
- };
43
-
44
24
ConfigManager config;
45
25
46
- #define INPUT_SAMPLE_RATE 24000.0
47
- #define INPUT_BANDWIDTH 12500.0
48
- #define INPUT_BAUD_RATE 2400.0
49
-
50
26
enum Protocol {
27
+ PROTOCOL_INVALID = -1 ,
51
28
PROTOCOL_POCSAG,
52
29
PROTOCOL_FLEX
53
30
};
54
31
55
32
class PagerDecoderModule : public ModuleManager ::Instance {
56
33
public:
57
- PagerDecoderModule (std::string name) : diag( 0.6 , 2400 ) {
34
+ PagerDecoderModule (std::string name) {
58
35
this ->name = name;
59
36
60
37
// Define protocols
61
38
protocols.define (" POCSAG" , PROTOCOL_POCSAG);
62
39
protocols.define (" FLEX" , PROTOCOL_FLEX);
63
40
64
- // Load config
65
- config.acquire ();
66
- if (!config.conf .contains (name)) {
67
- config.conf [name][" showLines" ] = false ;
68
- }
69
- showLines = config.conf [name][" showLines" ];
70
- if (showLines) {
71
- diag.lines .push_back (-1.0 );
72
- diag.lines .push_back (-1.0 /3.0 );
73
- diag.lines .push_back (1.0 /3.0 );
74
- diag.lines .push_back (1.0 );
75
- }
76
- config.release (true );
77
-
78
- // Initialize VFO
79
- vfo = sigpath::vfoManager.createVFO (name, ImGui::WaterfallVFO::REF_CENTER, 0 , INPUT_BANDWIDTH, INPUT_SAMPLE_RATE, INPUT_BANDWIDTH, INPUT_BANDWIDTH, true );
41
+ // Initialize VFO with default values
42
+ vfo = sigpath::vfoManager.createVFO (name, ImGui::WaterfallVFO::REF_CENTER, 0 , 12500 , 24000 , 12500 , 12500 , true );
80
43
vfo->setSnapInterval (1 );
81
44
82
- // Initialize DSP here (negative dev to invert signal)
83
- demod.init (vfo->output , -4500.0 , INPUT_SAMPLE_RATE);
84
- dcBlock.init (&demod.out , 0.001 );
85
- float taps[] = { 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f , 0 .1f };
86
- shape = dsp::taps::fromArray<float >(10 , taps);
87
- fir.init (&dcBlock.out , shape);
88
- recov.init (&fir.out , INPUT_SAMPLE_RATE/INPUT_BAUD_RATE, 1e5 , 0.1 , 0.05 );
89
- doubler.init (&recov.out );
90
- slicer.init (&doubler.outB );
91
- dataHandler.init (&slicer.out , _dataHandler, this );
92
- reshape.init (&doubler.outA , 2400.0 , (INPUT_BAUD_RATE / 30.0 ) - 2400.0 );
93
- diagHandler.init (&reshape.out , _diagHandler, this );
94
-
95
- // Initialize decode
96
- decoder.onMessage .bind (&PagerDecoderModule::messageHandler, this );
97
-
98
- // Start DSP Here
99
- demod.start ();
100
- dcBlock.start ();
101
- fir.start ();
102
- recov.start ();
103
- doubler.start ();
104
- slicer.start ();
105
- dataHandler.start ();
106
- reshape.start ();
107
- diagHandler.start ();
45
+ // Select the protocol
46
+ selectProtocol (PROTOCOL_POCSAG);
108
47
109
48
gui::menu.registerEntry (name, menuHandler, this , this );
110
49
}
@@ -113,15 +52,8 @@ class PagerDecoderModule : public ModuleManager::Instance {
113
52
gui::menu.removeEntry (name);
114
53
// Stop DSP
115
54
if (enabled) {
116
- demod.stop ();
117
- dcBlock.stop ();
118
- fir.stop ();
119
- recov.stop ();
120
- doubler.stop ();
121
- slicer.stop ();
122
- dataHandler.stop ();
123
- reshape.stop ();
124
- diagHandler.stop ();
55
+ decoder->stop ();
56
+ decoder.reset ();
125
57
sigpath::vfoManager.deleteVFO (vfo);
126
58
}
127
59
@@ -132,36 +64,17 @@ class PagerDecoderModule : public ModuleManager::Instance {
132
64
133
65
void enable () {
134
66
double bw = gui::waterfall.getBandwidth ();
135
- vfo = sigpath::vfoManager.createVFO (name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double >(0 , -bw / 2.0 , bw / 2.0 ), INPUT_BANDWIDTH, INPUT_SAMPLE_RATE, INPUT_BANDWIDTH, INPUT_BANDWIDTH, true );
136
- vfo->setSnapInterval (250 );
137
-
138
- // Start DSP
139
- demod.start ();
140
- dcBlock.start ();
141
- fir.start ();
142
- recov.start ();
143
- doubler.start ();
144
- slicer.start ();
145
- dataHandler.start ();
146
- reshape.start ();
147
- diagHandler.start ();
67
+ vfo = sigpath::vfoManager.createVFO (name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double >(0 , -bw / 2.0 , bw / 2.0 ), 12500 , 24000 , 12500 , 12500 , true );
68
+ vfo->setSnapInterval (1 );
69
+
70
+ decoder->setVFO (vfo);
71
+ decoder->start ();
148
72
149
73
enabled = true ;
150
74
}
151
75
152
76
void disable () {
153
- demod.stop ();
154
- dcBlock.stop ();
155
- fir.stop ();
156
- recov.stop ();
157
- doubler.stop ();
158
- slicer.stop ();
159
- dataHandler.stop ();
160
- reshape.stop ();
161
- diagHandler.stop ();
162
- reshape.stop ();
163
- diagHandler.stop ();
164
-
77
+ decoder->stop ();
165
78
sigpath::vfoManager.deleteVFO (vfo);
166
79
enabled = false ;
167
80
}
@@ -170,6 +83,36 @@ class PagerDecoderModule : public ModuleManager::Instance {
170
83
return enabled;
171
84
}
172
85
86
+ void selectProtocol (Protocol newProto) {
87
+ // Cannot change while disabled
88
+ if (!enabled) { return ; }
89
+
90
+ // If the protocol hasn't changed, no need to do anything
91
+ if (newProto == proto) { return ; }
92
+
93
+ // Delete current decoder
94
+ decoder.reset ();
95
+
96
+ // Create a new decoder
97
+ switch (newProto) {
98
+ case PROTOCOL_POCSAG:
99
+ decoder = std::make_unique<POCSAGDecoder>(name, vfo);
100
+ break ;
101
+ case PROTOCOL_FLEX:
102
+ decoder = std::make_unique<FLEXDecoder>(name, vfo);
103
+ break ;
104
+ default :
105
+ flog::error (" Tried to select unknown pager protocol" );
106
+ return ;
107
+ }
108
+
109
+ // Start the new decoder
110
+ decoder->start ();
111
+
112
+ // Save selected protocol
113
+ proto = newProto;
114
+ }
115
+
173
116
private:
174
117
static void menuHandler (void * ctx) {
175
118
PagerDecoderModule* _this = (PagerDecoderModule*)ctx;
@@ -181,54 +124,28 @@ class PagerDecoderModule : public ModuleManager::Instance {
181
124
ImGui::LeftLabel (" Protocol" );
182
125
ImGui::FillWidth ();
183
126
if (ImGui::Combo ((" ##pager_decoder_proto_" + _this->name ).c_str (), &_this->protoId , _this->protocols .txt )) {
184
- // TODO
127
+ _this-> selectProtocol (_this-> protocols . value (_this-> protoId ));
185
128
}
186
129
187
- ImGui::SetNextItemWidth (menuWidth);
188
- _this->diag .draw ();
189
-
190
- if (!_this->enabled ) { style::endDisabled (); }
191
- }
192
-
193
- static void _dataHandler (uint8_t * data, int count, void * ctx) {
194
- PagerDecoderModule* _this = (PagerDecoderModule*)ctx;
195
- _this->decoder .process (data, count);
196
- }
130
+ if (_this->decoder ) { _this->decoder ->showMenu (); }
197
131
198
- static void _diagHandler (float * data, int count, void * ctx) {
199
- PagerDecoderModule* _this = (PagerDecoderModule*)ctx;
200
- float * buf = _this->diag .acquireBuffer ();
201
- memcpy (buf, data, count * sizeof (float ));
202
- _this->diag .releaseBuffer ();
203
- }
132
+ ImGui::Button ((" Record##pager_decoder_show_" + _this->name ).c_str (), ImVec2 (menuWidth, 0 ));
133
+ ImGui::Button ((" Show Messages##pager_decoder_show_" + _this->name ).c_str (), ImVec2 (menuWidth, 0 ));
204
134
205
- void messageHandler (pocsag::Address addr, pocsag::MessageType type, const std::string& msg) {
206
- flog::debug (" [{}]: '{}'" , (uint32_t )addr, msg);
135
+ if (!_this->enabled ) { style::endDisabled (); }
207
136
}
208
137
209
138
std::string name;
210
139
bool enabled = true ;
211
140
141
+ Protocol proto = PROTOCOL_INVALID;
212
142
int protoId = 0 ;
213
143
214
144
OptionList<std::string, Protocol> protocols;
215
145
216
- pocsag::Decoder decoder;
217
-
218
146
// DSP Chain
219
147
VFOManager::VFO* vfo;
220
- dsp::demod::Quadrature demod;
221
- dsp::correction::DCBlocker<float > dcBlock;
222
- dsp::tap<float > shape;
223
- dsp::filter::FIR<float , float > fir;
224
- dsp::clock_recovery::MM<float > recov;
225
- dsp::routing::Doubler<float > doubler;
226
- dsp::digital::BinarySlicer slicer;
227
- dsp::buffer::Reshaper<float > reshape;
228
- dsp::sink::Handler<uint8_t > dataHandler;
229
- dsp::sink::Handler<float > diagHandler;
230
-
231
- ImGui::SymbolDiagram diag;
148
+ std::unique_ptr<Decoder> decoder;
232
149
233
150
bool showLines = false ;
234
151
};
0 commit comments