Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/tests/line_model_monitor.cpp @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:26cd8f1ef0b1 | 5:f762bf195c4b |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * line_model_monitor.cpp - Model activity in a telephone line model, using the FLTK toolkit. | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2006 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: line_model_monitor.cpp,v 1.2 2006/10/24 13:22:03 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 #include <inttypes.h> | |
35 #include <stdio.h> | |
36 #include <math.h> | |
37 #include <stdlib.h> | |
38 #include <string.h> | |
39 #include <unistd.h> | |
40 #include <sys/select.h> | |
41 #if defined(HAVE_FFTW3_H) | |
42 #include <fftw3.h> | |
43 #else | |
44 #include <fftw.h> | |
45 #endif | |
46 | |
47 #include <FL/Fl.H> | |
48 #include <FL/Fl_Overlay_Window.H> | |
49 #include <FL/Fl_Light_Button.H> | |
50 #include <Fl/Fl_Cartesian.H> | |
51 #include <Fl/Fl_Audio_Meter.H> | |
52 #include <FL/fl_draw.H> | |
53 | |
54 #include "../src/spandsp/complex.h" | |
55 //#include "spandsp.h" | |
56 #include "line_model_monitor.h" | |
57 | |
58 Fl_Double_Window *w; | |
59 | |
60 Fl_Audio_Meter *audio_meter; | |
61 | |
62 Fl_Group *c_spec; | |
63 Fl_Group *c_right; | |
64 Fl_Group *c_can; | |
65 Fl_Group *c_line_model; | |
66 | |
67 Ca_Canvas *canvas_spec; | |
68 Ca_X_Axis *spec_freq; | |
69 Ca_Y_Axis *spec_amp; | |
70 Ca_Line *spec_re = NULL; | |
71 double spec_re_plot[2*512]; | |
72 | |
73 Ca_Canvas *canvas_can; | |
74 Ca_X_Axis *can_x; | |
75 Ca_Y_Axis *can_y; | |
76 Ca_Line *can_re = NULL; | |
77 double can_re_plot[512]; | |
78 | |
79 Ca_Canvas *canvas_line_model; | |
80 Ca_X_Axis *line_model_x; | |
81 Ca_Y_Axis *line_model_y; | |
82 Ca_Line *line_model_re = NULL; | |
83 double line_model_re_plot[512]; | |
84 | |
85 static int skip = 0; | |
86 | |
87 int in_ptr; | |
88 #if defined(HAVE_FFTW3_H) | |
89 double in[1024][2]; | |
90 double out[1024][2]; | |
91 #else | |
92 fftw_complex in[1024]; | |
93 fftw_complex out[1024]; | |
94 #endif | |
95 fftw_plan p; | |
96 | |
97 int line_model_monitor_can_update(const float *coeffs, int len) | |
98 { | |
99 int i; | |
100 float min; | |
101 float max; | |
102 | |
103 if (can_re) | |
104 delete can_re; | |
105 | |
106 canvas_can->current(canvas_can); | |
107 i = 0; | |
108 min = coeffs[i]; | |
109 max = coeffs[i]; | |
110 for (i = 0; i < len; i++) | |
111 { | |
112 can_re_plot[2*i] = i; | |
113 can_re_plot[2*i + 1] = coeffs[i]; | |
114 if (min > coeffs[i]) | |
115 min = coeffs[i]; | |
116 if (max < coeffs[i]) | |
117 max = coeffs[i]; | |
118 } | |
119 can_y->maximum((max == min) ? max + 0.2 : max); | |
120 can_y->minimum(min); | |
121 can_re = new Ca_Line(len, can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
122 if (++skip >= 100) | |
123 { | |
124 skip = 0; | |
125 Fl::check(); | |
126 } | |
127 return 0; | |
128 } | |
129 /*- End of function --------------------------------------------------------*/ | |
130 | |
131 int line_model_monitor_line_model_update(const float *coeffs, int len) | |
132 { | |
133 int i; | |
134 float min; | |
135 float max; | |
136 | |
137 if (line_model_re) | |
138 delete line_model_re; | |
139 | |
140 canvas_line_model->current(canvas_line_model); | |
141 i = 0; | |
142 min = coeffs[i]; | |
143 max = coeffs[i]; | |
144 for (i = 0; i < len; i++) | |
145 { | |
146 line_model_re_plot[2*i] = i; | |
147 line_model_re_plot[2*i + 1] = coeffs[i]; | |
148 if (min > coeffs[i]) | |
149 min = coeffs[i]; | |
150 if (max < coeffs[i]) | |
151 max = coeffs[i]; | |
152 } | |
153 line_model_y->maximum((max == min) ? max + 0.2 : max); | |
154 line_model_y->minimum(min); | |
155 line_model_re = new Ca_Line(len, line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
156 if (++skip >= 100) | |
157 { | |
158 skip = 0; | |
159 Fl::check(); | |
160 } | |
161 return 0; | |
162 } | |
163 /*- End of function --------------------------------------------------------*/ | |
164 | |
165 int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) | |
166 { | |
167 int i; | |
168 int x; | |
169 | |
170 for (i = 0; i < len; i++) | |
171 audio_meter->sample(amp[i]/32768.0); | |
172 | |
173 if (in_ptr + len < 512) | |
174 { | |
175 /* Just add this fragment to the buffer. */ | |
176 for (i = 0; i < len; i++) | |
177 #if defined(HAVE_FFTW3_H) | |
178 in[in_ptr + i][0] = amp[i]; | |
179 #else | |
180 in[in_ptr + i].re = amp[i]; | |
181 #endif | |
182 in_ptr += len; | |
183 return 0; | |
184 } | |
185 if (len >= 512) | |
186 { | |
187 /* We have enough for a whole block. Use the last 512 samples | |
188 we have. */ | |
189 x = len - 512; | |
190 for (i = 0; i < 512; i++) | |
191 #if defined(HAVE_FFTW3_H) | |
192 in[i][0] = amp[x + i]; | |
193 #else | |
194 in[i].re = amp[x + i]; | |
195 #endif | |
196 } | |
197 else | |
198 { | |
199 /* We want the last 512 samples. */ | |
200 x = 512 - len; | |
201 for (i = 0; i < x; i++) | |
202 #if defined(HAVE_FFTW3_H) | |
203 in[i][0] = in[in_ptr - x + i][0]; | |
204 #else | |
205 in[i].re = in[in_ptr - x + i].re; | |
206 #endif | |
207 for (i = x; i < 512; i++) | |
208 #if defined(HAVE_FFTW3_H) | |
209 in[i][0] = amp[i - x]; | |
210 #else | |
211 in[i].re = amp[i - x]; | |
212 #endif | |
213 } | |
214 in_ptr = 0; | |
215 #if defined(HAVE_FFTW3_H) | |
216 fftw_execute(p); | |
217 #else | |
218 fftw_one(p, in, out); | |
219 #endif | |
220 if (spec_re) | |
221 delete spec_re; | |
222 canvas_spec->current(canvas_spec); | |
223 for (i = 0; i < 512; i++) | |
224 { | |
225 spec_re_plot[2*i] = i*4000.0/512.0; | |
226 #if defined(HAVE_FFTW3_H) | |
227 spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1])/(256.0*32768)) + 3.14; | |
228 #else | |
229 spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i].re*out[i].re + out[i].im*out[i].im)/(256.0*32768)) + 3.14; | |
230 #endif | |
231 } | |
232 spec_re = new Ca_Line(512, spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); | |
233 Fl::check(); | |
234 return 0; | |
235 } | |
236 /*- End of function --------------------------------------------------------*/ | |
237 | |
238 int start_line_model_monitor(int len) | |
239 { | |
240 char buf[132 + 1]; | |
241 float x; | |
242 float y; | |
243 int i; | |
244 | |
245 w = new Fl_Double_Window(850, 400, "Telephone line model monitor"); | |
246 | |
247 c_spec = new Fl_Group(0, 0, 380, 400); | |
248 c_spec->box(FL_DOWN_BOX); | |
249 c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
250 | |
251 canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum"); | |
252 canvas_spec->box(FL_PLASTIC_DOWN_BOX); | |
253 canvas_spec->color(7); | |
254 canvas_spec->align(FL_ALIGN_TOP); | |
255 canvas_spec->border(15); | |
256 | |
257 spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)"); | |
258 spec_freq->align(FL_ALIGN_BOTTOM); | |
259 spec_freq->minimum(0); | |
260 spec_freq->maximum(4000); | |
261 spec_freq->label_format("%g"); | |
262 spec_freq->minor_grid_color(fl_gray_ramp(20)); | |
263 spec_freq->major_grid_color(fl_gray_ramp(15)); | |
264 spec_freq->label_grid_color(fl_gray_ramp(10)); | |
265 spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
266 spec_freq->minor_grid_style(FL_DOT); | |
267 spec_freq->major_step(5); | |
268 spec_freq->label_step(1); | |
269 spec_freq->axis_color(FL_BLACK); | |
270 spec_freq->axis_align(CA_BOTTOM | CA_LINE); | |
271 | |
272 spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)"); | |
273 spec_amp->align(FL_ALIGN_LEFT); | |
274 spec_amp->minimum(-80.0); | |
275 spec_amp->maximum(10.0); | |
276 spec_amp->minor_grid_color(fl_gray_ramp(20)); | |
277 spec_amp->major_grid_color(fl_gray_ramp(15)); | |
278 spec_amp->label_grid_color(fl_gray_ramp(10)); | |
279 //spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
280 spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
281 spec_amp->minor_grid_style(FL_DOT); | |
282 spec_amp->major_step(5); | |
283 spec_amp->label_step(1); | |
284 spec_amp->axis_color(FL_BLACK); | |
285 | |
286 spec_amp->current(); | |
287 | |
288 c_spec->end(); | |
289 | |
290 c_right = new Fl_Group(440, 0, 465, 405); | |
291 | |
292 c_can = new Fl_Group(380, 0, 415, 200); | |
293 c_can->box(FL_DOWN_BOX); | |
294 c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
295 c_can->current(); | |
296 | |
297 canvas_can = new Ca_Canvas(460, 35, 300, 100, "??? coefficients"); | |
298 canvas_can->box(FL_PLASTIC_DOWN_BOX); | |
299 canvas_can->color(7); | |
300 canvas_can->align(FL_ALIGN_TOP); | |
301 Fl_Group::current()->resizable(canvas_can); | |
302 canvas_can->border(15); | |
303 | |
304 can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap"); | |
305 can_x->align(FL_ALIGN_BOTTOM); | |
306 can_x->minimum(0.0); | |
307 can_x->maximum((float) len); | |
308 can_x->label_format("%g"); | |
309 can_x->minor_grid_color(fl_gray_ramp(20)); | |
310 can_x->major_grid_color(fl_gray_ramp(15)); | |
311 can_x->label_grid_color(fl_gray_ramp(10)); | |
312 can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
313 can_x->minor_grid_style(FL_DOT); | |
314 can_x->major_step(5); | |
315 can_x->label_step(1); | |
316 can_x->axis_align(CA_BOTTOM | CA_LINE); | |
317 can_x->axis_color(FL_BLACK); | |
318 can_x->current(); | |
319 | |
320 can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); | |
321 can_y->align(FL_ALIGN_LEFT); | |
322 can_y->minimum(-0.1); | |
323 can_y->maximum(0.1); | |
324 can_y->minor_grid_color(fl_gray_ramp(20)); | |
325 can_y->major_grid_color(fl_gray_ramp(15)); | |
326 can_y->label_grid_color(fl_gray_ramp(10)); | |
327 can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
328 can_y->minor_grid_style(FL_DOT); | |
329 can_y->major_step(5); | |
330 can_y->label_step(1); | |
331 can_y->axis_color(FL_BLACK); | |
332 can_y->current(); | |
333 | |
334 c_can->end(); | |
335 | |
336 c_line_model = new Fl_Group(380, 200, 415, 200); | |
337 c_line_model->box(FL_DOWN_BOX); | |
338 c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); | |
339 c_line_model->current(); | |
340 | |
341 canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model"); | |
342 canvas_line_model->box(FL_PLASTIC_DOWN_BOX); | |
343 canvas_line_model->color(7); | |
344 canvas_line_model->align(FL_ALIGN_TOP); | |
345 Fl_Group::current()->resizable(canvas_line_model); | |
346 canvas_line_model->border(15); | |
347 | |
348 line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap"); | |
349 line_model_x->align(FL_ALIGN_BOTTOM); | |
350 line_model_x->minimum(0.0); | |
351 line_model_x->maximum((float) len); | |
352 line_model_x->label_format("%g"); | |
353 line_model_x->minor_grid_color(fl_gray_ramp(20)); | |
354 line_model_x->major_grid_color(fl_gray_ramp(15)); | |
355 line_model_x->label_grid_color(fl_gray_ramp(10)); | |
356 line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
357 line_model_x->minor_grid_style(FL_DOT); | |
358 line_model_x->major_step(5); | |
359 line_model_x->label_step(1); | |
360 line_model_x->axis_align(CA_BOTTOM | CA_LINE); | |
361 line_model_x->axis_color(FL_BLACK); | |
362 line_model_x->current(); | |
363 | |
364 line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp"); | |
365 line_model_y->align(FL_ALIGN_LEFT); | |
366 line_model_y->minimum(-0.1); | |
367 line_model_y->maximum(0.1); | |
368 line_model_y->minor_grid_color(fl_gray_ramp(20)); | |
369 line_model_y->major_grid_color(fl_gray_ramp(15)); | |
370 line_model_y->label_grid_color(fl_gray_ramp(10)); | |
371 line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); | |
372 line_model_y->minor_grid_style(FL_DOT); | |
373 line_model_y->major_step(5); | |
374 line_model_y->label_step(1); | |
375 line_model_y->axis_color(FL_BLACK); | |
376 line_model_y->current(); | |
377 | |
378 c_line_model->end(); | |
379 | |
380 audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, ""); | |
381 audio_meter->box(FL_PLASTIC_UP_BOX); | |
382 audio_meter->type(FL_VERT_AUDIO_METER); | |
383 | |
384 c_right->end(); | |
385 | |
386 Fl_Group::current()->resizable(c_right); | |
387 w->end(); | |
388 w->show(); | |
389 | |
390 #if defined(HAVE_FFTW3_H) | |
391 p = fftw_plan_dft_1d(1024, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); | |
392 for (i = 0; i < 1024; i++) | |
393 { | |
394 in[i][0] = 0.0; | |
395 in[i][1] = 0.0; | |
396 } | |
397 #else | |
398 p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE); | |
399 for (i = 0; i < 1024; i++) | |
400 { | |
401 in[i].re = 0.0; | |
402 in[i].im = 0.0; | |
403 } | |
404 #endif | |
405 in_ptr = 0; | |
406 | |
407 Fl::check(); | |
408 return 0; | |
409 } | |
410 /*- End of function --------------------------------------------------------*/ | |
411 | |
412 void line_model_monitor_wait_to_end(void) | |
413 { | |
414 fd_set rfds; | |
415 int res; | |
416 struct timeval tv; | |
417 | |
418 fprintf(stderr, "Processing complete. Press the <enter> key to end\n"); | |
419 do | |
420 { | |
421 usleep(100000); | |
422 Fl::check(); | |
423 FD_ZERO(&rfds); | |
424 FD_SET(0, &rfds); | |
425 tv.tv_usec = 100000; | |
426 tv.tv_sec = 0; | |
427 res = select(1, &rfds, NULL, NULL, &tv); | |
428 } | |
429 while (res <= 0); | |
430 } | |
431 /*- End of function --------------------------------------------------------*/ | |
432 | |
433 void line_model_monitor_update_display(void) | |
434 { | |
435 Fl::check(); | |
436 Fl::check(); | |
437 Fl::check(); | |
438 Fl::check(); | |
439 Fl::check(); | |
440 Fl::check(); | |
441 Fl::check(); | |
442 Fl::check(); | |
443 Fl::check(); | |
444 Fl::check(); | |
445 Fl::check(); | |
446 Fl::check(); | |
447 } | |
448 /*- End of function --------------------------------------------------------*/ | |
449 #endif | |
450 /*- End of file ------------------------------------------------------------*/ |