SoDaRadio-5.0.3-master:8901fb5
soda_spect.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017 Matthew H. Reilly (kb1vc)
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "soda_spect.hpp"
30 #include <iostream>
31 #include <boost/format.hpp>
32 #include <cmath>
33 
34 #include <qwt/qwt_plot_grid.h>
35 #include <qwt/qwt_scale_engine.h>
36 
37 
38 
39 GUISoDa::Spect::Spect(QWidget *parent) :
40  QwtPlot(parent)
41 {
42  initPlot();
43 }
44 
46 {
47  if(freqs != NULL) delete[] freqs;
48  if(vals != NULL) delete[] vals;
49  num_buckets = 0;
50 }
51 
52 
54 {
55 
56  freq_span_disp = 10e3;
57  val_ref = 10.0;
58 
59  num_buckets = 0;
60  freqs = NULL;
61  vals = NULL;
62 
63  setCanvasBackground(Qt::black);
64  //QwtLinearScaleEngine se;
65  //setAxisScaleDiv(QwtPlot::xBottom, se.divideScale(144.1e6,144.2e6,10,5));
66  enableAxis(QwtPlot::xBottom, true);
67  enableAxis(QwtPlot::yLeft, true);
68  enableAxis(QwtPlot::yRight, true);
69 
70  freq_draw_p = new FreqScaleDraw();
71  setAxisScaleDraw(QwtPlot::xBottom, freq_draw_p);
72 
73  setFreqCenter(144.15e6);
74  setRefLevel(20);
75 
76  curve_p = new QwtPlotCurve();
77  curve_p->attach(this);
78 
79  grid_p = new QwtPlotGrid();
80  grid_p->setPen(Qt::gray);
81  grid_p->attach(this);
82 
83  curve_p->setPen(Qt::red);
84  // curve_p->setSamples(xdat, ydat, 1000);
85 
86  // setup the plotpicker -- this creates click events for us.
87  picker_p = new GUISoDa::PlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, canvas());
88 
89  connect(picker_p, SIGNAL(selected(const QPointF&)), SLOT(pickPoint(const QPointF&)));
90 
91  QColor fcol = Qt::green;
92  fcol.setAlpha(96);
93  freq_marker.setBrush(fcol);
94  freq_marker.setPen(fcol);
95  // make a dummy marker
96  freq_marker.setRect(QRectF(1.0, -100.0, 2.0, 100.0));
97  freq_marker.attach(this);
98  replot();
99  show();
100 }
101 
102 void GUISoDa::Spect::updateData(double cfreq, float * y)
103 {
104  if(cfreq != center_freq_in) resetFreqAxis(cfreq);
105  for(int i = 0; i < num_buckets; i++) vals[i] = y[i];
106  curve_p->setSamples(freqs, vals, num_buckets);
107  replot();
108 }
109 
111 {
112  val_ref = ((double) rlvl);
113  replotYAxis();
114 }
115 
117 {
118  val_range = drange;
119  replotYAxis();
120 }
121 
123 {
124  double y_min = val_ref - val_range;
125  double y_step = 5.0;
126  if(val_range < 25.1) y_step = 2.5;
127  if(val_range < 10.1) y_step = 1.0;
128  setAxisScale(QwtPlot::yLeft, y_min, val_ref, y_step);
129  setAxisScale(QwtPlot::yRight, y_min, val_ref, y_step);
130  replot();
131 }
132 
133 
135 {
136  double min = center_freq_disp - freq_span_disp * 0.5;
137  double max = center_freq_disp + freq_span_disp * 0.5;
138 
139 
140  setAxisScale(QwtPlot::xBottom, min, max, freq_span_disp / 5.0); // step);
141 
142  QwtLinearScaleEngine se;
143  setAxisScaleDiv(QwtPlot::xBottom, se.divideScale(min, max, 5, 5));
145  replot();
146 }
147 
148 void GUISoDa::Spect::setFreqCenter(double cf, bool check_boundary)
149 {
150  (void) check_boundary;
151  center_freq_disp = cf;
152  replotXAxis();
153 }
154 
155 
157 {
158  if((cfreq + 0.5 * freq_span_disp) > (center_freq_in + 0.5 * freq_span_in)) {
159  cfreq = (center_freq_in + 0.5 * (freq_span_in - freq_span_disp));
160  }
161  if((cfreq - 0.5 * freq_span_disp) < (center_freq_in - 0.5 * freq_span_in)) {
162  cfreq = (center_freq_in - 0.5 * (freq_span_in - freq_span_disp));
163  }
164  return cfreq;
165 }
166 
167 void GUISoDa::Spect::setFreqSpan(double fs, bool check_boundary) {
168  freq_span_disp = fs;
169  if(check_boundary) {
171  if((marker_freq < (center_freq_disp - 0.5 * freq_span_disp)) ||
174  }
175  }
176  replotXAxis();
177 }
178 
179 
180 void GUISoDa::Spect::pickPoint(const QPointF & pos)
181 {
182  double freq = pos.x() - marker_lo_offset;
183  setFreqMarker(freq);
184  emit xClick(freq);
185 }
186 
187 void GUISoDa::Spect::setMarkerOffset(double lo, double hi) {
188  marker_lo_offset = lo;
189  marker_hi_offset = hi;
191 }
192 
193 
195 {
196  double f = freq + marker_lo_offset;
197  double width = marker_hi_offset - marker_lo_offset;
198  freq_marker.setRect(QRectF(f, -200.0, width, 300.0));
199 
200  marker_freq = freq;
201  replot();
202 }
203 
204 void GUISoDa::Spect::resetFreqAxis(double cfreq) {
205  // load up the X axis values. (frequency)
206  double fincr = freq_span_in / ((double) (num_buckets-1));
207  double fr = cfreq - 0.5 * freq_span_in;
208  for(int i = 0; i < num_buckets; i++) {
209  freqs[i] = fr;
210  fr += fincr;
211  }
212 }
213 
214 void GUISoDa::Spect::configureSpectrum(double cfreq, double span, long buckets) {
215  marker_freq = cfreq;
216  center_freq_in = cfreq;
217  freq_span_in = span;
218  if(num_buckets < buckets) {
219  if(freqs != NULL) delete[] freqs;
220  if(vals != NULL) delete[] vals;
221  freqs = new double[buckets];
222  vals = new double[buckets];
223  num_buckets = buckets;
224  }
225 
226  resetFreqAxis(cfreq);
227  // load up the Y axis values.
228  for(int i = 0; i < num_buckets; i++) {
229  vals[i] = -200.0;
230  }
231 
232  // set the center display frequency and span.
233  setFreqCenter(cfreq);
234  // setFreqSpan(200.0e3); // default span.
235 }
void updateData(double cfreq, float *y)
Definition: soda_spect.cpp:102
QwtPlotShapeItem freq_marker
Definition: soda_spect.hpp:130
double marker_freq
Definition: soda_spect.hpp:120
double freq_span_disp
Definition: soda_spect.hpp:109
void replotXAxis()
Definition: soda_spect.cpp:134
double center_freq_in
Definition: soda_spect.hpp:103
FreqScaleDraw * freq_draw_p
Definition: soda_spect.hpp:122
void setFreqStep(double cf, double st)
void setFreqCenter(double cf, bool check_boundary=false)
Definition: soda_spect.cpp:148
void setMarkerOffset(double lo, double hi)
Definition: soda_spect.cpp:187
void setFreqMarker(double f)
Definition: soda_spect.cpp:194
double * vals
Definition: soda_spect.hpp:98
Spect(QWidget *parent=0)
Definition: soda_spect.cpp:39
void setDynamicRange(double drange)
Definition: soda_spect.cpp:116
double marker_hi_offset
Definition: soda_spect.hpp:117
QwtPlotCurve * curve_p
Definition: soda_spect.hpp:124
void replotYAxis()
Definition: soda_spect.cpp:122
void setRefLevel(int rlvl)
Definition: soda_spect.cpp:110
PlotPicker * picker_p
Definition: soda_spect.hpp:126
void xClick(double x)
double marker_lo_offset
Definition: soda_spect.hpp:116
double center_freq_disp
Definition: soda_spect.hpp:108
double correctCenterFreq(double cfreq)
Definition: soda_spect.cpp:156
void setFreqSpan(double fs, bool check_boundary=false)
Definition: soda_spect.cpp:167
void configureSpectrum(double cfreq, double span, long buckets)
Definition: soda_spect.cpp:214
void pickPoint(const QPointF &pos)
Definition: soda_spect.cpp:180
double freq_span_in
Definition: soda_spect.hpp:104
QwtPlotGrid * grid_p
Definition: soda_spect.hpp:128
void resetFreqAxis(double cfreq)
Definition: soda_spect.cpp:204
double * freqs
Definition: soda_spect.hpp:97