benoitrigolleau@211
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
benoitrigolleau@211
|
2
|
benoitrigolleau@211
|
3 /* Sound Access
|
benoitrigolleau@211
|
4 EASAIER client application.
|
benoitrigolleau@211
|
5 Silogic 2007. Benoit Rigolleau.
|
benoitrigolleau@211
|
6
|
benoitrigolleau@211
|
7 This program is free software; you can redistribute it and/or
|
benoitrigolleau@211
|
8 modify it under the terms of the GNU General Public License as
|
benoitrigolleau@211
|
9 published by the Free Software Foundation; either version 2 of the
|
benoitrigolleau@211
|
10 License, or (at your option) any later version. See the file
|
benoitrigolleau@211
|
11 COPYING included with this distribution for more information.
|
benoitrigolleau@211
|
12 */
|
benoitrigolleau@211
|
13
|
benoitrigolleau@211
|
14 #include "Plotter.h"
|
benoitrigolleau@231
|
15 #include <math.h>
|
benoitrigolleau@211
|
16 #include <QtGui>
|
benoitrigolleau@211
|
17
|
benoitrigolleau@211
|
18 Plotter::Plotter(QWidget *parent):
|
benoitrigolleau@211
|
19 m_signalWidth(400),
|
lbajardsilogic@233
|
20 m_signalHeight(120),
|
benoitrigolleau@211
|
21 m_margin(5),
|
lbajardsilogic@235
|
22 m_curveMaskActive(false),
|
lbajardsilogic@235
|
23 m_enableDrawCurve(false)
|
benoitrigolleau@211
|
24 {
|
lbajardsilogic@229
|
25 //m_curveMask = new int[m_signalWidth];
|
benoitrigolleau@211
|
26 for(int i = 0 ; i < m_signalWidth ; i++){
|
lbajardsilogic@229
|
27 m_curveMask.push_back(0);
|
benoitrigolleau@211
|
28 }
|
benoitrigolleau@240
|
29 m_oldCurveMask = m_curveMask;
|
benoitrigolleau@211
|
30
|
benoitrigolleau@240
|
31 setMinimumSize(QSize(m_signalWidth + 2*m_margin, m_signalHeight + 2*m_margin + 10));
|
benoitrigolleau@211
|
32
|
benoitrigolleau@211
|
33 refreshPixmap();
|
benoitrigolleau@211
|
34
|
benoitrigolleau@211
|
35 }
|
benoitrigolleau@211
|
36
|
benoitrigolleau@211
|
37 void Plotter::setCurveData(const QVector<QPoint> &data){
|
benoitrigolleau@211
|
38 m_curve = data;
|
benoitrigolleau@211
|
39 refreshPixmap();
|
benoitrigolleau@211
|
40 }
|
benoitrigolleau@211
|
41
|
lbajardsilogic@229
|
42 void Plotter::setCurve(float * curve)
|
lbajardsilogic@229
|
43 {
|
lbajardsilogic@229
|
44 m_curve.clear();
|
benoitrigolleau@231
|
45 for (int i=0; i< m_signalWidth; i++)
|
lbajardsilogic@229
|
46 {
|
lbajardsilogic@233
|
47 int m = m_signalHeight*2/3 +(int) floor(curve[i]/0.1);
|
lbajardsilogic@233
|
48 m_curve.push_back(QPoint(i, m));
|
lbajardsilogic@229
|
49 }
|
lbajardsilogic@229
|
50 refreshPixmap();
|
lbajardsilogic@229
|
51 }
|
lbajardsilogic@229
|
52
|
benoitrigolleau@211
|
53 void Plotter::clearCurve(){
|
benoitrigolleau@211
|
54 m_curve.clear();
|
benoitrigolleau@211
|
55 refreshPixmap();
|
benoitrigolleau@211
|
56 }
|
benoitrigolleau@211
|
57
|
benoitrigolleau@211
|
58 void Plotter::paintEvent(QPaintEvent *event){
|
benoitrigolleau@211
|
59 QStylePainter painter(this);
|
benoitrigolleau@211
|
60 painter.drawPixmap(0, 0, m_pixmap);
|
benoitrigolleau@211
|
61 }
|
benoitrigolleau@211
|
62
|
benoitrigolleau@211
|
63 void Plotter::resizeEvent(QResizeEvent *event){
|
benoitrigolleau@211
|
64 refreshPixmap();
|
benoitrigolleau@211
|
65 }
|
benoitrigolleau@211
|
66
|
benoitrigolleau@211
|
67 void Plotter::mousePressEvent(QMouseEvent *event){
|
benoitrigolleau@211
|
68 QRect rect(m_margin, m_margin,
|
benoitrigolleau@239
|
69 m_signalWidth , m_signalHeight );
|
benoitrigolleau@211
|
70
|
lbajardsilogic@235
|
71 if (m_enableDrawCurve)
|
lbajardsilogic@235
|
72 {
|
lbajardsilogic@235
|
73 if (event->button() == Qt::LeftButton) {
|
lbajardsilogic@235
|
74 if (rect.contains(event->pos())) {
|
lbajardsilogic@235
|
75 m_curveMaskActive = true;
|
lbajardsilogic@235
|
76 int x = event->pos().x()- m_margin;
|
lbajardsilogic@235
|
77 int y = event->pos().y()- m_margin;
|
lbajardsilogic@235
|
78 m_curveMask[x] = y;
|
lbajardsilogic@235
|
79 m_lastPoint.setX(x);
|
lbajardsilogic@235
|
80 m_lastPoint.setY(y);
|
lbajardsilogic@235
|
81 setCursor(Qt::CrossCursor);
|
lbajardsilogic@235
|
82 refreshPixmap();
|
lbajardsilogic@235
|
83 }
|
lbajardsilogic@235
|
84 }
|
lbajardsilogic@235
|
85 }
|
benoitrigolleau@211
|
86 }
|
benoitrigolleau@211
|
87
|
benoitrigolleau@211
|
88 void Plotter::mouseMoveEvent(QMouseEvent *event){
|
benoitrigolleau@211
|
89 QRect rect(m_margin, m_margin,
|
benoitrigolleau@239
|
90 m_signalWidth , m_signalHeight);
|
benoitrigolleau@211
|
91
|
lbajardsilogic@235
|
92 if (m_enableDrawCurve)
|
lbajardsilogic@235
|
93 {
|
lbajardsilogic@235
|
94 if(m_curveMaskActive && rect.contains(event->pos())){
|
lbajardsilogic@235
|
95 int x = event->pos().x() - m_margin;
|
lbajardsilogic@235
|
96 int y = event->pos().y() - m_margin;
|
lbajardsilogic@235
|
97 if(y>m_signalHeight-1)
|
lbajardsilogic@235
|
98 y= m_signalHeight-1;
|
lbajardsilogic@235
|
99 if(x>m_signalWidth-1)
|
lbajardsilogic@235
|
100 y= m_signalWidth-1;
|
lbajardsilogic@235
|
101 int xlast = m_lastPoint.x();
|
lbajardsilogic@235
|
102 int ylast = m_lastPoint.y();
|
benoitrigolleau@211
|
103
|
lbajardsilogic@235
|
104 //regul mask curve
|
lbajardsilogic@235
|
105 int minx, maxx, miny, maxy;
|
lbajardsilogic@235
|
106 if(x>xlast){
|
lbajardsilogic@235
|
107 minx = xlast;
|
lbajardsilogic@235
|
108 maxx = x;
|
lbajardsilogic@235
|
109 }else{
|
lbajardsilogic@235
|
110 minx = x;
|
lbajardsilogic@235
|
111 maxx = xlast;
|
lbajardsilogic@235
|
112 }
|
lbajardsilogic@235
|
113 if(y>ylast){
|
lbajardsilogic@235
|
114 miny = ylast;
|
lbajardsilogic@235
|
115 maxy = y;
|
lbajardsilogic@235
|
116 }else{
|
lbajardsilogic@235
|
117 miny = y;
|
lbajardsilogic@235
|
118 maxy = ylast;
|
lbajardsilogic@235
|
119 }
|
benoitrigolleau@211
|
120
|
lbajardsilogic@235
|
121 if((maxx - minx)>1){
|
lbajardsilogic@235
|
122 double incr = (double)(maxy - miny)/(double)(maxx - minx);
|
lbajardsilogic@235
|
123 if(x>xlast){
|
lbajardsilogic@235
|
124 for (int i = xlast + 1 ; i < x ; i++){
|
lbajardsilogic@235
|
125 if(ylast > y){
|
lbajardsilogic@235
|
126 m_curveMask[i] = ylast - (i-xlast)*incr;
|
lbajardsilogic@235
|
127 }else{
|
lbajardsilogic@235
|
128 m_curveMask[i] = ylast + (i-xlast)*incr;
|
lbajardsilogic@235
|
129 }
|
benoitrigolleau@211
|
130 }
|
lbajardsilogic@235
|
131 }else{
|
lbajardsilogic@235
|
132 for (int i = xlast - 1 ; i > x ; i--){
|
lbajardsilogic@235
|
133 if(ylast > y){
|
lbajardsilogic@235
|
134 m_curveMask[i] = ylast + (i-xlast)*incr;
|
lbajardsilogic@235
|
135 }else{
|
lbajardsilogic@235
|
136 m_curveMask[i] = ylast - (i-xlast)*incr;
|
lbajardsilogic@235
|
137 }
|
benoitrigolleau@211
|
138 }
|
benoitrigolleau@211
|
139 }
|
benoitrigolleau@211
|
140 }
|
lbajardsilogic@235
|
141 m_curveMask[x] = y;
|
lbajardsilogic@235
|
142 m_lastPoint.setX(x);
|
lbajardsilogic@235
|
143 m_lastPoint.setY(y);
|
lbajardsilogic@235
|
144 refreshPixmap();
|
benoitrigolleau@240
|
145 emit filterChanged(m_curveMask);
|
benoitrigolleau@211
|
146 }
|
benoitrigolleau@211
|
147 }
|
benoitrigolleau@211
|
148 }
|
benoitrigolleau@211
|
149
|
benoitrigolleau@211
|
150 void Plotter::mouseReleaseEvent(QMouseEvent *event){
|
lbajardsilogic@235
|
151 if (m_enableDrawCurve)
|
lbajardsilogic@235
|
152 {
|
lbajardsilogic@235
|
153 if ((event->button() == Qt::LeftButton) && m_curveMaskActive) {
|
lbajardsilogic@235
|
154 m_curveMaskActive = false;
|
lbajardsilogic@235
|
155 unsetCursor();
|
benoitrigolleau@240
|
156 //emit filterChanged(m_curveMask);
|
lbajardsilogic@235
|
157 }
|
lbajardsilogic@235
|
158 }
|
benoitrigolleau@211
|
159 }
|
benoitrigolleau@211
|
160
|
benoitrigolleau@211
|
161 void Plotter::drawGrid(QPainter *painter){
|
benoitrigolleau@211
|
162 QPixmap pm(":icons/grid.png");
|
benoitrigolleau@240
|
163 painter->setPen(Qt::white);
|
benoitrigolleau@211
|
164 painter->drawPixmap(0,0,pm);
|
benoitrigolleau@240
|
165
|
benoitrigolleau@240
|
166
|
benoitrigolleau@240
|
167 /**VLines **************/
|
benoitrigolleau@240
|
168
|
benoitrigolleau@240
|
169 // middle line
|
benoitrigolleau@240
|
170 painter->drawLine(m_signalWidth/2+m_margin, m_margin, m_signalWidth/2+m_margin , m_signalHeight + m_margin);
|
benoitrigolleau@240
|
171 //quater lines
|
benoitrigolleau@240
|
172 painter->drawLine(m_signalWidth/4+m_margin, m_margin, m_signalWidth/4+m_margin , m_signalHeight + m_margin);
|
benoitrigolleau@240
|
173 painter->drawLine(3*m_signalWidth/4+m_margin, m_margin, 3*m_signalWidth/4+m_margin , m_signalHeight + m_margin);
|
benoitrigolleau@240
|
174
|
benoitrigolleau@240
|
175 // border lines
|
benoitrigolleau@240
|
176 painter->drawLine(m_margin, m_margin, m_margin , m_signalHeight + m_margin);
|
benoitrigolleau@240
|
177 painter->drawLine(m_signalWidth+m_margin, m_margin, m_signalWidth+m_margin , m_signalHeight + m_margin);
|
benoitrigolleau@240
|
178
|
benoitrigolleau@240
|
179 /** HLines *************/
|
benoitrigolleau@240
|
180
|
benoitrigolleau@240
|
181
|
benoitrigolleau@240
|
182 /** Labels *************/
|
benoitrigolleau@240
|
183 painter->setPen(Qt::darkGray);
|
benoitrigolleau@240
|
184 painter->drawText(0, m_signalHeight+2*m_margin+10, "10Hz");
|
benoitrigolleau@240
|
185 painter->drawText(m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "100Hz");
|
benoitrigolleau@240
|
186 painter->drawText(m_signalWidth/2 -10, m_signalHeight+2*m_margin+10, "1000Hz");
|
benoitrigolleau@240
|
187 painter->drawText(3*m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "10000Hz");
|
benoitrigolleau@240
|
188 painter->drawText(m_signalWidth -22, m_signalHeight+2*m_margin+10, "22KHz");
|
benoitrigolleau@240
|
189
|
benoitrigolleau@240
|
190
|
benoitrigolleau@211
|
191 }
|
benoitrigolleau@211
|
192
|
benoitrigolleau@211
|
193 void Plotter::drawCurve(QPainter *painter){
|
benoitrigolleau@231
|
194 //painter->setRenderHint (QPainter::Antialiasing, true );
|
benoitrigolleau@211
|
195 QPolygonF polyline(m_signalWidth);
|
benoitrigolleau@231
|
196
|
benoitrigolleau@211
|
197 for(int i = 0 ; i < m_curve.count() ; i++){
|
lbajardsilogic@233
|
198 int m = m_curve.at(i).y(); // Calculates pixel coordinate and Plots FFT (in green)
|
benoitrigolleau@231
|
199 if (m>m_signalHeight){m = m_signalHeight;}
|
benoitrigolleau@231
|
200 if (m<0){m = 0;}
|
benoitrigolleau@231
|
201 int y= m_signalHeight - m;
|
benoitrigolleau@231
|
202 polyline[i] = QPoint(m_curve.at(i).x() + m_margin, /*m_curve.at(i).y()*/y + m_margin);
|
benoitrigolleau@211
|
203 }
|
benoitrigolleau@231
|
204
|
benoitrigolleau@211
|
205 painter->setPen(Qt::green);
|
benoitrigolleau@211
|
206 painter->drawPolyline(polyline);
|
benoitrigolleau@239
|
207
|
benoitrigolleau@211
|
208 }
|
benoitrigolleau@211
|
209
|
benoitrigolleau@211
|
210 void Plotter::drawMaskCurve(QPainter *painter){
|
benoitrigolleau@211
|
211
|
benoitrigolleau@220
|
212 painter->setRenderHint (QPainter::Antialiasing, true );
|
benoitrigolleau@220
|
213
|
benoitrigolleau@211
|
214 QPolygonF polyline(m_signalWidth);
|
benoitrigolleau@211
|
215
|
benoitrigolleau@211
|
216 for(int i = 0 ; i < m_signalWidth ; i++){
|
benoitrigolleau@211
|
217 polyline[i] = QPoint(i+m_margin, m_curveMask[i]+m_margin);
|
benoitrigolleau@211
|
218 }
|
benoitrigolleau@211
|
219 painter->setPen(Qt::red);
|
benoitrigolleau@211
|
220 painter->drawPolyline(polyline);
|
benoitrigolleau@211
|
221 }
|
benoitrigolleau@211
|
222
|
benoitrigolleau@211
|
223 void Plotter::refreshPixmap(){
|
benoitrigolleau@211
|
224 m_pixmap = QPixmap(size());
|
benoitrigolleau@211
|
225 m_pixmap.fill(this, 0, 0);
|
benoitrigolleau@211
|
226
|
benoitrigolleau@211
|
227 QPainter painter(&m_pixmap);
|
benoitrigolleau@211
|
228 painter.initFrom(this);
|
benoitrigolleau@211
|
229 drawGrid(&painter);
|
benoitrigolleau@211
|
230 drawCurve(&painter);
|
benoitrigolleau@211
|
231 drawMaskCurve(&painter);
|
benoitrigolleau@211
|
232 update();
|
benoitrigolleau@211
|
233 }
|
benoitrigolleau@211
|
234
|
benoitrigolleau@211
|
235 void Plotter::setMargin(int margin){
|
benoitrigolleau@211
|
236 m_margin = margin;
|
lbajardsilogic@232
|
237 }
|
lbajardsilogic@232
|
238
|
lbajardsilogic@232
|
239 void Plotter::setFilter(float* filter)
|
lbajardsilogic@232
|
240 {
|
benoitrigolleau@240
|
241
|
lbajardsilogic@232
|
242 m_curveMask.clear();
|
lbajardsilogic@232
|
243 for (int i=0; i<m_signalWidth; i++)
|
lbajardsilogic@232
|
244 {
|
lbajardsilogic@233
|
245 m_curveMask.push_back((int) (m_signalHeight - filter[i]*(m_signalHeight/2-1)));
|
lbajardsilogic@232
|
246 }
|
lbajardsilogic@232
|
247 refreshPixmap();
|
lbajardsilogic@235
|
248 }
|
lbajardsilogic@235
|
249
|
lbajardsilogic@235
|
250 void Plotter::enableDrawCurve(bool enable)
|
lbajardsilogic@235
|
251 {
|
benoitrigolleau@240
|
252 if(enable!=m_enableDrawCurve){
|
benoitrigolleau@240
|
253 QVector<float> aux = m_curveMask;
|
benoitrigolleau@240
|
254 m_curveMask = m_oldCurveMask;
|
benoitrigolleau@240
|
255 m_oldCurveMask = aux;
|
benoitrigolleau@240
|
256 refreshPixmap();
|
benoitrigolleau@240
|
257 if(enable){
|
benoitrigolleau@240
|
258 emit filterChanged(m_curveMask);
|
benoitrigolleau@240
|
259 }
|
benoitrigolleau@240
|
260 }
|
lbajardsilogic@235
|
261 m_enableDrawCurve = enable;
|
benoitrigolleau@211
|
262 } |