Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/modem_monitor.cpp @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 15:50:58 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
|---|---|
| 1 /* | |
| 2 * SpanDSP - a series of DSP components for telephony | |
| 3 * | |
| 4 * modem_monitor.cpp - Display QAM constellations, using the FLTK toolkit. | |
| 5 * | |
| 6 * Written by Steve Underwood <steveu@coppice.org> | |
| 7 * | |
| 8 * Copyright (C) 2004 Steve Underwood | |
| 9 * | |
| 10 * All rights reserved. | |
| 11 * | |
| 12 * This program is free software; you can redistribute it and/or modify | |
| 13 * it under the terms of the GNU General Public License version 2, as | |
| 14 * published by the Free Software Foundation. | |
| 15 * | |
| 16 * This program is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 * GNU General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU General Public License | |
| 22 * along with this program; if not, write to the Free Software | |
| 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 24 * | |
| 25 * $Id: modem_monitor.cpp,v 1.17 2008/09/04 14:40:05 steveu Exp $ | |
| 26 */ | |
| 27 | |
| 28 #ifdef HAVE_CONFIG_H | |
| 29 #include "config.h" | |
| 30 #endif | |
| 31 | |
| 32 #if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) | |
| 33 | |
| 34 #define __STDC_LIMIT_MACROS | |
| 35 | |
| 36 #include <inttypes.h> | |
| 37 #include <stdio.h> | |
| 38 #include <math.h> | |
| 39 #include <stdlib.h> | |
| 40 #include <string.h> | |
| 41 #include <unistd.h> | |
| 42 #include <sys/select.h> | |
| 43 | |
| 44 #include <FL/Fl.H> | |
| 45 #include <FL/Fl_Overlay_Window.H> | |
| 46 #include <FL/Fl_Light_Button.H> | |
| 47 #include <FL/Fl_Cartesian.H> | |
| 48 #include <FL/Fl_Audio_Meter.H> | |
| 49 #include <FL/Fl_Output.H> | |
| 50 #include <FL/fl_draw.H> | |
| 51 | |
| 52 #include "spandsp.h" | |
| 53 | |
| 54 #define SYMBOL_TRACKER_POINTS 12000 | |
| 55 #define CARRIER_TRACKER_POINTS 12000 | |
| 56 | |
| 57 #define FP_FACTOR 4096 | |
| 58 | |
| 59 struct qam_monitor_s | |
| 60 { | |
| 61 Fl_Double_Window *w; | |
| 62 Fl_Group *c_const; | |
| 63 Fl_Group *c_right; | |
| 64 Fl_Group *c_eq; | |
| 65 Fl_Group *c_symbol_track; | |
| 66 | |
| 67 /* Constellation stuff */ | |
| 68 Ca_Canvas *canvas_const; | |
| 69 Ca_X_Axis *sig_i; | |
| 70 Ca_Y_Axis *sig_q; | |
| 71 | |
| 72 Ca_Point *constel_point[100000]; | |
| 73 int constel_window; | |
| 74 int next_constel_point; | |
| 75 int skip; | |
| 76 | |
| 77 /* Equalizer stuff */ | |
| 78 Ca_Canvas *canvas_eq; | |
| 79 | |
| 80 Ca_X_Axis *eq_x; | |
| 81 Ca_Y_Axis *eq_y; | |
| 82 | |
| 83 Ca_Line *eq_re; | |
| 84 Ca_Line *eq_im; | |
| 85 | |
| 86 double eq_re_plot[200]; | |
| 87 double eq_im_plot[200]; | |
| 88 | |
| 89 /* Carrier and symbol tracking stuff */ | |
| 90 Ca_Canvas *canvas_track; | |
| 91 | |
| 92 Ca_X_Axis *track_x; | |
| 93 Ca_Y_Axis *symbol_track_y; | |
| 94 Ca_Y_Axis *carrier_y; | |
| 95 | |
| 96 Ca_Line *symbol_track; | |
| 97 Ca_Line *carrier; | |
| 98 | |
| 99 float symbol_tracker[SYMBOL_TRACKER_POINTS]; | |
| 100 double symbol_track_plot[SYMBOL_TRACKER_POINTS*2]; | |
| 101 int symbol_track_points; | |
| 102 int symbol_track_ptr; | |
| 103 int symbol_track_window; | |
| 104 | |
| 105 float carrier_tracker[CARRIER_TRACKER_POINTS]; | |
| 106 double carrier_plot[CARRIER_TRACKER_POINTS*2]; | |
| 107 int carrier_points; | |
| 108 int carrier_ptr; | |
| 109 int carrier_window; | |
| 110 | |
| 111 /* Audio meter stuff */ | |
| 112 Fl_Audio_Meter *audio_meter; | |
| 113 Fl_Output *audio_level; | |
| 114 int32_t power_reading; | |
| 115 }; | |
| 116 | |
| 117 #include "modem_monitor.h" | |
| 118 | |
| 119 int qam_monitor_clear_constel(qam_monitor_t *s) | |
| 120 { | |
| 121 int i; | |
| 122 | |
| 123 s->canvas_const->current(s->canvas_const); | |
| 124 for (i = 0; i < s->constel_window; i++) | |
| 125 { | |
| 126 if (s->constel_point[i]) | |
| 127 { | |
| 128 delete s->constel_point[i]; | |
| 129 s->constel_point[i] = NULL; | |
| 130 } | |
| 131 } | |
| 132 s->next_constel_point = 0; | |
| 133 Fl::check(); | |
| 134 return 0; | |
| 135 } | |
| 136 /*- End of function --------------------------------------------------------*/ | |
| 137 | |
| 138 int qam_monitor_update_constel(qam_monitor_t *s, const complexf_t *pt) | |
| 139 { | |
| 140 int i; | |
| 141 | |
| 142 s->canvas_const->current(s->canvas_const); | |
| 143 if (s->constel_point[s->next_constel_point]) | |
| 144 delete s->constel_point[s->next_constel_point]; | |
| 145 s->constel_point[s->next_constel_point++] = new Ca_Point(pt->re, pt->im, FL_BLACK); | |
| 146 if (s->next_constel_point >= s->constel_window) | |
| 147 s->next_constel_point = 0; | |
| 148 if (++s->skip >= 100) | |
| 149 { | |
| 150 s->skip = 0; | |
| 151 Fl::check(); | |
| 152 } | |
| 153 return 0; | |
| 154 } | |
| 155 /*- End of function --------------------------------------------------------*/ | |
| 156 | |
| 157 int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int len) | |
| 158 { | |
| 159 int i; | |
| 160 float min; | |
| 161 float max; | |
| 162 | |
| 163 /* Protect against screwy values */ | |
| 164 for (i = 0; i < len; i++) | |
| 165 { | |
| 166 if (isnan(coeffs[i].re) || isinf(coeffs[i].re)) | |
| 167 break; | |
| 168 if (isnan(coeffs[i].im) || isinf(coeffs[i].im)) | |
| 169 break; | |
| 170 if (coeffs[i].re < -20.0f || coeffs[i].re > 20.0f) | |
| 171 break; | |
| 172 if (coeffs[i].im < -20.0f || coeffs[i].im > 20.0f) | |
| 173 break; | |
| 174 } | |
| 175 if (i != len) | |
| 176 return -1; | |
| 177 | |
| 178 if (s->eq_re) | |
| 179 delete s->eq_re; | |
| 180 if (s->eq_im) | |
| 181 delete s->eq_im; | |
| 182 | |
| 183 s->canvas_eq->current(s->canvas_eq); | |
| 184 i = 0; | |
| 185 min = coeffs[i].re; | |
| 186 if (min > coeffs[i].im) | |
| 187 min = coeffs[i].im; | |
| 188 max = coeffs[i].re; | |
| 189 if (max < coeffs[i].im) | |
| 190 max = coeffs[i].im; | |
| 191 for (i = 0; i < len; i++) | |
| 192 { | |
| 193 s->eq_re_plot[2*i] = (i - len/2)/2.0; | |
| 194 s->eq_re_plot[2*i + 1] = coeffs[i].re; | |
| 195 if (min > coeffs[i].re) | |
| 196 min = coeffs[i].re; | |
| 197 if (max < coeffs[i].re) | |
| 198 max = coeffs[i].re; | |
| 199 | |
| 200 s->eq_im_plot[2*i] = (i - len/2)/2.0; | |
| 201 s->eq_im_plot[2*i + 1] = coeffs[i].im; | |
| 202 if (min > coeffs[i].im) | |
| 203 min = coeffs[i].im; | |
| 204 if (max < coeffs[i].im) | |
| 205 max = coeffs[i].im; | |
| 206 } | |
| 207 | |
| 208 s->eq_x->minimum(-len/4.0); | |
| 209 s->eq_x->maximum(len/4.0); | |
| 210 s->eq_y->maximum((max == min) ? max + 0.2 : max); | |
| 211 s->eq_y->minimum(min); | |
| 212 s->eq_re = new Ca_Line(len, s->eq_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
| 213 s->eq_im = new Ca_Line(len, s->eq_im_plot, 0, 0, FL_RED, CA_NO_POINT); | |
| 214 Fl::check(); | |
| 215 return 0; | |
| 216 } | |
| 217 /*- End of function --------------------------------------------------------*/ | |
| 218 | |
| 219 int qam_monitor_update_int_equalizer(qam_monitor_t *s, const complexi16_t *coeffs, int len) | |
| 220 { | |
| 221 int i; | |
| 222 float min; | |
| 223 float max; | |
| 224 | |
| 225 if (s->eq_re) | |
| 226 delete s->eq_re; | |
| 227 if (s->eq_im) | |
| 228 delete s->eq_im; | |
| 229 | |
| 230 s->canvas_eq->current(s->canvas_eq); | |
| 231 i = 0; | |
| 232 min = coeffs[i].re; | |
| 233 if (min > coeffs[i].im) | |
| 234 min = coeffs[i].im; | |
| 235 max = coeffs[i].re; | |
| 236 if (max < coeffs[i].im) | |
| 237 max = coeffs[i].im; | |
| 238 for (i = 0; i < len; i++) | |
| 239 { | |
| 240 s->eq_re_plot[2*i] = (i - len/2)/2.0f; | |
| 241 s->eq_re_plot[2*i + 1] = coeffs[i].re/(float) FP_FACTOR; | |
| 242 if (min > coeffs[i].re) | |
| 243 min = coeffs[i].re; | |
| 244 if (max < coeffs[i].re) | |
| 245 max = coeffs[i].re; | |
| 246 | |
| 247 s->eq_im_plot[2*i] = (i - len/2)/2.0f; | |
| 248 s->eq_im_plot[2*i + 1] = coeffs[i].im/(float) FP_FACTOR; | |
| 249 if (min > coeffs[i].im) | |
| 250 min = coeffs[i].im; | |
| 251 if (max < coeffs[i].im) | |
| 252 max = coeffs[i].im; | |
| 253 } | |
| 254 min /= (float) FP_FACTOR; | |
| 255 max /= (float) FP_FACTOR; | |
| 256 | |
| 257 s->eq_x->minimum(-len/4.0); | |
| 258 s->eq_x->maximum(len/4.0); | |
| 259 s->eq_y->maximum((max == min) ? max + 0.2 : max); | |
| 260 s->eq_y->minimum(min); | |
| 261 s->eq_re = new Ca_Line(len, s->eq_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
| 262 s->eq_im = new Ca_Line(len, s->eq_im_plot, 0, 0, FL_RED, CA_NO_POINT); | |
| 263 Fl::check(); | |
| 264 return 0; | |
| 265 } | |
| 266 /*- End of function --------------------------------------------------------*/ | |
| 267 | |
| 268 int qam_monitor_update_symbol_tracking(qam_monitor_t *s, float total_correction) | |
| 269 { | |
| 270 int i; | |
| 271 int j; | |
| 272 float min; | |
| 273 float max; | |
| 274 | |
| 275 s->symbol_tracker[s->symbol_track_ptr++] = total_correction; | |
| 276 if (s->symbol_track_points < SYMBOL_TRACKER_POINTS) | |
| 277 s->symbol_track_points++; | |
| 278 if (s->symbol_track_ptr >= SYMBOL_TRACKER_POINTS) | |
| 279 s->symbol_track_ptr = 0; | |
| 280 | |
| 281 s->canvas_track->current(s->canvas_track); | |
| 282 if (s->symbol_track) | |
| 283 delete s->symbol_track; | |
| 284 s->track_x->current(); | |
| 285 s->symbol_track_y->current(); | |
| 286 | |
| 287 min = | |
| 288 max = s->symbol_tracker[0]; | |
| 289 for (i = s->symbol_track_ptr, j = 0; i < s->symbol_track_points; i++, j++) | |
| 290 { | |
| 291 s->symbol_track_plot[2*j] = j; | |
| 292 s->symbol_track_plot[2*j + 1] = s->symbol_tracker[i]; | |
| 293 if (min > s->symbol_tracker[i]) | |
| 294 min = s->symbol_tracker[i]; | |
| 295 if (max < s->symbol_tracker[i]) | |
| 296 max = s->symbol_tracker[i]; | |
| 297 } | |
| 298 for (i = 0; i < s->symbol_track_ptr; i++, j++) | |
| 299 { | |
| 300 s->symbol_track_plot[2*j] = j; | |
| 301 s->symbol_track_plot[2*j + 1] = s->symbol_tracker[i]; | |
| 302 if (min > s->symbol_tracker[i]) | |
| 303 min = s->symbol_tracker[i]; | |
| 304 if (max < s->symbol_tracker[i]) | |
| 305 max = s->symbol_tracker[i]; | |
| 306 } | |
| 307 s->symbol_track_y->maximum((fabs(max - min) < 0.05) ? max + 0.05 : max); | |
| 308 s->symbol_track_y->minimum(min); | |
| 309 | |
| 310 s->symbol_track = new Ca_Line(s->symbol_track_points, s->symbol_track_plot, 0, 0, FL_RED, CA_NO_POINT); | |
| 311 //Fl::check(); | |
| 312 return 0; | |
| 313 } | |
| 314 /*- End of function --------------------------------------------------------*/ | |
| 315 | |
| 316 int qam_monitor_update_audio_level(qam_monitor_t *s, const int16_t amp[], int len) | |
| 317 { | |
| 318 int i; | |
| 319 char buf[11]; | |
| 320 double val; | |
| 321 | |
| 322 for (i = 0; i < len; i++) | |
| 323 { | |
| 324 s->audio_meter->sample(amp[i]/32768.0); | |
| 325 s->power_reading += ((amp[i]*amp[i] - s->power_reading) >> 10); | |
| 326 } | |
| 327 if (s->power_reading <= 0) | |
| 328 val = -90.0; | |
| 329 else | |
| 330 val = log10((double) s->power_reading/(32767.0f*32767.0f))*10.0f + 3.14 + 3.02; | |
| 331 | |
| 332 snprintf(buf, sizeof(buf), "%5.1fdBm0", val); | |
| 333 s->audio_level->value(buf); | |
| 334 return 0; | |
| 335 } | |
| 336 /*- End of function --------------------------------------------------------*/ | |
| 337 | |
| 338 int qam_monitor_update_carrier_tracking(qam_monitor_t *s, float carrier_freq) | |
| 339 { | |
| 340 int i; | |
| 341 int j; | |
| 342 float min; | |
| 343 float max; | |
| 344 | |
| 345 s->carrier_tracker[s->carrier_ptr++] = carrier_freq; | |
| 346 if (s->carrier_points < CARRIER_TRACKER_POINTS) | |
| 347 s->carrier_points++; | |
| 348 if (s->carrier_ptr >= CARRIER_TRACKER_POINTS) | |
| 349 s->carrier_ptr = 0; | |
| 350 | |
| 351 s->canvas_track->current(s->canvas_track); | |
| 352 if (s->carrier) | |
| 353 delete s->carrier; | |
| 354 s->track_x->current(); | |
| 355 s->carrier_y->current(); | |
| 356 | |
| 357 min = | |
| 358 max = s->carrier_tracker[0]; | |
| 359 for (i = s->carrier_ptr, j = 0; i < s->carrier_points; i++, j++) | |
| 360 { | |
| 361 s->carrier_plot[2*j] = j; | |
| 362 s->carrier_plot[2*j + 1] = s->carrier_tracker[i]; | |
| 363 if (min > s->carrier_tracker[i]) | |
| 364 min = s->carrier_tracker[i]; | |
| 365 if (max < s->carrier_tracker[i]) | |
| 366 max = s->carrier_tracker[i]; | |
| 367 } | |
| 368 for (i = 0; i < s->carrier_ptr; i++, j++) | |
| 369 { | |
| 370 s->carrier_plot[2*j] = j; | |
| 371 s->carrier_plot[2*j + 1] = s->carrier_tracker[i]; | |
| 372 if (min > s->carrier_tracker[i]) | |
| 373 min = s->carrier_tracker[i]; | |
| 374 if (max < s->carrier_tracker[i]) | |
| 375 max = s->carrier_tracker[i]; | |
| 376 } | |
| 377 | |
| 378 s->carrier_y->maximum((fabs(max - min) < 0.05) ? max + 0.05 : max); | |
| 379 s->carrier_y->minimum(min); | |
| 380 | |
| 381 s->carrier = new Ca_Line(s->carrier_points, s->carrier_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
| 382 //Fl::check(); | |
| 383 return 0; | |
| 384 } | |
| 385 /*- End of function --------------------------------------------------------*/ | |
| 386 | |
| 387 qam_monitor_t *qam_monitor_init(float constel_width, const char *tag) | |
| 388 { | |
| 389 char buf[132 + 1]; | |
| 390 float x; | |
| 391 float y; | |
| 392 qam_monitor_t *s; | |
| 393 | |
| 394 if ((s = (qam_monitor_t *) malloc(sizeof(*s))) == NULL) | |
| 395 return NULL; | |
| 396 | |
| 397 s->w = new Fl_Double_Window(905, 400, (tag) ? tag : "QAM monitor"); | |
| 398 | |
| 399 s->c_const = new Fl_Group(0, 0, 380, 400); | |
| 400 s->c_const->box(FL_DOWN_BOX); | |
| 401 s->c_const->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
| 402 | |
| 403 s->canvas_const = new Ca_Canvas(60, 30, 300, 300, "Constellation"); | |
| 404 s->canvas_const->box(FL_PLASTIC_DOWN_BOX); | |
| 405 s->canvas_const->color(7); | |
| 406 s->canvas_const->align(FL_ALIGN_TOP); | |
| 407 s->canvas_const->border(15); | |
| 408 | |
| 409 s->sig_i = new Ca_X_Axis(65, 330, 290, 30, "I"); | |
| 410 s->sig_i->align(FL_ALIGN_BOTTOM); | |
| 411 s->sig_i->minimum(-constel_width); | |
| 412 s->sig_i->maximum(constel_width); | |
| 413 s->sig_i->label_format("%g"); | |
| 414 s->sig_i->minor_grid_color(fl_gray_ramp(20)); | |
| 415 s->sig_i->major_grid_color(fl_gray_ramp(15)); | |
| 416 s->sig_i->label_grid_color(fl_gray_ramp(10)); | |
| 417 s->sig_i->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 418 s->sig_i->minor_grid_style(FL_DOT); | |
| 419 s->sig_i->major_step(5); | |
| 420 s->sig_i->label_step(1); | |
| 421 s->sig_i->axis_color(FL_BLACK); | |
| 422 s->sig_i->axis_align(CA_BOTTOM | CA_LINE); | |
| 423 | |
| 424 s->sig_q = new Ca_Y_Axis(20, 35, 40, 290, "Q"); | |
| 425 s->sig_q->align(FL_ALIGN_LEFT); | |
| 426 s->sig_q->minimum(-constel_width); | |
| 427 s->sig_q->maximum(constel_width); | |
| 428 s->sig_q->minor_grid_color(fl_gray_ramp(20)); | |
| 429 s->sig_q->major_grid_color(fl_gray_ramp(15)); | |
| 430 s->sig_q->label_grid_color(fl_gray_ramp(10)); | |
| 431 //s->sig_q->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 432 s->sig_q->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 433 s->sig_q->minor_grid_style(FL_DOT); | |
| 434 s->sig_q->major_step(5); | |
| 435 s->sig_q->label_step(1); | |
| 436 s->sig_q->axis_color(FL_BLACK); | |
| 437 | |
| 438 s->sig_q->current(); | |
| 439 | |
| 440 s->c_const->end(); | |
| 441 | |
| 442 s->c_right = new Fl_Group(440, 0, 465, 405); | |
| 443 | |
| 444 s->c_eq = new Fl_Group(380, 0, 265, 200); | |
| 445 s->c_eq->box(FL_DOWN_BOX); | |
| 446 s->c_eq->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
| 447 s->c_eq->current(); | |
| 448 s->canvas_eq = new Ca_Canvas(460, 35, 150, 100, "Equalizer"); | |
| 449 s->canvas_eq->box(FL_PLASTIC_DOWN_BOX); | |
| 450 s->canvas_eq->color(7); | |
| 451 s->canvas_eq->align(FL_ALIGN_TOP); | |
| 452 Fl_Group::current()->resizable(s->canvas_eq); | |
| 453 s->canvas_eq->border(15); | |
| 454 | |
| 455 s->eq_x = new Ca_X_Axis(465, 135, 140, 30, "Symbol"); | |
| 456 s->eq_x->align(FL_ALIGN_BOTTOM); | |
| 457 s->eq_x->minimum(-8.0); | |
| 458 s->eq_x->maximum(8.0); | |
| 459 s->eq_x->label_format("%g"); | |
| 460 s->eq_x->minor_grid_color(fl_gray_ramp(20)); | |
| 461 s->eq_x->major_grid_color(fl_gray_ramp(15)); | |
| 462 s->eq_x->label_grid_color(fl_gray_ramp(10)); | |
| 463 s->eq_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 464 s->eq_x->minor_grid_style(FL_DOT); | |
| 465 s->eq_x->major_step(5); | |
| 466 s->eq_x->label_step(1); | |
| 467 s->eq_x->axis_align(CA_BOTTOM | CA_LINE); | |
| 468 s->eq_x->axis_color(FL_BLACK); | |
| 469 s->eq_x->current(); | |
| 470 | |
| 471 s->eq_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); | |
| 472 s->eq_y->align(FL_ALIGN_LEFT); | |
| 473 s->eq_y->minimum(-0.1); | |
| 474 s->eq_y->maximum(0.1); | |
| 475 s->eq_y->minor_grid_color(fl_gray_ramp(20)); | |
| 476 s->eq_y->major_grid_color(fl_gray_ramp(15)); | |
| 477 s->eq_y->label_grid_color(fl_gray_ramp(10)); | |
| 478 s->eq_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 479 s->eq_y->minor_grid_style(FL_DOT); | |
| 480 s->eq_y->major_step(5); | |
| 481 s->eq_y->label_step(1); | |
| 482 s->eq_y->axis_color(FL_BLACK); | |
| 483 s->eq_y->current(); | |
| 484 | |
| 485 s->c_eq->end(); | |
| 486 | |
| 487 s->c_symbol_track = new Fl_Group(380, 200, 525, 200); | |
| 488 s->c_symbol_track->box(FL_DOWN_BOX); | |
| 489 s->c_symbol_track->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
| 490 s->c_symbol_track->current(); | |
| 491 | |
| 492 s->canvas_track = new Ca_Canvas(490, 235, 300, 100, "Symbol and carrier tracking"); | |
| 493 s->canvas_track->box(FL_PLASTIC_DOWN_BOX); | |
| 494 s->canvas_track->color(7); | |
| 495 s->canvas_track->align(FL_ALIGN_TOP); | |
| 496 Fl_Group::current()->resizable(s->canvas_track); | |
| 497 s->canvas_track->border(15); | |
| 498 | |
| 499 s->track_x = new Ca_X_Axis(495, 335, 290, 30, "Time (symbols)"); | |
| 500 s->track_x->align(FL_ALIGN_BOTTOM); | |
| 501 s->track_x->minimum(0.0); | |
| 502 s->track_x->maximum(2400.0*5.0); | |
| 503 s->track_x->label_format("%g"); | |
| 504 s->track_x->minor_grid_color(fl_gray_ramp(20)); | |
| 505 s->track_x->major_grid_color(fl_gray_ramp(15)); | |
| 506 s->track_x->label_grid_color(fl_gray_ramp(10)); | |
| 507 s->track_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 508 s->track_x->minor_grid_style(FL_DOT); | |
| 509 s->track_x->major_step(5); | |
| 510 s->track_x->label_step(1); | |
| 511 s->track_x->axis_align(CA_BOTTOM | CA_LINE); | |
| 512 s->track_x->axis_color(FL_BLACK); | |
| 513 s->track_x->current(); | |
| 514 | |
| 515 s->symbol_track_y = new Ca_Y_Axis(420, 240, 70, 90, "Cor"); | |
| 516 s->symbol_track_y->align(FL_ALIGN_LEFT); | |
| 517 s->symbol_track_y->minimum(-0.1); | |
| 518 s->symbol_track_y->maximum(0.1); | |
| 519 s->symbol_track_y->minor_grid_color(fl_gray_ramp(20)); | |
| 520 s->symbol_track_y->major_grid_color(fl_gray_ramp(15)); | |
| 521 s->symbol_track_y->label_grid_color(fl_gray_ramp(10)); | |
| 522 s->symbol_track_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 523 s->symbol_track_y->minor_grid_style(FL_DOT); | |
| 524 s->symbol_track_y->major_step(5); | |
| 525 s->symbol_track_y->label_step(1); | |
| 526 s->symbol_track_y->axis_color(FL_RED); | |
| 527 s->symbol_track_y->current(); | |
| 528 | |
| 529 s->carrier_y = new Ca_Y_Axis(790, 240, 70, 90, "Freq"); | |
| 530 s->carrier_y->align(FL_ALIGN_RIGHT); | |
| 531 s->carrier_y->minimum(-0.1); | |
| 532 s->carrier_y->maximum(0.1); | |
| 533 s->carrier_y->minor_grid_color(fl_gray_ramp(20)); | |
| 534 s->carrier_y->major_grid_color(fl_gray_ramp(15)); | |
| 535 s->carrier_y->label_grid_color(fl_gray_ramp(10)); | |
| 536 s->carrier_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
| 537 s->carrier_y->minor_grid_style(FL_DOT); | |
| 538 s->carrier_y->major_step(5); | |
| 539 s->carrier_y->label_step(1); | |
| 540 s->carrier_y->axis_align(CA_RIGHT); | |
| 541 s->carrier_y->axis_color(FL_BLUE); | |
| 542 s->carrier_y->current(); | |
| 543 | |
| 544 s->c_symbol_track->end(); | |
| 545 | |
| 546 s->audio_meter = new Fl_Audio_Meter(672, 10, 16, 150, ""); | |
| 547 s->audio_meter->box(FL_PLASTIC_UP_BOX); | |
| 548 s->audio_meter->type(FL_VERT_AUDIO_METER); | |
| 549 | |
| 550 s->audio_level = new Fl_Output(650, 170, 60, 20, ""); | |
| 551 s->audio_level->textsize(10); | |
| 552 | |
| 553 s->c_right->end(); | |
| 554 | |
| 555 Fl_Group::current()->resizable(s->c_right); | |
| 556 s->w->end(); | |
| 557 s->w->show(); | |
| 558 | |
| 559 s->next_constel_point = 0; | |
| 560 s->constel_window = 10000; | |
| 561 | |
| 562 s->carrier_points = 0; | |
| 563 s->carrier_ptr = 0; | |
| 564 s->carrier_window = 100; | |
| 565 | |
| 566 s->symbol_track_points = 0; | |
| 567 s->symbol_track_window = 10000; | |
| 568 Fl::check(); | |
| 569 return s; | |
| 570 } | |
| 571 /*- End of function --------------------------------------------------------*/ | |
| 572 | |
| 573 void qam_wait_to_end(qam_monitor_t *s) | |
| 574 { | |
| 575 fd_set rfds; | |
| 576 int res; | |
| 577 struct timeval tv; | |
| 578 | |
| 579 fprintf(stderr, "Processing complete. Press the <enter> key to end\n"); | |
| 580 do | |
| 581 { | |
| 582 usleep(100000); | |
| 583 Fl::check(); | |
| 584 FD_ZERO(&rfds); | |
| 585 FD_SET(0, &rfds); | |
| 586 tv.tv_usec = 100000; | |
| 587 tv.tv_sec = 0; | |
| 588 res = select(1, &rfds, NULL, NULL, &tv); | |
| 589 } | |
| 590 while (res <= 0); | |
| 591 } | |
| 592 /*- End of function --------------------------------------------------------*/ | |
| 593 #endif | |
| 594 /*- End of file ------------------------------------------------------------*/ |
