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.
scopevis.h
Go to the documentation of this file.
1 // Copyright (C) 2017 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #ifndef SDRBASE_DSP_SCOPEVISNG_H_
20 #define SDRBASE_DSP_SCOPEVISNG_H_
21 
22 #include <QDebug>
23 #include <QColor>
24 #include <QByteArray>
25 
26 #include <algorithm>
27 #include <utility>
28 #include <math.h>
29 
30 #include <stdint.h>
31 #include <vector>
32 #include <boost/circular_buffer.hpp>
33 #include "dsp/dsptypes.h"
34 #include "dsp/basebandsamplesink.h"
35 #include "dsp/projector.h"
36 #include "export.h"
37 #include "util/message.h"
38 #include "util/doublebuffer.h"
39 
40 #undef M_PI
41 #define M_PI 3.14159265358979323846
42 
43 class GLScope;
44 
46 
47 public:
48  struct TraceData
49  {
52  float m_amp;
54  float m_ofs;
56  int m_ofsFine;
61  QColor m_traceColor;
62  float m_traceColorR;
63  float m_traceColorG;
64  float m_traceColorB;
66  QString m_textOverlay;
67  bool m_viewTrace;
68 
70  m_projectionType(Projector::ProjectionReal),
71  m_inputIndex(0),
72  m_amp(1.0f),
73  m_ampIndex(0),
74  m_ofs(0.0f),
75  m_ofsCoarse(0),
76  m_ofsFine(0),
77  m_traceDelay(0),
78  m_traceDelayCoarse(0),
79  m_traceDelayFine(0),
80  m_triggerDisplayLevel(2.0), // OVer scale by default (2.0)
81  m_traceColor(255,255,64),
82  m_hasTextOverlay(false),
83  m_viewTrace(true)
84  {
85  setColor(m_traceColor);
86  }
87 
88  void setColor(QColor color)
89  {
90  m_traceColor = color;
91  qreal r,g,b,a;
92  m_traceColor.getRgbF(&r, &g, &b, &a);
93  m_traceColorR = r;
94  m_traceColorG = g;
95  m_traceColorB = b;
96  }
97  };
98 
99 
100  struct TriggerData
101  {
115  QColor m_triggerColor;
119 
121  m_projectionType(Projector::ProjectionReal),
122  m_inputIndex(0),
123  m_triggerLevel(0.0f),
124  m_triggerLevelCoarse(0),
125  m_triggerLevelFine(0),
126  m_triggerPositiveEdge(true),
127  m_triggerBothEdges(false),
128  m_triggerHoldoff(1),
129  m_triggerDelay(0),
130  m_triggerDelayMult(0.0),
131  m_triggerDelayCoarse(0),
132  m_triggerDelayFine(0),
133  m_triggerRepeat(0),
134  m_triggerColor(0,255,0)
135  {
136  setColor(m_triggerColor);
137  }
138 
139  void setColor(QColor color)
140  {
141  m_triggerColor = color;
142  qreal r,g,b,a;
143  m_triggerColor.getRgbF(&r, &g, &b, &a);
144  m_triggerColorR = r;
145  m_triggerColorG = g;
146  m_triggerColorB = b;
147  }
148  };
149 
151  static const uint32_t m_maxNbTriggers = 10;
152  static const uint32_t m_maxNbTraces = 10;
153  static const uint32_t m_nbTraceMemories = 50;
154 
155  ScopeVis(GLScope* glScope = 0);
156  virtual ~ScopeVis();
157 
158  void setLiveRate(int sampleRate);
159  void setLiveRateLog2Decim(int log2Decim);
160  void configure(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun);
161  void addTrace(const TraceData& traceData);
162  void changeTrace(const TraceData& traceData, uint32_t traceIndex);
163  void removeTrace(uint32_t traceIndex);
164  void moveTrace(uint32_t traceIndex, bool upElseDown);
165  void focusOnTrace(uint32_t traceIndex);
166  void addTrigger(const TriggerData& triggerData);
167  void changeTrigger(const TriggerData& triggerData, uint32_t triggerIndex);
168  void removeTrigger(uint32_t triggerIndex);
169  void moveTrigger(uint32_t triggerIndex, bool upElseDown);
170  void focusOnTrigger(uint32_t triggerIndex);
171  void setOneShot(bool oneShot);
172  void setMemoryIndex(uint32_t memoryIndex);
173 
174  QByteArray serializeMemory() const
175  {
176  SimpleSerializer s(1);
177 
178  s.writeU32(1, m_traceSize);
179  s.writeU32(2, m_preTriggerDelay);
180  s.writeS32(3, m_sampleRate);
181  QByteArray buffer = m_traceDiscreteMemory.serialize();
182  s.writeBlob(4, buffer);
183 
184  return s.final();
185  }
186 
187  bool deserializeMemory(const QByteArray& data)
188  {
189  SimpleDeserializer d(data);
190 
191  if(!d.isValid()) {
192  return false;
193  }
194 
195  if (d.getVersion() == 1)
196  {
197  uint32_t traceSize, preTriggerDelay;
198  int sampleRate;
199  QByteArray buf;
200  bool traceDiscreteMemorySuccess;
201 
202  d.readU32(1, &traceSize, m_traceChunkSize);
203  d.readU32(2, &preTriggerDelay, 0);
204  d.readS32(3, &sampleRate, 0);
205  setSampleRate(sampleRate);
206  setTraceSize(traceSize, true);
207  setPreTriggerDelay(preTriggerDelay, true);
208  d.readBlob(4, &buf);
209  traceDiscreteMemorySuccess = m_traceDiscreteMemory.deserialize(buf);
210 
211  if (traceDiscreteMemorySuccess && (m_glScope) && (m_currentTraceMemoryIndex > 0)) {
212  processMemoryTrace();
213  }
214 
215  return traceDiscreteMemorySuccess;
216  }
217  else
218  {
219  return false;
220  }
221  }
222 
223  void getTriggerData(TriggerData& triggerData, uint32_t triggerIndex)
224  {
225  if (triggerIndex < m_triggerConditions.size())
226  {
227  triggerData = m_triggerConditions[triggerIndex]->m_triggerData;
228  }
229  }
230 
231  void getTraceData(TraceData& traceData, uint32_t traceIndex)
232  {
233  if (traceIndex < m_traces.m_tracesData.size())
234  {
235  traceData = m_traces.m_tracesData[traceIndex];
236  }
237  }
238 
239  const TriggerData& getTriggerData(uint32_t triggerIndex) const { return m_triggerConditions[triggerIndex]->m_triggerData; }
240  const std::vector<TraceData>& getTracesData() const { return m_traces.m_tracesData; }
241  uint32_t getNbTriggers() const { return m_triggerConditions.size(); }
242 
243  virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
244  virtual void start();
245  virtual void stop();
246  virtual bool handleMessage(const Message& message);
247  int getTriggerLocation() const { return m_triggerLocation; }
248 
249 private:
250  // === messages ===
251  // ---------------------------------------------
254 
255  public:
257  uint32_t traceSize,
258  uint32_t timeBase,
259  uint32_t timeOfsProMill,
260  uint32_t triggerPre,
261  bool freeRun)
262  {
263  return new MsgConfigureScopeVisNG(traceSize, timeBase, timeOfsProMill, triggerPre, freeRun);
264  }
265 
266  uint32_t getTraceSize() const { return m_traceSize; }
267  uint32_t getTimeBase() const { return m_timeBase; }
268  uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; }
269  uint32_t getTriggerPre() const { return m_triggerPre; }
270  bool getFreeRun() const { return m_freeRun; }
271 
272  private:
277  bool m_freeRun;
278 
280  uint32_t timeBase,
281  uint32_t timeOfsProMill,
282  uint32_t triggerPre,
283  bool freeRun) :
284  m_traceSize(traceSize),
285  m_timeBase(timeBase),
286  m_timeOfsProMill(timeOfsProMill),
287  m_triggerPre(triggerPre),
288  m_freeRun(freeRun)
289  {}
290  };
291 
292  // ---------------------------------------------
295 
296  public:
298  const TriggerData& triggerData)
299  {
300  return new MsgScopeVisNGAddTrigger(triggerData);
301  }
302 
303  const TriggerData& getTriggerData() const { return m_triggerData; }
304 
305  private:
307 
308  MsgScopeVisNGAddTrigger(const TriggerData& triggerData) :
309  m_triggerData(triggerData)
310  {}
311  };
312 
313  // ---------------------------------------------
316 
317  public:
319  const TriggerData& triggerData, uint32_t triggerIndex)
320  {
321  return new MsgScopeVisNGChangeTrigger(triggerData, triggerIndex);
322  }
323 
324  const TriggerData& getTriggerData() const { return m_triggerData; }
325  uint32_t getTriggerIndex() const { return m_triggerIndex; }
326 
327  private:
330 
331  MsgScopeVisNGChangeTrigger(const TriggerData& triggerData, uint32_t triggerIndex) :
332  m_triggerData(triggerData),
333  m_triggerIndex(triggerIndex)
334  {}
335  };
336 
337  // ---------------------------------------------
340 
341  public:
343  uint32_t triggerIndex)
344  {
345  return new MsgScopeVisNGRemoveTrigger(triggerIndex);
346  }
347 
348  uint32_t getTriggerIndex() const { return m_triggerIndex; }
349 
350  private:
352 
354  m_triggerIndex(triggerIndex)
355  {}
356  };
357 
358  // ---------------------------------------------
361 
362  public:
364  uint32_t triggerIndex,
365  bool moveUpElseDown)
366  {
367  return new MsgScopeVisNGMoveTrigger(triggerIndex, moveUpElseDown);
368  }
369 
370  uint32_t getTriggerIndex() const { return m_triggerIndex; }
371  bool getMoveUp() const { return m_moveUpElseDown; }
372 
373  private:
376 
377  MsgScopeVisNGMoveTrigger(uint32_t triggerIndex, bool moveUpElseDown) :
378  m_triggerIndex(triggerIndex),
379  m_moveUpElseDown(moveUpElseDown)
380  {}
381  };
382 
383  // ---------------------------------------------
386 
387  public:
389  uint32_t triggerIndex)
390  {
391  return new MsgScopeVisNGFocusOnTrigger(triggerIndex);
392  }
393 
394  uint32_t getTriggerIndex() const { return m_triggerIndex; }
395 
396  private:
398 
400  m_triggerIndex(triggerIndex)
401  {}
402  };
403 
404  // ---------------------------------------------
407 
408  public:
410  const TraceData& traceData)
411  {
412  return new MsgScopeVisNGAddTrace(traceData);
413  }
414 
415  const TraceData& getTraceData() const { return m_traceData; }
416 
417  private:
419 
420  MsgScopeVisNGAddTrace(const TraceData& traceData) :
421  m_traceData(traceData)
422  {}
423  };
424 
425  // ---------------------------------------------
428 
429  public:
431  const TraceData& traceData, uint32_t traceIndex)
432  {
433  return new MsgScopeVisNGChangeTrace(traceData, traceIndex);
434  }
435 
436  const TraceData& getTraceData() const { return m_traceData; }
437  uint32_t getTraceIndex() const { return m_traceIndex; }
438 
439  private:
442 
443  MsgScopeVisNGChangeTrace(TraceData traceData, uint32_t traceIndex) :
444  m_traceData(traceData),
445  m_traceIndex(traceIndex)
446  {}
447  };
448 
449  // ---------------------------------------------
452 
453  public:
455  uint32_t traceIndex)
456  {
457  return new MsgScopeVisNGRemoveTrace(traceIndex);
458  }
459 
460  uint32_t getTraceIndex() const { return m_traceIndex; }
461 
462  private:
464 
466  m_traceIndex(traceIndex)
467  {}
468  };
469 
470  // ---------------------------------------------
473 
474  public:
476  uint32_t traceIndex,
477  bool moveUpElseDown)
478  {
479  return new MsgScopeVisNGMoveTrace(traceIndex, moveUpElseDown);
480  }
481 
482  uint32_t getTraceIndex() const { return m_traceIndex; }
483  bool getMoveUp() const { return m_moveUpElseDown; }
484 
485  private:
488 
489  MsgScopeVisNGMoveTrace(uint32_t traceIndex, bool moveUpElseDown) :
490  m_traceIndex(traceIndex),
491  m_moveUpElseDown(moveUpElseDown)
492  {}
493  };
494 
495  // ---------------------------------------------
498 
499  public:
501  uint32_t traceIndex)
502  {
503  return new MsgScopeVisNGFocusOnTrace(traceIndex);
504  }
505 
506  uint32_t getTraceIndex() const { return m_traceIndex; }
507 
508  private:
510 
512  m_traceIndex(traceIndex)
513  {}
514  };
515 
516  // ---------------------------------------------
517  class MsgScopeVisNGOneShot : public Message {
519 
520  public:
522  bool oneShot)
523  {
524  return new MsgScopeVisNGOneShot(oneShot);
525  }
526 
527  bool getOneShot() const { return m_oneShot; }
528 
529  private:
530  bool m_oneShot;
531 
532  MsgScopeVisNGOneShot(bool oneShot) :
533  m_oneShot(oneShot)
534  {}
535  };
536 
537  // ---------------------------------------------
540 
541  public:
543  uint32_t memoryIndex)
544  {
545  return new MsgScopeVisNGMemoryTrace(memoryIndex);
546  }
547 
548  uint32_t getMemoryIndex() const { return m_memoryIndex; }
549 
550  private:
552 
554  m_memoryIndex(memoryIndex)
555  {}
556  };
557 
558  // ---------------------------------------------
559 
564  {
568  };
569 
571  {
572  public:
580 
581 
582  TriggerCondition(const TriggerData& triggerData) :
583  m_projector(Projector::ProjectionReal),
584  m_triggerData(triggerData),
585  m_prevCondition(false),
586  m_triggerDelayCount(0),
587  m_triggerCounter(0),
588  m_trues(0),
589  m_falses(0)
590  {
591  }
592 
594  {
595  }
596 
598  {
599  m_projector.settProjectionType(m_triggerData.m_projectionType);
600  }
601 
603  {
604  }
605 
606  void setData(const TriggerData& triggerData)
607  {
608  m_triggerData = triggerData;
609 
610  if (m_projector.getProjectionType() != m_triggerData.m_projectionType)
611  {
612  m_projector.settProjectionType(m_triggerData.m_projectionType);
613  }
614 
615  m_prevCondition = false;
616  m_triggerDelayCount = 0;
617  m_triggerCounter = 0;
618  m_trues = 0;
619  m_falses = 0;
620  }
621 
622  void operator=(const TriggerCondition& other)
623  {
624  setData(other.m_triggerData);
625  }
626  };
627 
632 
634  {
635  TraceBuffer m_traceBuffer;
636  SampleVector::iterator m_endPoint;
637 
639  {
640  m_endPoint = m_traceBuffer.getCurrent();
641  }
642 
643  void resize(uint32_t size)
644  {
645  m_traceBuffer.resize(size);
646  }
647 
648  void reset()
649  {
650  m_traceBuffer.reset();
651  }
652 
653  void write(const SampleVector::const_iterator begin, const SampleVector::const_iterator end)
654  {
655  m_traceBuffer.write(begin, end);
656  }
657 
658  unsigned int absoluteFill() const {
659  return m_traceBuffer.absoluteFill();
660  }
661 
662  SampleVector::iterator current() { return m_traceBuffer.getCurrent(); }
663 
664  QByteArray serialize() const
665  {
666  SimpleSerializer s(1);
667 
668  QByteArray buffer = m_traceBuffer.serialize();
669  unsigned int endDelta = m_endPoint - m_traceBuffer.begin();
670  s.writeU32(1, endDelta);
671  s.writeBlob(2, buffer);
672 
673  return s.final();
674  }
675 
676  bool deserialize(const QByteArray& data)
677  {
678  SimpleDeserializer d(data);
679 
680  if(!d.isValid()) {
681  return false;
682  }
683 
684  if (d.getVersion() == 1)
685  {
686  unsigned int tmpUInt;
687  QByteArray buf;
688 
689  d.readU32(1, &tmpUInt, 0);
690  d.readBlob(2, &buf);
691  m_traceBuffer.deserialize(buf);
692  m_endPoint = m_traceBuffer.begin() + tmpUInt;
693 
694  return true;
695  }
696  else
697  {
698  return false;
699  }
700  }
701  };
702 
704  {
705  std::vector<TraceBackBuffer> m_traceBackBuffers;
709 
713  TraceBackDiscreteMemory(uint32_t size) : m_memSize(size), m_currentMemIndex(0), m_traceSize(0)
714  {
715  m_traceBackBuffers.resize(m_memSize);
716  }
717 
721  void resize(uint32_t size)
722  {
723  m_traceSize = size;
724 
725  for (std::vector<TraceBackBuffer>::iterator it = m_traceBackBuffers.begin(); it != m_traceBackBuffers.end(); ++it)
726  {
727  it->resize(2*m_traceSize); // was multiplied by 4
728  }
729  }
730 
736  TraceBackBuffer &store(int samplesToReport)
737  {
738  uint32_t nextMemIndex = m_currentMemIndex < (m_memSize-1) ? m_currentMemIndex+1 : 0;
739  m_traceBackBuffers[nextMemIndex].reset();
740  m_traceBackBuffers[nextMemIndex].write(m_traceBackBuffers[m_currentMemIndex].m_endPoint - samplesToReport,
741  m_traceBackBuffers[m_currentMemIndex].m_endPoint);
742  m_currentMemIndex = nextMemIndex;
743  return m_traceBackBuffers[m_currentMemIndex]; // new trace
744  }
745 
750  {
751  int index = (m_currentMemIndex + (m_memSize - (shift % m_memSize))) % m_memSize;
752  return m_traceBackBuffers[index];
753  }
754 
759  {
760  return m_traceBackBuffers[m_currentMemIndex];
761  }
762 
766  TraceBackBuffer& at(int index)
767  {
768  return m_traceBackBuffers[index];
769  }
770 
774  uint32_t currentIndex() const { return m_currentMemIndex; }
775 
779  QByteArray serialize() const
780  {
781  SimpleSerializer s(1);
782 
783  s.writeU32(1, m_memSize);
784  s.writeU32(2, m_currentMemIndex);
785  s.writeU32(3, m_traceSize);
786 
787  for (unsigned int i = 0; i < m_memSize; i++)
788  {
789  QByteArray buffer = m_traceBackBuffers[i].serialize();
790  s.writeBlob(100+i, buffer);
791  }
792 
793  return s.final();
794  }
795 
799  bool deserialize(const QByteArray& data)
800  {
801  SimpleDeserializer d(data);
802 
803  if(!d.isValid()) {
804  return false;
805  }
806 
807  if (d.getVersion() == 1)
808  {
809  d.readU32(1, &m_memSize, 0);
810  d.readU32(2, &m_currentMemIndex, 0);
811  uint32_t traceSize;
812  d.readU32(3, &traceSize, 0);
813  m_traceBackBuffers.resize(m_memSize);
814 
815  if (traceSize != m_traceSize) {
816  resize(traceSize);
817  }
818 
819  for (unsigned int i = 0; i < m_memSize; i++)
820  {
821  QByteArray buffer;
822  d.readBlob(100+i, &buffer);
823  m_traceBackBuffers[i].deserialize(buffer);
824  }
825 
826  return true;
827  }
828  else
829  {
830  return false;
831  }
832  }
833  };
834 
839  {
841  uint32_t m_traceCount[2];
842  double m_maxPow;
843  double m_sumPow;
844  int m_nbPow;
845 
846  TraceControl() : m_projector(Projector::ProjectionReal)
847  {
848  reset();
849  }
850 
852  {
853  }
854 
856  {
857  m_projector.settProjectionType(projectionType);
858  }
859 
861  {
862  }
863 
864  void reset()
865  {
866  m_traceCount[0] = 0;
867  m_traceCount[1] = 0;
868  m_maxPow = 0.0f;
869  m_sumPow = 0.0f;
870  m_nbPow = 0;
871  }
872  };
873 
874  struct Traces
875  {
876  std::vector<TraceControl*> m_tracesControl;
877  std::vector<TraceData> m_tracesData;
878  std::vector<float *> m_traces[2];
882 
883  Traces() :
884  m_traceSize(0),
885  m_maxTraceSize(0),
886  evenOddIndex(true),
887  m_x0(0),
888  m_x1(0)
889  {
890  }
891 
893  {
894  for (std::vector<TraceControl*>::iterator it = m_tracesControl.begin(); it != m_tracesControl.end(); ++it) {
895  delete *it;
896  }
897 
898  if (m_x0) {
899  delete[] m_x0;
900  }
901 
902  if (m_x1) {
903  delete[] m_x1;
904  }
905 
906  m_maxTraceSize = 0;
907  }
908 
909  bool isVerticalDisplayChange(const TraceData& traceData, uint32_t traceIndex)
910  {
911  return (m_tracesData[traceIndex].m_projectionType != traceData.m_projectionType)
912  || (m_tracesData[traceIndex].m_amp != traceData.m_amp)
913  || (m_tracesData[traceIndex].m_ofs != traceData.m_ofs
914  || (m_tracesData[traceIndex].m_traceColor != traceData.m_traceColor));
915  }
916 
917  void addTrace(const TraceData& traceData, int traceSize)
918  {
919  if (m_traces[0].size() < m_maxNbTraces)
920  {
921  qDebug("ScopeVis::addTrace");
922  m_traces[0].push_back(0);
923  m_traces[1].push_back(0);
924  m_tracesData.push_back(traceData);
925  m_tracesControl.push_back(new TraceControl());
926  TraceControl *traceControl = m_tracesControl.back();
927  traceControl->initProjector(traceData.m_projectionType);
928 
929  resize(traceSize);
930  }
931  }
932 
933  void changeTrace(const TraceData& traceData, uint32_t traceIndex)
934  {
935  if (traceIndex < m_tracesControl.size()) {
936  TraceControl *traceControl = m_tracesControl[traceIndex];
937  traceControl->releaseProjector();
938  traceControl->initProjector(traceData.m_projectionType);
939  m_tracesData[traceIndex] = traceData;
940  }
941  }
942 
943  void removeTrace(uint32_t traceIndex)
944  {
945  if (traceIndex < m_tracesControl.size())
946  {
947  qDebug("ScopeVis::removeTrace");
948  m_traces[0].erase(m_traces[0].begin() + traceIndex);
949  m_traces[1].erase(m_traces[1].begin() + traceIndex);
950  TraceControl *traceControl = m_tracesControl[traceIndex];
951  traceControl->releaseProjector();
952  m_tracesControl.erase(m_tracesControl.begin() + traceIndex);
953  m_tracesData.erase(m_tracesData.begin() + traceIndex);
954  delete traceControl;
955 
956  resize(m_traceSize); // reallocate pointers
957  }
958  }
959 
960  void moveTrace(uint32_t traceIndex, bool upElseDown)
961  {
962  if ((!upElseDown) && (traceIndex == 0)) {
963  return;
964  }
965 
966  int nextControlIndex = (traceIndex + (upElseDown ? 1 : -1)) % (m_tracesControl.size());
967  int nextDataIndex = (traceIndex + (upElseDown ? 1 : -1)) % (m_tracesData.size()); // should be the same
968 
969  TraceControl *traceControl = m_tracesControl[traceIndex];
970  TraceControl *nextTraceControl = m_tracesControl[nextControlIndex];
971 
972  traceControl->releaseProjector();
973  nextTraceControl->releaseProjector();
974 
975  m_tracesControl[nextControlIndex] = traceControl;
976  m_tracesControl[traceIndex] = nextTraceControl;
977 
978  TraceData nextData = m_tracesData[nextDataIndex];
979  m_tracesData[nextDataIndex] = m_tracesData[traceIndex];
980  m_tracesData[traceIndex] = nextData;
981 
982  traceControl = m_tracesControl[traceIndex];
983  nextTraceControl = m_tracesControl[nextControlIndex];
984 
985  traceControl->initProjector(m_tracesData[traceIndex].m_projectionType);
986  nextTraceControl->initProjector(m_tracesData[nextDataIndex].m_projectionType);
987  }
988 
989  void resize(int traceSize)
990  {
991  m_traceSize = traceSize;
992 
993  if (m_traceSize > m_maxTraceSize)
994  {
995  delete[] m_x0;
996  delete[] m_x1;
997  m_x0 = new float[2*m_traceSize*m_maxNbTraces];
998  m_x1 = new float[2*m_traceSize*m_maxNbTraces];
999 
1000  m_maxTraceSize = m_traceSize;
1001  }
1002 
1003  std::fill_n(m_x0, 2*m_traceSize*m_traces[0].size(), 0.0f);
1004  std::fill_n(m_x1, 2*m_traceSize*m_traces[0].size(), 0.0f);
1005 
1006  for (unsigned int i = 0; i < m_traces[0].size(); i++)
1007  {
1008  (m_traces[0])[i] = &m_x0[2*m_traceSize*i];
1009  (m_traces[1])[i] = &m_x1[2*m_traceSize*i];
1010  }
1011  }
1012 
1013  uint32_t currentBufferIndex() const { return evenOddIndex? 0 : 1; }
1014  uint32_t size() const { return m_tracesControl.size(); }
1015 
1017  {
1018  evenOddIndex = !evenOddIndex;
1019 
1020  for (std::vector<TraceControl*>::iterator it = m_tracesControl.begin(); it != m_tracesControl.end(); ++it)
1021  {
1022  (*it)->m_traceCount[currentBufferIndex()] = 0;
1023  }
1024  }
1025 
1026  private:
1027  float *m_x0;
1028  float *m_x1;
1029  };
1030 
1032  {
1033  public:
1034  TriggerComparator() : m_level(0), m_reset(true)
1035  {
1036  computeLevels();
1037  }
1038 
1039  bool triggered(const Sample& s, TriggerCondition& triggerCondition)
1040  {
1041  if (triggerCondition.m_triggerData.m_triggerLevel != m_level)
1042  {
1043  m_level = triggerCondition.m_triggerData.m_triggerLevel;
1044  computeLevels();
1045  }
1046 
1047  bool condition, trigger;
1048 
1049  if (triggerCondition.m_projector.getProjectionType() == Projector::ProjectionMagDB) {
1050  condition = triggerCondition.m_projector.run(s) > m_levelPowerDB;
1051  } else if (triggerCondition.m_projector.getProjectionType() == Projector::ProjectionMagLin) {
1052  condition = triggerCondition.m_projector.run(s) > m_levelPowerLin;
1053  } else {
1054  condition = triggerCondition.m_projector.run(s) > m_level;
1055  }
1056 
1057  if (condition)
1058  {
1059  if (triggerCondition.m_trues < triggerCondition.m_triggerData.m_triggerHoldoff) {
1060  condition = false;
1061  triggerCondition.m_trues++;
1062  } else {
1063  triggerCondition.m_falses = 0;
1064  }
1065  }
1066  else
1067  {
1068  if (triggerCondition.m_falses < triggerCondition.m_triggerData.m_triggerHoldoff) {
1069  condition = true;
1070  triggerCondition.m_falses++;
1071  } else {
1072  triggerCondition.m_trues = 0;
1073  }
1074  }
1075 
1076  if (m_reset)
1077  {
1078  triggerCondition.m_prevCondition = condition;
1079  m_reset = false;
1080  return false;
1081  }
1082 
1083  if (triggerCondition.m_triggerData.m_triggerBothEdges) {
1084  trigger = triggerCondition.m_prevCondition ? !condition : condition; // This is a XOR between bools
1085  } else if (triggerCondition.m_triggerData.m_triggerPositiveEdge) {
1086  trigger = !triggerCondition.m_prevCondition && condition;
1087  } else {
1088  trigger = triggerCondition.m_prevCondition && !condition;
1089  }
1090 
1091 // if (trigger) {
1092 // qDebug("ScopeVis::triggered: %s/%s %f/%f",
1093 // triggerCondition.m_prevCondition ? "T" : "F",
1094 // condition ? "T" : "F",
1095 // triggerCondition.m_projector->run(s),
1096 // triggerCondition.m_triggerData.m_triggerLevel);
1097 // }
1098 
1099  triggerCondition.m_prevCondition = condition;
1100  return trigger;
1101  }
1102 
1103  void reset()
1104  {
1105  m_reset = true;
1106  }
1107 
1108  private:
1110  {
1111  m_levelPowerLin = m_level + 1.0f;
1112  m_levelPowerDB = (100.0f * (m_level - 1.0f));
1113  }
1114 
1118  bool m_reset;
1119  };
1120 
1124  std::vector<TriggerCondition*> m_triggerConditions;
1141  bool m_freeRun;
1144  QMutex m_mutex;
1145  Real m_projectorCache[(int) Projector::nbProjectionTypes];
1149 
1155  bool nextTrigger();
1156 
1160  void processTrace(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, int& triggerPointToEnd);
1161 
1165  void processMemoryTrace();
1166 
1172  int processTraces(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool traceBack = false);
1173 
1177  void updateMaxTraceDelay();
1178 
1182  void initTraceBuffers();
1183 
1191  void computeDisplayTriggerLevels();
1192 
1198  void updateGLScopeDisplay();
1199 
1203  void setSampleRate(int sampleRate);
1204 
1208  void setTraceSize(uint32_t traceSize, bool emitSignal = false);
1209 
1213  void setPreTriggerDelay(uint32_t preTriggerDelay, bool emitSignal = false);
1214 };
1215 
1216 
1217 
1218 #endif /* SDRBASE_DSP_SCOPEVISNG_H_ */
MsgScopeVisNGMoveTrace(uint32_t traceIndex, bool moveUpElseDown)
Definition: scopevis.h:489
uint32_t m_triggerRepeat
Number of trigger conditions before the final decisive trigger.
Definition: scopevis.h:114
void resize(int size)
Definition: doublebuffer.h:59
void addTrace(const TraceData &traceData, int traceSize)
Definition: scopevis.h:917
const TraceData & getTraceData() const
Definition: scopevis.h:415
uint32_t currentBufferIndex() const
Definition: scopevis.h:1013
bool m_viewTrace
Trace visibility.
Definition: scopevis.h:67
void getTraceData(TraceData &traceData, uint32_t traceIndex)
Definition: scopevis.h:231
static MsgScopeVisNGChangeTrigger * create(const TriggerData &triggerData, uint32_t triggerIndex)
Definition: scopevis.h:318
bool m_triggerPositiveEdge
Trigger on the positive edge (else negative)
Definition: scopevis.h:107
MsgScopeVisNGAddTrace(const TraceData &traceData)
Definition: scopevis.h:420
static MsgScopeVisNGRemoveTrigger * create(uint32_t triggerIndex)
Definition: scopevis.h:342
void write(const SampleVector::const_iterator begin, const SampleVector::const_iterator end)
Definition: scopevis.h:653
double m_sumPow
Cumulative power over the current trace for MagDB overlay display.
Definition: scopevis.h:843
TraceBackDiscreteMemory(uint32_t size)
Definition: scopevis.h:713
MsgScopeVisNGFocusOnTrace(uint32_t traceIndex)
Definition: scopevis.h:511
std::vector< TraceControl * > m_tracesControl
Corresponding traces control data.
Definition: scopevis.h:876
uint32_t m_focusedTriggerIndex
Index of the trigger that has focus.
Definition: scopevis.h:1126
MsgConfigureScopeVisNG(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun)
Definition: scopevis.h:279
uint32_t getTraceIndex() const
Definition: scopevis.h:482
bool m_triggerWaitForReset
In one shot mode suspended until reset by UI.
Definition: scopevis.h:1147
int m_liveSampleRate
Sample rate in live mode.
Definition: scopevis.h:1138
MsgScopeVisNGChangeTrigger(const TriggerData &triggerData, uint32_t triggerIndex)
Definition: scopevis.h:331
std::vector< TraceData > m_tracesData
Corresponding traces data.
Definition: scopevis.h:877
Calculate logarithmic (dB) of squared magnitude.
Definition: projector.h:31
MsgScopeVisNGMoveTrigger(uint32_t triggerIndex, bool moveUpElseDown)
Definition: scopevis.h:377
const TriggerData & getTriggerData() const
Definition: scopevis.h:303
MsgScopeVisNGAddTrigger(const TriggerData &triggerData)
Definition: scopevis.h:308
TraceBackBuffer & current()
Definition: scopevis.h:758
QMutex m_mutex
Definition: scopevis.h:1144
QByteArray serializeMemory() const
Definition: scopevis.h:174
TraceBuffer m_traceBuffer
Definition: scopevis.h:635
SampleVector::iterator current()
Definition: scopevis.h:662
void writeBlob(quint32 id, const QByteArray &value)
double m_maxPow
Maximum power over the current trace for MagDB overlay display.
Definition: scopevis.h:842
void getTriggerData(TriggerData &triggerData, uint32_t triggerIndex)
Definition: scopevis.h:223
ProjectionType
Definition: projector.h:25
QColor m_traceColor
Trace display color.
Definition: scopevis.h:61
float m_traceColorR
Trace display color - red shortcut.
Definition: scopevis.h:62
std::vector< T >::const_iterator begin() const
Definition: doublebuffer.h:94
void setColor(QColor color)
Definition: scopevis.h:88
uint32_t currentIndex() const
Definition: scopevis.h:774
float m_triggerDisplayLevel
Displayable trigger display level in -1:+1 scale. Off scale if not displayable.
Definition: scopevis.h:60
bool readU32(quint32 id, quint32 *result, quint32 def=0) const
int m_focusedTraceIndex
Index of the trace that has focus.
Definition: scopevis.h:1129
float m_traceColorG
Trace display color - green shortcut.
Definition: scopevis.h:63
Trigger is not kicked off yet (or trigger list is empty)
Definition: scopevis.h:565
Gives the number of projections in the enum.
Definition: projector.h:38
std::vector< TraceBackBuffer > m_traceBackBuffers
Definition: scopevis.h:705
uint32_t m_timeOfsProMill
Start trace shift in 1/1000 trace size.
Definition: scopevis.h:1134
QString m_textOverlay
Text overlay to display.
Definition: scopevis.h:66
bool deserialize(const QByteArray &data)
Definition: doublebuffer.h:111
int m_traceSize
Current size of a trace in buffer.
Definition: scopevis.h:879
static MsgConfigureScopeVisNG * create(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun)
Definition: scopevis.h:256
Trigger conditions have been kicked off but it is waiting for delay before final kick off...
Definition: scopevis.h:567
bool deserialize(const QByteArray &data)
Definition: scopevis.h:799
bool isValid() const
int m_traceDelay
Trace delay in number of samples.
Definition: scopevis.h:57
unsigned int uint32_t
Definition: rtptypes_win.h:46
uint32_t size() const
Definition: scopevis.h:1014
static MsgScopeVisNGFocusOnTrace * create(uint32_t traceIndex)
Definition: scopevis.h:500
const TriggerData & getTriggerData() const
Definition: scopevis.h:324
bool m_prevCondition
Condition (above threshold) at previous sample.
Definition: scopevis.h:575
uint32_t m_trues
Count of true conditions for holdoff processing.
Definition: scopevis.h:578
#define SDRGUI_API
Definition: export.h:52
int m_traceDelayCoarse
Coarse delay slider value.
Definition: scopevis.h:58
static MsgScopeVisNGMoveTrigger * create(uint32_t triggerIndex, bool moveUpElseDown)
Definition: scopevis.h:363
int m_traceDelayFine
Fine delay slider value.
Definition: scopevis.h:59
uint32_t getTriggerPre() const
Definition: scopevis.h:269
float m_triggerColorR
Trigger line display color - red shortcut.
Definition: scopevis.h:116
uint32_t m_triggerCounter
Counter of trigger occurrences.
Definition: scopevis.h:577
static MsgScopeVisNGMoveTrace * create(uint32_t traceIndex, bool moveUpElseDown)
Definition: scopevis.h:475
bool readS32(quint32 id, qint32 *result, qint32 def=0) const
uint32_t m_traceSize
Size of traces in number of samples.
Definition: scopevis.h:1130
uint32_t m_livePreTriggerDelay
Pre-trigger delay in number of samples in live mode.
Definition: scopevis.h:1123
bool readBlob(quint32 id, QByteArray *result, const QByteArray &def=QByteArray()) const
uint32_t m_liveTraceSize
Size of traces in number of samples in live mode.
Definition: scopevis.h:1131
static MsgScopeVisNGFocusOnTrigger * create(uint32_t triggerIndex)
Definition: scopevis.h:388
GLScope * m_glScope
Definition: scopevis.h:1121
void setData(const TriggerData &triggerData)
Definition: scopevis.h:606
#define MESSAGE_CLASS_DECLARATION
Definition: message.h:43
bool m_triggerBothEdges
Trigger on both edges (else only one)
Definition: scopevis.h:108
int getTriggerLocation() const
Definition: scopevis.h:247
uint32_t m_triggerHoldoff
Trigger holdoff in number of samples.
Definition: scopevis.h:109
int m_liveLog2Decim
Sample rate decimation log2 in live mode.
Definition: scopevis.h:1139
static MsgScopeVisNGMemoryTrace * create(uint32_t memoryIndex)
Definition: scopevis.h:542
TraceBackBuffer & at(int index)
Definition: scopevis.h:766
float m_traceColorB
Trace display color - blue shortcut.
Definition: scopevis.h:64
uint32_t m_triggerDelayCount
Counter of samples for delay.
Definition: scopevis.h:576
MsgScopeVisNGRemoveTrace(uint32_t traceIndex)
Definition: scopevis.h:465
TraceBackBuffer & store(int samplesToReport)
Definition: scopevis.h:736
bool deserialize(const QByteArray &data)
Definition: scopevis.h:676
void write(const typename std::vector< T >::const_iterator &begin, const typename std::vector< T >::const_iterator &cend)
Definition: doublebuffer.h:66
QColor m_triggerColor
Trigger line display color.
Definition: scopevis.h:115
uint32_t m_timeBase
Trace display time divisor.
Definition: scopevis.h:1133
int m_triggerLocation
Trigger location from end point.
Definition: scopevis.h:1136
int m_maxTraceDelay
Maximum trace delay.
Definition: scopevis.h:1142
int32_t i
Definition: decimators.h:244
uint32_t m_currentTriggerIndex
Index of current index in the chain.
Definition: scopevis.h:1125
static MsgScopeVisNGOneShot * create(bool oneShot)
Definition: scopevis.h:521
bool deserializeMemory(const QByteArray &data)
Definition: scopevis.h:187
int m_ofsFine
Fine offset slider value.
Definition: scopevis.h:56
Real m_triggerLevel
Level in real units.
Definition: scopevis.h:104
uint32_t m_falses
Count of false conditions for holdoff processing.
Definition: scopevis.h:579
MsgScopeVisNGRemoveTrigger(uint32_t triggerIndex)
Definition: scopevis.h:353
Calculate linear magnitude or modulus.
Definition: projector.h:29
void operator=(const TriggerCondition &other)
Definition: scopevis.h:622
bool m_hasTextOverlay
True if a text overlay has to be displayed.
Definition: scopevis.h:65
void writeS32(quint32 id, qint32 value)
TriggerData m_triggerData
Trigger data.
Definition: scopevis.h:574
static MsgScopeVisNGChangeTrace * create(const TraceData &traceData, uint32_t traceIndex)
Definition: scopevis.h:430
quint32 getVersion() const
unsigned int absoluteFill() const
Definition: scopevis.h:658
void switchBuffer()
Definition: scopevis.h:1016
bool m_traceStart
Trace is at start point.
Definition: scopevis.h:1135
Projector::ProjectionType m_projectionType
Complex to real projection type.
Definition: scopevis.h:102
float m_amp
Amplification factor.
Definition: scopevis.h:52
static const uint32_t m_traceChunkSize
Definition: scopevis.h:150
void settProjectionType(ProjectionType projectionType)
Definition: projector.h:45
MsgScopeVisNGOneShot(bool oneShot)
Definition: scopevis.h:532
void resize(uint32_t size)
Definition: scopevis.h:721
void writeU32(quint32 id, quint32 value)
bool triggered(const Sample &s, TriggerCondition &triggerCondition)
Definition: scopevis.h:1039
uint32_t m_preTriggerDelay
Pre-trigger delay in number of samples.
Definition: scopevis.h:1122
Traces m_traces
Displayable traces.
Definition: scopevis.h:1128
bool evenOddIndex
Even (true) or odd (false) index.
Definition: scopevis.h:881
int m_maxTraceSize
Maximum Size of a trace in buffer.
Definition: scopevis.h:880
MsgScopeVisNGFocusOnTrigger(uint32_t triggerIndex)
Definition: scopevis.h:399
void changeTrace(const TraceData &traceData, uint32_t traceIndex)
Definition: scopevis.h:933
uint32_t getMemoryIndex() const
Definition: scopevis.h:548
uint32_t getTriggerIndex() const
Definition: scopevis.h:370
MsgScopeVisNGMemoryTrace(uint32_t memoryIndex)
Definition: scopevis.h:553
uint32_t getTimeBase() const
Definition: scopevis.h:267
SampleVector::iterator m_endPoint
Definition: scopevis.h:636
ProjectionType getProjectionType() const
Definition: projector.h:44
TraceBackBuffer & recall(uint32_t shift)
Definition: scopevis.h:749
uint32_t m_inputIndex
Input or feed index this trace is associated with.
Definition: scopevis.h:51
Trigger has been kicked off.
Definition: scopevis.h:566
int m_nbPow
Number of power samples over the current trace for MagDB overlay display.
Definition: scopevis.h:844
QByteArray serialize() const
Definition: scopevis.h:664
const TraceData & getTraceData() const
Definition: scopevis.h:436
uint32_t getNbTriggers() const
Definition: scopevis.h:241
static MsgScopeVisNGRemoveTrace * create(uint32_t traceIndex)
Definition: scopevis.h:454
DoubleBufferSimple< Sample > TraceBuffer
Definition: scopevis.h:631
Projector::ProjectionType m_projectionType
Complex to real projection type.
Definition: scopevis.h:50
uint32_t m_triggerDelay
Delay before the trigger is kicked off in number of samples (trigger delay)
Definition: scopevis.h:110
uint32_t getTraceSize() const
Definition: scopevis.h:266
int m_nbSamples
Number of samples yet to process in one complex trace.
Definition: scopevis.h:1132
void resize(int traceSize)
Definition: scopevis.h:989
uint32_t m_currentTraceMemoryIndex
The current index of trace in memory (0: current)
Definition: scopevis.h:1148
const std::vector< TraceData > & getTracesData() const
Definition: scopevis.h:240
static MsgScopeVisNGAddTrace * create(const TraceData &traceData)
Definition: scopevis.h:409
std::vector< TriggerCondition * > m_triggerConditions
Chain of triggers.
Definition: scopevis.h:1124
unsigned int absoluteFill() const
Definition: doublebuffer.h:96
void resize(uint32_t size)
Definition: scopevis.h:643
void moveTrace(uint32_t traceIndex, bool upElseDown)
Definition: scopevis.h:960
bool isVerticalDisplayChange(const TraceData &traceData, uint32_t traceIndex)
Definition: scopevis.h:909
void initProjector(Projector::ProjectionType projectionType)
Definition: scopevis.h:855
TriggerComparator m_triggerComparator
Compares sample level to trigger level.
Definition: scopevis.h:1143
uint32_t m_ampIndex
Index in list of amplification factors.
Definition: scopevis.h:53
TraceBackDiscreteMemory m_traceDiscreteMemory
Complex trace memory for triggered states TODO: vectorize when more than on input is allowed...
Definition: scopevis.h:1140
uint32_t m_inputIndex
Input or feed index this trigger is associated with.
Definition: scopevis.h:103
TriggerState m_triggerState
Current trigger state.
Definition: scopevis.h:1127
float Real
Definition: dsptypes.h:42
float m_triggerColorB
Trigger line display color - blue shortcut.
Definition: scopevis.h:118
uint32_t getTraceIndex() const
Definition: scopevis.h:460
const QByteArray & final()
float m_triggerColorG
Trigger line display color - green shortcut.
Definition: scopevis.h:117
bool m_triggerOneShot
True when one shot mode is active.
Definition: scopevis.h:1146
std::vector< T >::iterator getCurrent() const
Definition: doublebuffer.h:93
void setColor(QColor color)
Definition: scopevis.h:139
QByteArray serialize() const
Definition: scopevis.h:779
uint32_t getTraceIndex() const
Definition: scopevis.h:437
float m_ofs
Offset factor.
Definition: scopevis.h:54
int m_sampleRate
Actual sample rate being used.
Definition: scopevis.h:1137
uint32_t getTimeOfsProMill() const
Definition: scopevis.h:268
const TriggerData & getTriggerData(uint32_t triggerIndex) const
Definition: scopevis.h:239
static MsgScopeVisNGAddTrigger * create(const TriggerData &triggerData)
Definition: scopevis.h:297
TriggerState
Definition: scopevis.h:563
void removeTrace(uint32_t traceIndex)
Definition: scopevis.h:943
MsgScopeVisNGChangeTrace(TraceData traceData, uint32_t traceIndex)
Definition: scopevis.h:443
TriggerCondition(const TriggerData &triggerData)
Definition: scopevis.h:582
Projector m_projector
Projector transform from complex trace to real (displayable) trace.
Definition: scopevis.h:840
int m_ofsCoarse
Coarse offset slider value.
Definition: scopevis.h:55
bool m_freeRun
True if free running (trigger globally disabled)
Definition: scopevis.h:1141
Real run(const Sample &s)
Definition: projector.cpp:35
double m_triggerDelayMult
Trigger delay as a multiplier of trace length.
Definition: scopevis.h:111
QByteArray serialize() const
Definition: doublebuffer.h:99