comparison spandsp-0.0.6pre17/tests/power_meter_tests.c @ 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 * power_meter_tests.c
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2003 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: power_meter_tests.c,v 1.24 2009/05/30 15:23:14 steveu Exp $
26 */
27
28 /*! \page power_meter_tests_page Power meter tests
29 \section power_meter_tests_page_sec_1 What does it do?
30 These tests assess the accuracy of power meters built from the power meter module.
31 Both tones and noise are used to check the meter's behaviour.
32
33 \section power_meter_tests_page_sec_2 How does it work?
34 ???.
35 */
36
37 #if defined(HAVE_CONFIG_H)
38 #include <config.h>
39 #endif
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <unistd.h>
44 #include <memory.h>
45 #include <float.h>
46 #include <time.h>
47 #include <sndfile.h>
48
49 //#if defined(WITH_SPANDSP_INTERNALS)
50 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
51 //#endif
52
53 #include "spandsp.h"
54 #include "spandsp-sim.h"
55
56 #define IN_FILE_NAME "../test-data/local/short_nb_voice.wav"
57 #define OUT_FILE_NAME "power_meter_tests.wav"
58
59 static int power_surge_detector_tests(void)
60 {
61 SNDFILE *outhandle;
62 power_surge_detector_state_t *sig;
63 int i;
64 int sample;
65 int16_t amp[8000];
66 int16_t amp_out[2*8000];
67 awgn_state_t *awgnx;
68 int32_t phase_rate;
69 uint32_t phase_acc;
70 int16_t phase_scale;
71 float signal_power;
72 int32_t signal_level;
73 int signal_present;
74 int prev_signal_present;
75 int ok;
76 int extremes[4];
77
78 if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
79 {
80 fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
81 exit(2);
82 }
83 sig = power_surge_detector_init(NULL, -50.0f, 5.0f);
84 prev_signal_present = FALSE;
85
86 phase_rate = dds_phase_rate(450.0f);
87 phase_acc = 0;
88
89 phase_scale = dds_scaling_dbm0(-33.0f);
90 awgnx = awgn_init_dbm0(NULL, 1234567, -45.0f);
91
92 extremes[0] = 8001;
93 extremes[1] = -1;
94 extremes[2] = 8001;
95 extremes[3] = -1;
96 for (sample = 0; sample < 800000; sample += 8000)
97 {
98 ok = 0;
99 for (i = 0; i < 8000; i++)
100 {
101 amp[i] = awgn(awgnx);
102 if (i < 4000)
103 amp[i] += dds_mod(&phase_acc, phase_rate, phase_scale, 0);
104
105 signal_level = power_surge_detector(sig, amp[i]);
106 signal_present = (signal_level != 0);
107 if (prev_signal_present != signal_present)
108 {
109 signal_power = power_surge_detector_current_dbm0(sig);
110 if (signal_present)
111 {
112 if (ok == 0 && i >= 0 && i < 25)
113 ok = 1;
114 if (extremes[0] > i)
115 extremes[0] = i;
116 if (extremes[1] < i)
117 extremes[1] = i;
118 printf("On at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
119 }
120 else
121 {
122 if (ok == 1 && i >= 4000 + 0 && i < 4000 + 35)
123 ok = 2;
124 if (extremes[2] > i)
125 extremes[2] = i;
126 if (extremes[3] < i)
127 extremes[3] = i;
128 printf("Off at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
129 }
130 prev_signal_present = signal_present;
131 }
132 amp_out[2*i] = amp[i];
133 amp_out[2*i + 1] = signal_present*5000;
134 }
135 sf_writef_short(outhandle, amp_out, 8000);
136 if (ok != 2
137 ||
138 extremes[0] < 1
139 ||
140 extremes[1] > 30
141 ||
142 extremes[2] < 4001
143 ||
144 extremes[3] > 4030)
145 {
146 printf(" Surge not detected correctly (%d)\n", ok);
147 exit(2);
148 }
149 }
150 sf_close(outhandle);
151 printf("Min on %d, max on %d, min off %d, max off %d\n", extremes[0], extremes[1], extremes[2], extremes[3]);
152 return 0;
153 }
154 /*- End of function --------------------------------------------------------*/
155
156 static int power_surge_detector_file_test(const char *file)
157 {
158 SNDFILE *inhandle;
159 SNDFILE *outhandle;
160 int inframes;
161 power_surge_detector_state_t *sig;
162 int i;
163 int16_t amp[8000];
164 int16_t amp_out[2*8000];
165 int sample;
166 float signal_power;
167 int32_t signal_level;
168 int signal_present;
169 int prev_signal_present;
170
171 if ((inhandle = sf_open_telephony_read(file, 1)) == NULL)
172 {
173 printf(" Cannot open speech file '%s'\n", file);
174 exit(2);
175 }
176
177 if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
178 {
179 fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
180 exit(2);
181 }
182 sig = power_surge_detector_init(NULL, -50.0f, 6.0f);
183 prev_signal_present = FALSE;
184
185 sample = 0;
186 while ((inframes = sf_readf_short(inhandle, amp, 8000)))
187 {
188 for (i = 0; i < inframes; i++)
189 {
190 signal_level = power_surge_detector(sig, amp[i]);
191 signal_present = (signal_level != 0);
192 if (prev_signal_present != signal_present)
193 {
194 signal_power = power_surge_detector_current_dbm0(sig);
195 if (signal_present)
196 printf("On at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
197 else
198 printf("Off at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
199 prev_signal_present = signal_present;
200 }
201 amp_out[2*i] = amp[i];
202 amp_out[2*i + 1] = signal_present*5000;
203 }
204 sf_writef_short(outhandle, amp_out, inframes);
205 sample += inframes;
206 }
207 sf_close(inhandle);
208 sf_close(outhandle);
209 return 0;
210 }
211 /*- End of function --------------------------------------------------------*/
212
213 static int power_meter_tests(void)
214 {
215 awgn_state_t noise_source;
216 power_meter_t meter;
217 tone_gen_descriptor_t tone_desc;
218 tone_gen_state_t gen;
219 int i;
220 int idum = 1234567;
221 int16_t amp[1000];
222 int len;
223 int32_t level;
224
225 power_meter_init(&meter, 7);
226 printf("Testing with zero in the power register\n");
227 printf("Power: expected %fdBm0, got %fdBm0\n", -90.169f, power_meter_current_dbm0(&meter));
228 printf("Power: expected %fdBOv, got %fdBOv\n", -96.329f, power_meter_current_dbov(&meter));
229
230 printf("Testing with a square wave 10dB from maximum\n");
231 for (i = 0; i < 1000; i++)
232 {
233 amp[i] = (i & 1) ? 10362 : -10362;
234 level = power_meter_update(&meter, amp[i]);
235 //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter));
236 }
237 printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level);
238 printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter));
239 printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter));
240 if (level < power_meter_level_dbov(-10.0f)*0.99f
241 ||
242 level > power_meter_level_dbov(-10.0f)*1.01f)
243 {
244 printf("Test failed (level)\n");
245 exit(2);
246 }
247 if (0.1f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER))
248 {
249 printf("Test failed (dBm0)\n");
250 exit(2);
251 }
252 if (0.1f < fabsf(power_meter_current_dbov(&meter) + 10.0))
253 {
254 printf("Test failed (dBOv)\n");
255 exit(2);
256 }
257
258 printf("Testing with a sine wave tone 10dB from maximum\n");
259 make_tone_gen_descriptor(&tone_desc,
260 1000,
261 -4,
262 0,
263 1,
264 1,
265 0,
266 0,
267 0,
268 TRUE);
269 tone_gen_init(&gen, &tone_desc);
270 len = tone_gen(&gen, amp, 1000);
271 for (i = 0; i < len; i++)
272 {
273 level = power_meter_update(&meter, amp[i]);
274 //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter));
275 }
276 printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level);
277 printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter));
278 printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter));
279 if (level < power_meter_level_dbov(-10.0f)*0.95f
280 ||
281 level > power_meter_level_dbov(-10.0f)*1.05f)
282 {
283 printf("Test failed (level)\n");
284 exit(2);
285 }
286 if (0.2f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER))
287 {
288 printf("Test failed (dBm0)\n");
289 exit(2);
290 }
291 if (0.2f < fabsf(power_meter_current_dbov(&meter) + 10.0))
292 {
293 printf("Test failed (dBOv)\n");
294 exit(2);
295 }
296
297 printf("Testing with AWGN 10dB from maximum\n");
298 awgn_init_dbov(&noise_source, idum, -10.0f);
299 for (i = 0; i < 1000; i++)
300 amp[i] = awgn(&noise_source);
301 for (i = 0; i < 1000; i++)
302 {
303 level = power_meter_update(&meter, amp[i]);
304 //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter));
305 }
306 printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level);
307 printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter));
308 printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter));
309 if (level < power_meter_level_dbov(-10.0f)*0.95f
310 ||
311 level > power_meter_level_dbov(-10.0f)*1.05f)
312 {
313 printf("Test failed (level)\n");
314 exit(2);
315 }
316 if (0.2f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER))
317 {
318 printf("Test failed (dBm0)\n");
319 exit(2);
320 }
321 if (0.2f < fabsf(power_meter_current_dbov(&meter) + 10.0f))
322 {
323 printf("Test failed (dBOv)\n");
324 exit(2);
325 }
326 return 0;
327 }
328 /*- End of function --------------------------------------------------------*/
329
330 int main(int argc, char *argv[])
331 {
332 int basic_tests;
333 int decode;
334 int opt;
335 const char *in_file;
336
337 basic_tests = TRUE;
338 decode = FALSE;
339 in_file = IN_FILE_NAME;
340 while ((opt = getopt(argc, argv, "d:")) != -1)
341 {
342 switch (opt)
343 {
344 case 'd':
345 in_file = optarg;
346 basic_tests = FALSE;
347 decode = TRUE;
348 break;
349 default:
350 //usage();
351 exit(2);
352 }
353 }
354
355 if (basic_tests)
356 {
357 power_meter_tests();
358 power_surge_detector_tests();
359 }
360 if (decode)
361 {
362 power_surge_detector_file_test(in_file);
363 }
364 printf("Tests passed\n");
365 return 0;
366 }
367 /*- End of function --------------------------------------------------------*/
368 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.