summaryrefslogtreecommitdiff
path: root/gr-qtgui/src/lib/fftdisplay.cc
blob: d701642801ce974729bea6cff366e8aced7ac13b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef FFT_DISPLAY_CC
#define FFT_DISPLAY_CC

#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_engine.h>
#include <qapplication.h>
#include <fftdisplay.h>

const int fft_display_event::EVENT_TYPE_ID = QEvent::User+100;

fft_display_event::fft_display_event( std::vector<gr_complex>* fft_data, const float start_frequency, const float stop_frequency):QCustomEvent(fft_display_event::EVENT_TYPE_ID){
	d_fft_data.resize(fft_data->size());
	for(unsigned int i = 0; i < fft_data->size(); i++){
		d_fft_data[i] = fft_data->operator[](i);
	}
	d_start_frequency = start_frequency;
	d_stop_frequency = stop_frequency;
}

fft_display_event::~fft_display_event(){

}

const std::vector<gr_complex>& fft_display_event::get_fft_data() const{
	return d_fft_data;
}

float fft_display_event::get_start_frequency()const{
	return d_start_frequency;
}

float fft_display_event::get_stop_frequency()const{
	return d_stop_frequency;
}

fft_display::fft_display(const unsigned int fft_size, QWidget* parent):
	QwtPlot(parent)
{
    	// Disable polygon clipping
    	QwtPainter::setDeviceClipping(false);

    	// We don't need the cache here
    	canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
    	canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);

	canvas()->setPaletteBackgroundColor(QColor("white"));

	d_fft_bin_size = fft_size;
	if(d_fft_bin_size < 1){
		d_fft_bin_size = 1;
	}

	d_start_frequency = 0.0;
	d_stop_frequency = 4000.0;

	d_fft_data = new std::vector<gr_complex>(d_fft_bin_size);
	d_plot_data = new double[d_fft_bin_size];
	d_x_data = new double[d_fft_bin_size];
	for( unsigned int i = 0; i < d_fft_bin_size; i++){
		d_fft_data->operator[](i) = gr_complex(static_cast<float>(i), 0.0);
		d_x_data[i] = d_start_frequency + ((d_stop_frequency-d_start_frequency) / static_cast<float>(d_fft_bin_size)*static_cast<float>(i));
		d_plot_data[i] = 1.0;
	}
	
	// Set the Appropriate Axis Scale Engine
#warning Pass the axis info as necessary...
	if(true){
		setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
	}
	else{
		setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
	}

	QwtPlotCurve* fft_plot_curve = new QwtPlotCurve("FFT Spectrum");
	fft_plot_curve->attach(this);
	fft_plot_curve->setPen(QPen(Qt::blue));
	fft_plot_curve->setRawData(d_x_data, d_plot_data, d_fft_bin_size);

	setTitle("Spectral Display");
}

fft_display::~fft_display(){
	/* The Qwt objects are destroyed by Qt when their parent is destroyed */

	delete[] d_plot_data;
	delete[] d_x_data;
	delete d_fft_data;
}


void fft_display::set_data(const std::vector<gr_complex>& input_data){
	unsigned int min_points = d_fft_data->size();
	if(min_points < input_data.size()){
		min_points = input_data.size();
	}
	if(min_points > d_fft_bin_size){
		min_points = d_fft_bin_size;
	}
	for(unsigned int point = 0; point < min_points; point++){
		d_fft_data->operator[](point) = input_data[point];
	}
}

void fft_display::update_display(){

	// Tell the event loop to display the new data - the event loop handles deleting this object
	qApp->postEvent(this, new fft_display_event(d_fft_data, d_start_frequency, d_stop_frequency));

}

void fft_display::customEvent(QCustomEvent* e){
	if(e->type() == fft_display_event::EVENT_TYPE_ID){
		fft_display_event* fft_display_event_ptr = (fft_display_event*)e;
		// Write out the FFT data to the display here

		gr_complex data_value;
		for(unsigned int number = 0; number < fft_display_event_ptr->get_fft_data().size(); number++){
			data_value = fft_display_event_ptr->get_fft_data()[number];
			d_plot_data[number] = abs(data_value);
#warning Add code here for handling magnitude, scaling, etc...

			d_x_data[number] = d_start_frequency + ((d_stop_frequency-d_start_frequency) / static_cast<float>(d_fft_bin_size)*static_cast<float>(number));
		}

    		// Axis 
    		setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
    		setAxisScale(QwtPlot::xBottom, fft_display_event_ptr->get_start_frequency(), fft_display_event_ptr->get_stop_frequency());

    		setAxisTitle(QwtPlot::yLeft, "Values");
		replot();
	}
}

void fft_display::set_start_frequency(const float new_freq){
	d_start_frequency = new_freq;
}

float fft_display::get_start_frequency()const{
	return d_start_frequency;
}

void fft_display::set_stop_frequency(const float new_freq){
	d_stop_frequency = new_freq;
}

float fft_display::get_stop_frequency()const{
	return d_stop_frequency;
}

unsigned int fft_display::get_fft_bin_size()const{
	return d_fft_bin_size;
}


#endif /* FFT_DISPLAY_CC */