SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
deviceset.cpp
Go to the documentation of this file.
1 // Copyright (C) 2017 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
20 #include "plugin/pluginapi.h"
21 #include "plugin/plugininterface.h"
22 #include "settings/preset.h"
23 #include "channel/channelapi.h"
24 #include "settings/preset.h"
25 
26 #include "deviceset.h"
27 
28 
30  m_channelName(channelName),
31  m_channelSinkAPI(channelAPI),
32  m_channelSourceAPI(0)
33 {
34  if (channelAPI->getStreamType() == ChannelAPI::StreamSingleSink)
35  {
36  m_channelSinkAPI = channelAPI;
37  m_channelSourceAPI = nullptr;
38  }
39  else if (channelAPI->getStreamType() == ChannelAPI::StreamSingleSource)
40  {
41  m_channelSinkAPI = nullptr;
42  m_channelSourceAPI = channelAPI;
43  }
44  else
45  {
46  m_channelSinkAPI = nullptr;
47  m_channelSourceAPI = nullptr;
48  }
49 }
50 
51 DeviceSet::DeviceSet(int tabIndex)
52 {
53  m_deviceAPI = nullptr;
54  m_deviceSourceEngine = nullptr;
55  m_deviceSinkEngine = nullptr;
56  m_deviceMIMOEngine = nullptr;
57  m_deviceTabIndex = tabIndex;
58 }
59 
61 {
62 }
63 
64 void DeviceSet::registerRxChannelInstance(const QString& channelName, ChannelAPI* channelAPI)
65 {
66  m_rxChannelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, channelAPI));
68 }
69 
70 void DeviceSet::registerTxChannelInstance(const QString& channelName, ChannelAPI* channelAPI)
71 {
72  m_txChannelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, channelAPI));
74 }
75 
77 {
78  for(ChannelInstanceRegistrations::iterator it = m_rxChannelInstanceRegistrations.begin(); it != m_rxChannelInstanceRegistrations.end(); ++it)
79  {
80  if(it->m_channelSinkAPI == channelAPI)
81  {
83  break;
84  }
85  }
86 
88 }
89 
91 {
92  for(ChannelInstanceRegistrations::iterator it = m_txChannelInstanceRegistrations.begin(); it != m_txChannelInstanceRegistrations.end(); ++it)
93  {
94  if(it->m_channelSourceAPI == channelAPI)
95  {
97  break;
98  }
99  }
100 
102 }
103 
105 {
106  for(int i = 0; i < m_rxChannelInstanceRegistrations.count(); i++)
107  {
108  qDebug("DeviceSet::freeAll: destroying channel [%s]", qPrintable(m_rxChannelInstanceRegistrations[i].m_channelName));
109  m_rxChannelInstanceRegistrations[i].m_channelSinkAPI->destroy();
110  }
111 }
112 
114 {
115  for(int i = 0; i < m_txChannelInstanceRegistrations.count(); i++)
116  {
117  qDebug("DeviceSet::freeAll: destroying channel [%s]", qPrintable(m_txChannelInstanceRegistrations[i].m_channelName));
118  m_txChannelInstanceRegistrations[i].m_channelSourceAPI->destroy();
119  }
120 }
121 
122 void DeviceSet::deleteRxChannel(int channelIndex)
123 {
124  if (channelIndex < m_rxChannelInstanceRegistrations.count())
125  {
126  m_rxChannelInstanceRegistrations[channelIndex].m_channelSinkAPI->destroy();
127  m_rxChannelInstanceRegistrations.removeAt(channelIndex);
129  }
130 }
131 
132 void DeviceSet::deleteTxChannel(int channelIndex)
133 {
134  if (channelIndex < m_txChannelInstanceRegistrations.count())
135  {
136  m_txChannelInstanceRegistrations[channelIndex].m_channelSourceAPI->destroy();
137  m_txChannelInstanceRegistrations.removeAt(channelIndex);
139  }
140 }
141 
142 void DeviceSet::addRxChannel(int selectedChannelIndex, PluginAPI *pluginAPI)
143 {
144  PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getRxChannelRegistrations(); // Available channel plugins
145  ChannelAPI *rxChannel =(*channelRegistrations)[selectedChannelIndex].m_plugin->createRxChannelCS(m_deviceAPI);
146  ChannelInstanceRegistration reg = ChannelInstanceRegistration(rxChannel->getName(), rxChannel);
148  qDebug("DeviceSet::addRxChannel: %s", qPrintable(rxChannel->getName()));
149 }
150 
151 void DeviceSet::addTxChannel(int selectedChannelIndex, PluginAPI *pluginAPI)
152 {
153  PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getTxChannelRegistrations(); // Available channel plugins
154  ChannelAPI *txChannel = (*channelRegistrations)[selectedChannelIndex].m_plugin->createTxChannelCS(m_deviceAPI);
155  ChannelInstanceRegistration reg = ChannelInstanceRegistration(txChannel->getName(), txChannel);
157  qDebug("DeviceSet::addTxChannel: %s", qPrintable(txChannel->getName()));
158 }
159 
160 void DeviceSet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
161 {
162  if (preset->isSourcePreset())
163  {
164  qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s]", qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
165 
166  // Available channel plugins
167  PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getRxChannelRegistrations();
168 
169  // copy currently open channels and clear list
172 
173  qDebug("DeviceSet::loadChannelSettings: %d channel(s) in preset", preset->getChannelCount());
174 
175  for (int i = 0; i < preset->getChannelCount(); i++)
176  {
177  const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i);
179 
180  // if we have one instance available already, use it
181 
182  for (int i = 0; i < openChannels.count(); i++)
183  {
184  qDebug("DeviceSet::loadChannelSettings: channels compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channelIdURI));
185 
186  //if(openChannels[i].m_channelName == channelConfig.m_channelIdURI)
187  if (compareRxChannelURIs(openChannels[i].m_channelName, channelConfig.m_channelIdURI))
188  {
189  qDebug("DeviceSet::loadChannelSettings: channel [%s] found", qPrintable(openChannels[i].m_channelName));
190  reg = openChannels.takeAt(i);
192  break;
193  }
194  }
195 
196  // if we haven't one already, create one
197 
198  if (reg.m_channelSinkAPI == 0)
199  {
200  for (int i = 0; i < channelRegistrations->count(); i++)
201  {
202  //if((*channelRegistrations)[i].m_channelIdURI == channelConfig.m_channelIdURI)
203  if (compareRxChannelURIs((*channelRegistrations)[i].m_channelIdURI, channelConfig.m_channelIdURI))
204  {
205  qDebug("DeviceSet::loadChannelSettings: creating new channel [%s] from config [%s]",
206  qPrintable((*channelRegistrations)[i].m_channelIdURI),
207  qPrintable(channelConfig.m_channelIdURI));
208  ChannelAPI *rxChannel = (*channelRegistrations)[i].m_plugin->createRxChannelCS(m_deviceAPI);
209  reg = ChannelInstanceRegistration(channelConfig.m_channelIdURI, rxChannel);
211  break;
212  }
213  }
214  }
215 
216  if (reg.m_channelSinkAPI != 0)
217  {
218  qDebug("DeviceSet::loadChannelSettings: deserializing channel [%s]", qPrintable(channelConfig.m_channelIdURI));
219  reg.m_channelSinkAPI->deserialize(channelConfig.m_config);
220  }
221  }
222 
223  // everything, that is still "available" is not needed anymore
224  for (int i = 0; i < openChannels.count(); i++)
225  {
226  qDebug("DeviceSet::loadChannelSettings: destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName));
227  openChannels[i].m_channelSinkAPI->destroy();
228  }
229 
231  }
232  else
233  {
234  qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s] not a source preset", qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
235  }
236 }
237 
239 {
240  if (preset->isSourcePreset())
241  {
242  qSort(m_rxChannelInstanceRegistrations.begin(), m_rxChannelInstanceRegistrations.end()); // sort by increasing delta frequency and type
243 
244  for(int i = 0; i < m_rxChannelInstanceRegistrations.count(); i++)
245  {
246  qDebug("DeviceSet::saveChannelSettings: channel [%s] saved", qPrintable(m_rxChannelInstanceRegistrations[i].m_channelName));
248  }
249  }
250  else
251  {
252  qDebug("DeviceSet::saveChannelSettings: not a source preset");
253  }
254 }
255 
256 void DeviceSet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
257 {
258  if (preset->isSourcePreset())
259  {
260  qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s] not a sink preset", qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
261  }
262  else
263  {
264  qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s]", qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
265 
266  // Available channel plugins
267  PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getTxChannelRegistrations();
268 
269  // copy currently open channels and clear list
272 
273  qDebug("DeviceSet::loadChannelSettings: %d channel(s) in preset", preset->getChannelCount());
274 
275  for(int i = 0; i < preset->getChannelCount(); i++)
276  {
277  const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i);
279 
280  // if we have one instance available already, use it
281 
282  for(int i = 0; i < openChannels.count(); i++)
283  {
284  qDebug("DeviceSet::loadChannelSettings: channels compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channelIdURI));
285 
286  if(openChannels[i].m_channelName == channelConfig.m_channelIdURI)
287  {
288  qDebug("DeviceSet::loadChannelSettings: channel [%s] found", qPrintable(openChannels[i].m_channelName));
289  reg = openChannels.takeAt(i);
291  break;
292  }
293  }
294 
295  // if we haven't one already, create one
296 
297  if(reg.m_channelSourceAPI == 0)
298  {
299  for(int i = 0; i < channelRegistrations->count(); i++)
300  {
301  if((*channelRegistrations)[i].m_channelIdURI == channelConfig.m_channelIdURI)
302  {
303  qDebug("DeviceSet::loadChannelSettings: creating new channel [%s]", qPrintable(channelConfig.m_channelIdURI));
304  ChannelAPI *txChannel = (*channelRegistrations)[i].m_plugin->createTxChannelCS(m_deviceAPI);
305  reg = ChannelInstanceRegistration(channelConfig.m_channelIdURI, txChannel);
307  break;
308  }
309  }
310  }
311 
312  if(reg.m_channelSourceAPI != 0)
313  {
314  qDebug("DeviceSet::loadChannelSettings: deserializing channel [%s]", qPrintable(channelConfig.m_channelIdURI));
315  reg.m_channelSourceAPI->deserialize(channelConfig.m_config);
316  }
317  }
318 
319  // everything, that is still "available" is not needed anymore
320  for(int i = 0; i < openChannels.count(); i++)
321  {
322  qDebug("DeviceSet::loadChannelSettings: destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName));
323  openChannels[i].m_channelSourceAPI->destroy();
324  }
325 
327  }
328 }
329 
331 {
332  if (preset->isSourcePreset())
333  {
334  qDebug("DeviceSet::saveChannelSettings: not a sink preset");
335  }
336  else
337  {
338  qSort(m_txChannelInstanceRegistrations.begin(), m_txChannelInstanceRegistrations.end()); // sort by increasing delta frequency and type
339 
340  for(int i = 0; i < m_txChannelInstanceRegistrations.count(); i++)
341  {
342  qDebug("DeviceSet::saveChannelSettings: channel [%s] saved", qPrintable(m_txChannelInstanceRegistrations[i].m_channelName));
344  }
345  }
346 }
347 
349 {
350  for(int i = 0; i < m_rxChannelInstanceRegistrations.count(); i++)
351  {
352  m_rxChannelInstanceRegistrations[i].m_channelSinkAPI->setName(QString("%1:%2").arg(m_rxChannelInstanceRegistrations[i].m_channelName).arg(i));
353  }
354 }
355 
357 {
358  for(int i = 0; i < m_txChannelInstanceRegistrations.count(); i++)
359  {
360  m_txChannelInstanceRegistrations[i].m_channelSourceAPI->setName(QString("%1:%2").arg(m_txChannelInstanceRegistrations[i].m_channelName).arg(i));
361  }
362 }
363 
364 // sort by increasing delta frequency and type (i.e. name)
366 {
367  if (m_channelSinkAPI && other.m_channelSinkAPI)
368  {
370  {
371  return m_channelSinkAPI->getName() < other.m_channelSinkAPI->getName();
372  }
373  else
374  {
376  }
377  }
378  else if (m_channelSourceAPI && other.m_channelSourceAPI)
379  {
381  {
383  }
384  else
385  {
387  }
388  }
389  else
390  {
391  return false;
392  }
393 }
394 
395 bool DeviceSet::compareRxChannelURIs(const QString& registerdChannelURI, const QString& xChannelURI)
396 {
397  if ((xChannelURI == "sdrangel.channel.chanalyzerng") || (xChannelURI == "sdrangel.channel.chanalyzer")) { // renamed ChanalyzerNG to Chanalyzer in 4.0.0
398  return registerdChannelURI == "sdrangel.channel.chanalyzer";
399  } else if ((xChannelURI == "de.maintech.sdrangelove.channel.am") || (xChannelURI == "sdrangel.channel.amdemod")) {
400  return registerdChannelURI == "sdrangel.channel.amdemod";
401  } else if ((xChannelURI == "de.maintech.sdrangelove.channel.nfm") || (xChannelURI == "sdrangel.channel.nfmdemod")) {
402  return registerdChannelURI == "sdrangel.channel.nfmdemod";
403  } else if ((xChannelURI == "de.maintech.sdrangelove.channel.ssb") || (xChannelURI == "sdrangel.channel.ssbdemod")) {
404  return registerdChannelURI == "sdrangel.channel.ssbdemod";
405  } else if ((xChannelURI == "de.maintech.sdrangelove.channel.wfm") || (xChannelURI == "sdrangel.channel.wfmdemod")) {
406  return registerdChannelURI == "sdrangel.channel.wfmdemod";
407  } else {
408  return registerdChannelURI == xChannelURI;
409  }
410 }
virtual const QString & getName() const
Definition: channelapi.h:53
int getChannelCount() const
Definition: preset.h:86
DeviceSet(int tabIndex)
Definition: deviceset.cpp:51
ChannelRegistrations * getTxChannelRegistrations()
Definition: pluginapi.cpp:34
void renameRxChannelInstances()
Definition: deviceset.cpp:348
QList< ChannelRegistration > ChannelRegistrations
Definition: pluginapi.h:44
void loadTxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
Definition: deviceset.cpp:256
void removeTxChannelInstance(ChannelAPI *channelAPI)
Definition: deviceset.cpp:90
int m_deviceTabIndex
Definition: deviceset.h:81
bool operator<(const ChannelInstanceRegistration &other) const
Definition: deviceset.cpp:365
const ChannelConfig & getChannelConfig(int index) const
Definition: preset.h:87
ChannelInstanceRegistrations m_rxChannelInstanceRegistrations
Definition: deviceset.h:79
QString m_channelIdURI
Channel type ID in URI form.
Definition: preset.h:31
DSPDeviceSourceEngine * m_deviceSourceEngine
Definition: deviceset.h:35
Exposes a single source stream (output, Tx)
Definition: channelapi.h:42
bool isSourcePreset() const
Definition: preset.h:66
void removeRxChannelInstance(ChannelAPI *channelAPI)
Definition: deviceset.cpp:76
void freeTxChannels()
Definition: deviceset.cpp:113
void renameTxChannelInstances()
Definition: deviceset.cpp:356
virtual qint64 getCenterFrequency() const =0
Applies to a default stream.
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
ChannelRegistrations * getRxChannelRegistrations()
Definition: pluginapi.cpp:14
void addChannel(const QString &channel, const QByteArray &config)
Definition: preset.h:85
void loadRxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
Definition: deviceset.cpp:160
void addRxChannel(int selectedChannelIndex, PluginAPI *pluginAPI)
Definition: deviceset.cpp:142
void saveRxChannelSettings(Preset *preset)
Definition: deviceset.cpp:238
bool compareRxChannelURIs(const QString &registerdChannelURI, const QString &xChannelURI)
Definition: deviceset.cpp:395
Definition: preset.h:28
int32_t i
Definition: decimators.h:244
void registerRxChannelInstance(const QString &channelName, ChannelAPI *channelAPI)
Definition: deviceset.cpp:64
QList< ChannelInstanceRegistration > ChannelInstanceRegistrations
Definition: deviceset.h:77
DeviceAPI * m_deviceAPI
Definition: deviceset.h:34
void deleteRxChannel(int channelIndex)
Definition: deviceset.cpp:122
StreamType getStreamType() const
Definition: channelapi.h:96
Exposes a single sink stream (input, Rx)
Definition: channelapi.h:41
void saveTxChannelSettings(Preset *preset)
Definition: deviceset.cpp:330
DSPDeviceMIMOEngine * m_deviceMIMOEngine
Definition: deviceset.h:37
void registerTxChannelInstance(const QString &channelName, ChannelAPI *channelAPI)
Definition: deviceset.cpp:70
QByteArray m_config
Definition: preset.h:33
virtual bool deserialize(const QByteArray &data)=0
ChannelInstanceRegistrations m_txChannelInstanceRegistrations
Definition: deviceset.h:80
virtual QByteArray serialize() const =0
void freeRxChannels()
Definition: deviceset.cpp:104
const QString & getDescription() const
Definition: preset.h:74
DSPDeviceSinkEngine * m_deviceSinkEngine
Definition: deviceset.h:36
void deleteTxChannel(int channelIndex)
Definition: deviceset.cpp:132
const QString & getGroup() const
Definition: preset.h:72
void addTxChannel(int selectedChannelIndex, PluginAPI *pluginAPI)
Definition: deviceset.cpp:151