Statistics
| Branch: | Tag: | Revision:

root / gr-qtgui / lib / waterfalldisplayform.cc @ 582dc9b9

History | View | Annotate | Download (5.1 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2012 Free Software Foundation, Inc.
4
 *
5
 * This file is part of GNU Radio
6
 *
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 *
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with GNU Radio; see the file COPYING.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street,
20
 * Boston, MA 02110-1301, USA.
21
 */
22
23
#include <cmath>
24
#include <QColorDialog>
25
#include <QMessageBox>
26
#include <waterfalldisplayform.h>
27
#include <iostream>
28
29
WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
30
  : DisplayForm(nplots, parent)
31
{
32
  _intValidator = new QIntValidator(this);
33
  _intValidator->setBottom(0);
34
35
  _layout = new QGridLayout(this);
36
  _displayPlot = new WaterfallDisplayPlot(nplots, this);
37
  _layout->addWidget(_displayPlot, 0, 0);
38
  setLayout(_layout);
39
40
  _numRealDataPoints = 1024;
41
  _fftsize = 1024;
42
  _fftavg = 1.0;
43
44
  _min_val =  1000;
45
  _max_val = -1000;
46
47
  QAction *autoscale_act = new QAction("Auto Scale", this);
48
  autoscale_act->setStatusTip(tr("Autoscale intensity range"));
49
  connect(autoscale_act, SIGNAL(triggered()), this, SLOT(AutoScale()));
50
51
  FFTSizeMenu *sizemenu = new FFTSizeMenu(this);
52
  FFTAverageMenu *avgmenu = new FFTAverageMenu(this);
53
  FFTWindowMenu *winmenu = new FFTWindowMenu(this);
54
  _menu->addMenu(sizemenu);
55
  _menu->addMenu(avgmenu);
56
  _menu->addMenu(winmenu);
57
  _menu->addAction(autoscale_act);
58
  connect(sizemenu, SIGNAL(whichTrigger(int)),
59
          this, SLOT(SetFFTSize(const int)));
60
  connect(avgmenu, SIGNAL(whichTrigger(float)),
61
          this, SLOT(SetFFTAverage(const float)));
62
  connect(winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
63
          this, SLOT(SetFFTWindowType(const gr::filter::firdes::win_type)));
64
65
  Reset();
66
67
  connect(_displayPlot, SIGNAL(plotPointSelected(const QPointF)),
68
          this, SLOT(onPlotPointSelected(const QPointF)));
69
}
70
71
WaterfallDisplayForm::~WaterfallDisplayForm()
72
{
73
  // Qt deletes children when parent is deleted
74
75
  // Don't worry about deleting Display Plots - they are deleted when parents are deleted
76
  delete _intValidator;
77
}
78
79
WaterfallDisplayPlot*
80
WaterfallDisplayForm::getPlot()
81
{
82
  return ((WaterfallDisplayPlot*)_displayPlot);
83
}
84
85
void
86
WaterfallDisplayForm::newData(const QEvent *updateEvent)
87
{
88
  WaterfallUpdateEvent *event = (WaterfallUpdateEvent*)updateEvent;
89
  const std::vector<double*> dataPoints = event->getPoints();
90
  const uint64_t numDataPoints = event->getNumDataPoints();
91
  const gruel::high_res_timer_type dataTimestamp = event->getDataTimestamp();
92
93
  _min_val =  1000;
94
  _max_val = -1000;
95
  for(size_t i=0; i < dataPoints.size(); i++) {
96
    double *min_val = std::min_element(&dataPoints[i][0], &dataPoints[i][numDataPoints-1]);
97
    double *max_val = std::max_element(&dataPoints[i][0], &dataPoints[i][numDataPoints-1]);
98
    if(*min_val < _min_val)
99
      _min_val = *min_val;
100
    if(*max_val > _max_val)
101
      _max_val = *max_val;
102
  }
103
104
  getPlot()->PlotNewData(dataPoints, numDataPoints,
105
                         d_update_time, dataTimestamp, 0);
106
}
107
108
void
109
WaterfallDisplayForm::customEvent( QEvent * e)
110
{
111
  if(e->type() == WaterfallUpdateEvent::Type()) {
112
    newData(e);
113
  }
114
}
115
116
int
117
WaterfallDisplayForm::GetFFTSize() const
118
{
119
  return _fftsize;
120
}
121
122
float
123
WaterfallDisplayForm::GetFFTAverage() const
124
{
125
  return _fftavg;
126
}
127
128
gr::filter::firdes::win_type
129
WaterfallDisplayForm::GetFFTWindowType() const
130
{
131
  return _fftwintype;
132
}
133
134
void
135
WaterfallDisplayForm::SetFFTSize(const int newsize)
136
{
137
  _fftsize = newsize;
138
}
139
140
void
141
WaterfallDisplayForm::SetFFTAverage(const float newavg)
142
{
143
  _fftavg = newavg;
144
}
145
146
void
147
WaterfallDisplayForm::SetFFTWindowType(const gr::filter::firdes::win_type newwin)
148
{
149
  _fftwintype = newwin;
150
}
151
152
void
153
WaterfallDisplayForm::SetFrequencyRange(const double newCenterFrequency,
154
                                        const double newStartFrequency,
155
                                        const double newStopFrequency)
156
{
157
  double fdiff = std::max(fabs(newStartFrequency), fabs(newStopFrequency));
158
159
  if(fdiff > 0) {
160
    std::string strunits[4] = {"Hz", "kHz", "MHz", "GHz"};
161
    double units10 = floor(log10(fdiff));
162
    double units3  = std::max(floor(units10 / 3.0), 0.0);
163
    double units = pow(10, (units10-fmod(units10, 3.0)));
164
    int iunit = static_cast<int>(units3);
165
166
    _startFrequency = newStartFrequency;
167
    _stopFrequency = newStopFrequency;
168
    double centerFrequency = newCenterFrequency;
169
170
    getPlot()->SetFrequencyRange(_startFrequency,
171
                                 _stopFrequency,
172
                                 centerFrequency,
173
                                 true,
174
                                 units, strunits[iunit]);
175
  }
176
}
177
178
void
179
WaterfallDisplayForm::SetIntensityRange(const double minIntensity,
180
                                        const double maxIntensity)
181
{
182
  getPlot()->SetIntensityRange(minIntensity, maxIntensity);
183
}
184
185
void
186
WaterfallDisplayForm::AutoScale()
187
{
188
  double min_int = _min_val - 5;
189
  double max_int = _max_val + 10;
190
191
  getPlot()->SetIntensityRange(min_int, max_int);
192
}