media_monitor.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * media_monitor.cpp - Display IP streaming media status, using the FLTK toolkit.
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2007 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. #if defined(HAVE_CONFIG_H)
  26. #include "config.h"
  27. #endif
  28. #if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H)
  29. #define __STDC_LIMIT_MACROS
  30. #include <inttypes.h>
  31. #include <stdio.h>
  32. #include <math.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <sys/select.h>
  37. #include <FL/Fl.H>
  38. #include <FL/Fl_Overlay_Window.H>
  39. #include <FL/Fl_Light_Button.H>
  40. #include <FL/Fl_Cartesian.H>
  41. #include <FL/fl_draw.H>
  42. #include "spandsp.h"
  43. #include "media_monitor.h"
  44. struct line_model_monitor_s
  45. {
  46. Fl_Double_Window *w;
  47. Fl_Group *c_right;
  48. Fl_Group *c_sent;
  49. Fl_Group *c_received;
  50. Ca_Canvas *canvas_sent;
  51. Ca_X_Axis *sent_x;
  52. Ca_Y_Axis *sent_y;
  53. Ca_Line *sent_re;
  54. double sent_re_plot[1000];
  55. double sent_re_plot_min;
  56. double sent_re_plot_max;
  57. Ca_Canvas *canvas_received;
  58. Ca_X_Axis *received_x;
  59. Ca_Y_Axis *received_y;
  60. Ca_Line *received_delays;
  61. double received_delays_plot[4000];
  62. double received_delays_plot_max;
  63. int min_diff;
  64. int max_diff;
  65. int highest_seq_no_seen;
  66. };
  67. static int skip = 0;
  68. static struct line_model_monitor_s media;
  69. static struct line_model_monitor_s *s = &media;
  70. void media_monitor_rx(int seq_no, double departure_time, double arrival_time)
  71. {
  72. double fdiff;
  73. int diff;
  74. int i;
  75. if (s->received_delays)
  76. delete s->received_delays;
  77. s->canvas_received->current(s->canvas_received);
  78. fdiff = (arrival_time - departure_time)*1000.0;
  79. diff = (int) fdiff;
  80. if (diff < 0)
  81. diff = 0;
  82. else if (diff > 1999)
  83. diff = 1999;
  84. s->received_delays_plot[2*diff + 1]++;
  85. if (s->received_delays_plot[2*diff + 1] > s->received_delays_plot_max)
  86. {
  87. s->received_delays_plot_max = s->received_delays_plot[2*diff + 1];
  88. s->received_y->maximum(s->received_delays_plot_max);
  89. }
  90. if (diff > s->max_diff)
  91. {
  92. s->max_diff = diff;
  93. s->received_x->maximum((double) s->max_diff);
  94. }
  95. if (diff < s->min_diff)
  96. {
  97. s->min_diff = diff - 1;
  98. s->received_x->minimum((double) s->min_diff);
  99. }
  100. s->received_delays = new Ca_Line(2000, s->received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT);
  101. if (s->sent_re)
  102. delete s->sent_re;
  103. s->canvas_sent->current(s->canvas_sent);
  104. if (seq_no > s->highest_seq_no_seen + 1)
  105. {
  106. for (i = s->highest_seq_no_seen + 1; i < seq_no; i++)
  107. s->sent_re_plot[2*(i%500) + 1] = 0.0;
  108. }
  109. s->sent_re_plot[2*(seq_no%500) + 1] = fdiff;
  110. if (fdiff > s->sent_re_plot_max)
  111. {
  112. s->sent_re_plot_max = fdiff;
  113. s->sent_y->maximum(s->sent_re_plot_max);
  114. }
  115. if (fdiff < s->sent_re_plot_min)
  116. {
  117. s->sent_re_plot_min = fdiff - 1.0;
  118. s->sent_y->minimum(s->sent_re_plot_min);
  119. }
  120. s->sent_re = new Ca_Line(500, s->sent_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
  121. if (seq_no > s->highest_seq_no_seen)
  122. s->highest_seq_no_seen = seq_no;
  123. if (++skip >= 100)
  124. {
  125. skip = 0;
  126. Fl::check();
  127. }
  128. }
  129. /*- End of function --------------------------------------------------------*/
  130. int start_media_monitor(void)
  131. {
  132. char buf[132 + 1];
  133. float x;
  134. float y;
  135. int i;
  136. int len;
  137. len = 128;
  138. s->w = new Fl_Double_Window(465, 400, "IP streaming media monitor");
  139. s->c_right = new Fl_Group(0, 0, 465, 405);
  140. s->c_sent = new Fl_Group(0, 0, 465, 200);
  141. s->c_sent->box(FL_DOWN_BOX);
  142. s->c_sent->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
  143. s->c_sent->current();
  144. s->canvas_sent = new Ca_Canvas(110, 35, 300, 100, "Packet delays");
  145. s->canvas_sent->box(FL_PLASTIC_DOWN_BOX);
  146. s->canvas_sent->color(7);
  147. s->canvas_sent->align(FL_ALIGN_TOP);
  148. Fl_Group::current()->resizable(s->canvas_sent);
  149. s->canvas_sent->border(15);
  150. s->sent_x = new Ca_X_Axis(115, 135, 290, 30, "Packet");
  151. s->sent_x->align(FL_ALIGN_BOTTOM);
  152. s->sent_x->minimum(0.0);
  153. s->sent_x->maximum(500.0);
  154. s->sent_x->label_format("%g");
  155. s->sent_x->minor_grid_color(fl_gray_ramp(20));
  156. s->sent_x->major_grid_color(fl_gray_ramp(15));
  157. s->sent_x->label_grid_color(fl_gray_ramp(10));
  158. s->sent_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
  159. s->sent_x->minor_grid_style(FL_DOT);
  160. s->sent_x->major_step(5);
  161. s->sent_x->label_step(1);
  162. s->sent_x->axis_align(CA_BOTTOM | CA_LINE);
  163. s->sent_x->axis_color(FL_BLACK);
  164. s->sent_x->current();
  165. s->sent_y = new Ca_Y_Axis(60, 40, 50, 90, "Delay\n(ms)");
  166. s->sent_y->align(FL_ALIGN_LEFT);
  167. s->sent_y->minimum(0.0);
  168. s->sent_y->maximum(2000.0);
  169. s->sent_y->minor_grid_color(fl_gray_ramp(20));
  170. s->sent_y->major_grid_color(fl_gray_ramp(15));
  171. s->sent_y->label_grid_color(fl_gray_ramp(10));
  172. s->sent_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
  173. s->sent_y->minor_grid_style(FL_DOT);
  174. s->sent_y->major_step(5);
  175. s->sent_y->label_step(1);
  176. s->sent_y->axis_color(FL_BLACK);
  177. s->sent_y->current();
  178. s->c_sent->end();
  179. s->c_received = new Fl_Group(0, 200, 465, 200);
  180. s->c_received->box(FL_DOWN_BOX);
  181. s->c_received->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
  182. s->c_received->current();
  183. s->canvas_received = new Ca_Canvas(110, 235, 300, 100, "Delay spread");
  184. s->canvas_received->box(FL_PLASTIC_DOWN_BOX);
  185. s->canvas_received->color(7);
  186. s->canvas_received->align(FL_ALIGN_TOP);
  187. Fl_Group::current()->resizable(s->canvas_received);
  188. s->canvas_received->border(15);
  189. s->received_x = new Ca_X_Axis(115, 335, 290, 30, "Delay (ms)");
  190. s->received_x->align(FL_ALIGN_BOTTOM);
  191. s->received_x->minimum(0.0);
  192. s->received_x->maximum(2000.0);
  193. s->received_x->label_format("%g");
  194. s->received_x->minor_grid_color(fl_gray_ramp(20));
  195. s->received_x->major_grid_color(fl_gray_ramp(15));
  196. s->received_x->label_grid_color(fl_gray_ramp(10));
  197. s->received_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
  198. s->received_x->minor_grid_style(FL_DOT);
  199. s->received_x->major_step(5);
  200. s->received_x->label_step(1);
  201. s->received_x->axis_align(CA_BOTTOM | CA_LINE);
  202. s->received_x->axis_color(FL_BLACK);
  203. s->received_x->current();
  204. s->received_y = new Ca_Y_Axis(60, 240, 50, 90, "Freq");
  205. s->received_y->align(FL_ALIGN_LEFT);
  206. s->received_y->minimum(0.0);
  207. s->received_y->maximum(50.0);
  208. s->received_y->minor_grid_color(fl_gray_ramp(20));
  209. s->received_y->major_grid_color(fl_gray_ramp(15));
  210. s->received_y->label_grid_color(fl_gray_ramp(10));
  211. s->received_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
  212. s->received_y->minor_grid_style(FL_DOT);
  213. s->received_y->major_step(5);
  214. s->received_y->label_step(1);
  215. s->received_y->axis_color(FL_BLACK);
  216. s->received_y->current();
  217. for (i = 0; i < 2000; i++)
  218. s->received_delays_plot[2*i] = i;
  219. s->received_delays_plot_max = 0.0;
  220. s->min_diff = 2000;
  221. s->max_diff = 0;
  222. s->received_delays = NULL;
  223. s->highest_seq_no_seen = -1;
  224. for (i = 0; i < 500; i++)
  225. s->sent_re_plot[2*i] = i;
  226. s->sent_re_plot_min = 99999.0;
  227. s->sent_re_plot_max = 0.0;
  228. s->sent_re = NULL;
  229. s->c_received->end();
  230. s->c_right->end();
  231. Fl_Group::current()->resizable(s->c_right);
  232. s->w->end();
  233. s->w->show();
  234. Fl::check();
  235. return 0;
  236. }
  237. /*- End of function --------------------------------------------------------*/
  238. void media_monitor_wait_to_end(void)
  239. {
  240. fd_set rfds;
  241. int res;
  242. struct timeval tv;
  243. fprintf(stderr, "Processing complete. Press the <enter> key to end\n");
  244. do
  245. {
  246. usleep(100000);
  247. Fl::check();
  248. FD_ZERO(&rfds);
  249. FD_SET(0, &rfds);
  250. tv.tv_usec = 100000;
  251. tv.tv_sec = 0;
  252. res = select(1, &rfds, NULL, NULL, &tv);
  253. }
  254. while (res <= 0);
  255. }
  256. /*- End of function --------------------------------------------------------*/
  257. void media_monitor_update_display(void)
  258. {
  259. Fl::check();
  260. Fl::check();
  261. Fl::check();
  262. Fl::check();
  263. Fl::check();
  264. Fl::check();
  265. Fl::check();
  266. Fl::check();
  267. Fl::check();
  268. Fl::check();
  269. Fl::check();
  270. Fl::check();
  271. }
  272. /*- End of function --------------------------------------------------------*/
  273. #endif
  274. /*- End of file ------------------------------------------------------------*/