Bug Summary

File:libs/spandsp/src/sig_tone.c
Location:line 560, column 37
Description:The left operand of '<' is a garbage value

Annotated Source Code

1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * sig_tone.c - Signalling tone processing for the 2280Hz, 2400Hz, 2600Hz
5 * and similar signalling tones used in older protocols.
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2004 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 2.1,
15 * as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27/*! \file */
28
29#if defined(HAVE_CONFIG_H1)
30#include "config.h"
31#endif
32
33#include <stdlib.h>
34#include <inttypes.h>
35#if defined(HAVE_TGMATH_H1)
36#include <tgmath.h>
37#endif
38#if defined(HAVE_MATH_H1)
39#include <math.h>
40#endif
41#if defined(HAVE_STDBOOL_H1)
42#include <stdbool.h>
43#else
44#include "spandsp/stdbool.h"
45#endif
46#include "floating_fudge.h"
47#include <memory.h>
48#include <string.h>
49#include <limits.h>
50
51#include "spandsp/telephony.h"
52#include "spandsp/alloc.h"
53#include "spandsp/fast_convert.h"
54#include "spandsp/saturated.h"
55#include "spandsp/vector_int.h"
56#include "spandsp/complex.h"
57#include "spandsp/power_meter.h"
58#include "spandsp/dds.h"
59#include "spandsp/super_tone_rx.h"
60#include "spandsp/sig_tone.h"
61
62#include "spandsp/private/power_meter.h"
63#include "spandsp/private/sig_tone.h"
64
65/*! PI */
66#define PI3.14159265358979323 3.14159265358979323
67
68enum
69{
70 NOTCH_COEFF_SET_2280HZ = 0,
71 NOTCH_COEFF_SET_2400HZ,
72 NOTCH_COEFF_SET_2600HZ
73};
74
75/* The coefficients for the data notch filters. These filters are also the
76 guard filters for tone detection. */
77static const sig_tone_notch_coeffs_t notch_coeffs[3] =
78{
79 { /* 2280 Hz */
80#if defined(SPANDSP_USE_FIXED_POINT)
81 { 3600, 14397, 32767},
82 { 0, -9425, -28954},
83 { 0, 14196, 32767},
84 { 0, -17393, -28954},
85 12,
86#else
87 {0.878906f, 0.439362f, 1.0f},
88 {0.0f, -0.287627f, -0.883605f},
89 {0.0f, 0.433228f, 1.0f},
90 {0.0f, -0.530792f, -0.883605f},
91#endif
92 },
93 { /* 2400Hz */
94#if defined(SPANDSP_USE_FIXED_POINT)
95 { 3530, 20055, 32767},
96 { 0, -14950, -28341},
97 { 0, 20349, 32767},
98 { 0, -22633, -28341},
99 12,
100#else
101 {0.862000f, 0.612055f, 1.0f},
102 {0.0f, -0.456264f, -0.864899f},
103 {0.0f, 0.621021f, 1.0f},
104 {0.0f, -0.690738f, -0.864899f},
105#endif
106 },
107 { /* 2600Hz */
108#if defined(SPANDSP_USE_FIXED_POINT)
109 { 3530, 29569, 32767},
110 { 0, -24010, -28341},
111 { 0, 29844, 32767},
112 { 0, -31208, -28341},
113 12,
114#else
115 {0.862000f, 0.902374f, 1.0f},
116 {0.0f, -0.732727f, -0.864899f},
117 {0.0f, 0.910766f, 1.0f},
118 {0.0f, -0.952393f, -0.864899f},
119#endif
120 }
121};
122
123static const sig_tone_flat_coeffs_t flat_coeffs[1] =
124{
125 {
126#if defined(SPANDSP_USE_FIXED_POINT)
127 { 12900, -16384, -16384},
128 { 0, -8578, -11796},
129 15,
130#else
131 {0.393676f, -0.5f, -0.5f},
132 {0.0f, -0.261778f, -0.359985f},
133#endif
134 }
135};
136
137static const sig_tone_descriptor_t sig_tones[3] =
138{
139 {
140 /* 2280Hz (e.g. AC15, and many other European protocols) */
141 {2280, 0},
142 {{-10, -20}, {0, 0}}, /* -10+-1 dBm0 and -20+-1 dBm0 */
143 ms_to_samples(400)((400)*(8000/1000)), /* High to low timout - 300ms to 550ms */
144 ms_to_samples(225)((225)*(8000/1000)), /* Sharp to flat timeout */
145 ms_to_samples(225)((225)*(8000/1000)), /* Notch insertion timeout */
146
147 ms_to_samples(3)((3)*(8000/1000)), /* Tone on persistence check */
148 ms_to_samples(8)((8)*(8000/1000)), /* Tone off persistence check */
149
150 1,
151 {
152 &notch_coeffs[NOTCH_COEFF_SET_2280HZ],
153 NULL((void*)0),
154 },
155 &flat_coeffs[NOTCH_COEFF_SET_2280HZ],
156
157#if defined(SPANDSP_USE_FIXED_POINT)
158 13,
159 -30,
160 -30
161#else
162 13.0f,
163 -30.0f,
164 -30.0f
165#endif
166 },
167 {
168 /* 2600Hz (e.g. many US protocols) */
169 {2600, 0},
170 {{-8, -8}, {0, 0}},
171 ms_to_samples(0)((0)*(8000/1000)),
172 ms_to_samples(0)((0)*(8000/1000)),
173 ms_to_samples(225)((225)*(8000/1000)),
174
175 ms_to_samples(3)((3)*(8000/1000)),
176 ms_to_samples(8)((8)*(8000/1000)),
177
178 1,
179 {
180 &notch_coeffs[NOTCH_COEFF_SET_2600HZ],
181 NULL((void*)0),
182 },
183 NULL((void*)0),
184
185#if defined(SPANDSP_USE_FIXED_POINT)
186 16,
187 -30,
188 -30
189#else
190 15.6f,
191 -30.0f,
192 -30.0f
193#endif
194 },
195 {
196 /* 2400Hz/2600Hz (e.g. SS5 and SS5bis) */
197 {2400, 2600},
198 {{-8, -8}, {-8, -8}},
199 ms_to_samples(0)((0)*(8000/1000)),
200 ms_to_samples(0)((0)*(8000/1000)),
201 ms_to_samples(225)((225)*(8000/1000)),
202
203 ms_to_samples(3)((3)*(8000/1000)),
204 ms_to_samples(8)((8)*(8000/1000)),
205
206 2,
207 {
208 &notch_coeffs[NOTCH_COEFF_SET_2400HZ],
209 &notch_coeffs[NOTCH_COEFF_SET_2600HZ]
210 },
211 NULL((void*)0),
212
213#if defined(SPANDSP_USE_FIXED_POINT)
214 16,
215 -30,
216 -30
217#else
218 15.6f,
219 -30.0f,
220 -30.0f
221#endif
222 }
223};
224
225static const int tone_present_bits[3] =
226{
227 SIG_TONE_1_PRESENT,
228 SIG_TONE_2_PRESENT,
229 SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT
230};
231
232static const int tone_change_bits[3] =
233{
234 SIG_TONE_1_CHANGE,
235 SIG_TONE_2_CHANGE,
236 SIG_TONE_1_CHANGE | SIG_TONE_2_CHANGE
237};
238
239static const int coeff_sets[3] =
240{
241 0,
242 1,
243 0
244};
245
246SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
247{
248 int i;
249 int j;
250 int k;
251 int n;
252 int16_t tone;
253 bool_Bool need_update;
254 int high_low;
255
256 for (i = 0; i < len; i += n)
257 {
258 if (s->current_tx_timeout)
259 {
260 if (s->current_tx_timeout <= len - i)
261 {
262 n = s->current_tx_timeout;
263 need_update = true1;
264 }
265 else
266 {
267 n = len - i;
268 need_update = false0;
269 }
270 s->current_tx_timeout -= n;
271 }
272 else
273 {
274 n = len - i;
275 need_update = false0;
276 }
277 if (!(s->current_tx_tone & SIG_TONE_TX_PASSTHROUGH))
278 vec_zeroi16(&amp[i], n);
279 /*endif*/
280 if ((s->current_tx_tone & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
281 {
282 /* Are we in the early phase (high tone energy level), or the sustaining
283 phase (low tone energy level) of tone generation? */
284 /* This doesn't try to get the high/low timing precise, as there is no
285 value in doing so. It works block by block, and the blocks are normally
286 quite short. */
287 if (s->high_low_timer > 0)
288 {
289 if (n > s->high_low_timer)
290 n = s->high_low_timer;
291 s->high_low_timer -= n;
292 high_low = 0;
293 }
294 else
295 {
296 high_low = 1;
297 }
298 /*endif*/
299 for (k = 0; k < s->desc->tones; k++)
300 {
301 if ((s->current_tx_tone & tone_present_bits[k]) && s->phase_rate[k])
302 {
303 for (j = i; j < i + n; j++)
304 {
305 tone = dds_mod(&s->phase_acc[k], s->phase_rate[k], s->tone_scaling[k][high_low], 0);
306 amp[j] = sat_add16(amp[j], tone);
307 }
308 /*endfor*/
309 }
310 /*endif*/
311 }
312 }
313 /*endif*/
314 if (need_update && s->sig_update)
315 s->sig_update(s->user_data, SIG_TONE_TX_UPDATE_REQUEST, 0, 0);
316 /*endif*/
317 }
318 /*endfor*/
319 return len;
320}
321/*- End of function --------------------------------------------------------*/
322
323SPAN_DECLARE(void)__attribute__((visibility("default"))) void sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode, int duration)
324{
325 int old_tones;
326 int new_tones;
327
328 old_tones = s->current_tx_tone & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT);
329 new_tones = mode & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT);
330 if (new_tones && old_tones != new_tones)
331 s->high_low_timer = s->desc->high_low_timeout;
332 /*endif*/
333 /* If a tone is being turned on, let's start the phase from zero */
334 if ((mode & SIG_TONE_1_PRESENT) && !(s->current_tx_tone & SIG_TONE_1_PRESENT))
335 s->phase_acc[0] = 0;
336 if ((mode & SIG_TONE_2_PRESENT) && !(s->current_tx_tone & SIG_TONE_2_PRESENT))
337 s->phase_acc[1] = 0;
338 s->current_tx_tone = mode;
339 s->current_tx_timeout = duration;
340}
341/*- End of function --------------------------------------------------------*/
342
343SPAN_DECLARE(sig_tone_tx_state_t *)__attribute__((visibility("default"))) sig_tone_tx_state_t * sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data)
344{
345 int i;
346
347 if (sig_update == NULL((void*)0) || tone_type < 1 || tone_type > 3)
348 return NULL((void*)0);
349 /*endif*/
350
351 if (s == NULL((void*)0))
352 {
353 if ((s = (sig_tone_tx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0))
354 return NULL((void*)0);
355 }
356 memset(s, 0, sizeof(*s));
357
358 s->sig_update = sig_update;
359 s->user_data = user_data;
360
361 s->desc = &sig_tones[tone_type - 1];
362
363 for (i = 0; i < 2; i++)
364 {
365 if (s->desc->tone_freq[i])
366 s->phase_rate[i] = dds_phase_rate((float) s->desc->tone_freq[i]);
367 else
368 s->phase_rate[i] = 0;
369 s->tone_scaling[i][0] = dds_scaling_dbm0((float) s->desc->tone_amp[i][0]);
370 s->tone_scaling[i][1] = dds_scaling_dbm0((float) s->desc->tone_amp[i][1]);
371 }
372 return s;
373}
374/*- End of function --------------------------------------------------------*/
375
376SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_tx_release(sig_tone_tx_state_t *s)
377{
378 return 0;
379}
380/*- End of function --------------------------------------------------------*/
381
382SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_tx_free(sig_tone_tx_state_t *s)
383{
384 if (s)
385 span_free(s);
386 return 0;
387}
388/*- End of function --------------------------------------------------------*/
389
390int nnn = 0;
391
392SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
393{
394#if defined(SPANDSP_USE_FIXED_POINT)
395 int16_t x;
396 int32_t v;
397 int16_t notched_signal[3];
398 int16_t bandpass_signal;
399 int16_t signal;
400#else
401 float x;
402 float v;
403 float notched_signal[3];
404 float bandpass_signal;
405 float signal;
406#endif
407 int i;
408 int j;
409 int k;
410 int l;
411 int m;
412 int32_t notch_power[3];
413 int32_t flat_power;
414 int immediate;
415
416 l = s->desc->tones;
417 if (l == 2)
1
Assuming 'l' is not equal to 2
2
Taking false branch
418 l = 3;
419 notch_power[1] =
420 notch_power[2] = INT32_MAX(2147483647);
421 for (i = 0; i < len; i++)
3
Assuming 'i' is < 'len'
4
Loop condition is true. Entering loop body
15
Assuming 'i' is < 'len'
16
Loop condition is true. Entering loop body
26
Assuming 'i' is < 'len'
27
Loop condition is true. Entering loop body
37
Assuming 'i' is < 'len'
38
Loop condition is true. Entering loop body
422 {
423 if (s->signalling_state_duration < INT_MAX2147483647)
5
Taking false branch
17
Taking false branch
28
Taking false branch
39
Taking false branch
424 s->signalling_state_duration++;
425 /*endif*/
426 signal = amp[i];
427 for (j = 0; j < l; j++)
6
Assuming 'j' is >= 'l'
7
Loop condition is false. Execution continues on line 473
18
Loop condition is false. Execution continues on line 473
29
Loop condition is false. Execution continues on line 473
40
Loop condition is false. Execution continues on line 473
428 {
429 k = coeff_sets[j];
430 /* The notch filter is two cascaded biquads. */
431#if defined(SPANDSP_USE_FIXED_POINT)
432 v = ((int32_t) signal*s->desc->notch[k]->a1[0])
433 + ((int32_t) s->tone[j].notch_z1[0]*s->desc->notch[k]->b1[1])
434 + ((int32_t) s->tone[j].notch_z1[1]*s->desc->notch[k]->b1[2]);
435 x = v >> 15;
436 v += ((int32_t) s->tone[j].notch_z1[0]*s->desc->notch[k]->a1[1])
437 + ((int32_t) s->tone[j].notch_z1[1]*s->desc->notch[k]->a1[2]);
438 s->tone[j].notch_z1[1] = s->tone[j].notch_z1[0];
439 s->tone[j].notch_z1[0] = x;
440 v += ((int32_t) s->tone[j].notch_z2[0]*s->desc->notch[k]->b2[1])
441 + ((int32_t) s->tone[j].notch_z2[1]*s->desc->notch[k]->b2[2]);
442 x = v >> 15;
443 v += ((int32_t) s->tone[j].notch_z2[0]*s->desc->notch[k]->a2[1])
444 + ((int32_t) s->tone[j].notch_z2[1]*s->desc->notch[k]->a2[2]);
445 s->tone[j].notch_z2[1] = s->tone[j].notch_z2[0];
446 s->tone[j].notch_z2[0] = x;
447 notched_signal[j] = v >> s->desc->notch[k]->postscale;
448#else
449 v = signal*s->desc->notch[k]->a1[0]
450 + s->tone[j].notch_z1[0]*s->desc->notch[k]->b1[1]
451 + s->tone[j].notch_z1[1]*s->desc->notch[k]->b1[2];
452 x = v;
453 v += s->tone[j].notch_z1[0]*s->desc->notch[k]->a1[1]
454 + s->tone[j].notch_z1[1]*s->desc->notch[k]->a1[2];
455 s->tone[j].notch_z1[1] = s->tone[j].notch_z1[0];
456 s->tone[j].notch_z1[0] = x;
457 v += s->tone[j].notch_z2[0]*s->desc->notch[k]->b2[1]
458 + s->tone[j].notch_z2[1]*s->desc->notch[k]->b2[2];
459 x = v;
460 v += s->tone[j].notch_z2[0]*s->desc->notch[k]->a2[1]
461 + s->tone[j].notch_z2[1]*s->desc->notch[k]->a2[2];
462 s->tone[j].notch_z2[1] = s->tone[j].notch_z2[0];
463 s->tone[j].notch_z2[0] = x;
464 notched_signal[j] = v;
465#endif
466 /* Modulus and leaky integrate the notched data. The result of
467 this isn't used in low tone detect mode, but we must keep the
468 power measurement rolling along. */
469 notch_power[j] = power_meter_update(&s->tone[j].power, notched_signal[j]);
470 if (j == 1)
471 signal = notched_signal[j];
472 }
473 if ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
8
Taking false branch
19
Taking false branch
30
Taking false branch
41
Taking false branch
474 {
475 if (s->flat_mode_timeout && --s->flat_mode_timeout == 0)
476 s->flat_mode = true1;
477 /*endif*/
478 }
479 else
480 {
481 s->flat_mode_timeout = s->desc->sharp_flat_timeout;
482 s->flat_mode = false0;
483 }
484 /*endif*/
485
486 immediate = -1;
487 if (s->flat_mode)
9
Taking false branch
20
Taking false branch
31
Taking false branch
42
Taking false branch
488 {
489 //printf("Flat mode %d %d\n", s->flat_mode_timeout, s->desc->sharp_flat_timeout);
490 /* Flat mode */
491 bandpass_signal = amp[i];
492 if (s->desc->flat)
493 {
494 /* The bandpass filter is a single bi-quad stage */
495#if defined(SPANDSP_USE_FIXED_POINT)
496 v = ((int32_t) amp[i]*s->desc->flat->a[0])
497 + ((int32_t) s->flat_z[0]*s->desc->flat->b[1])
498 + ((int32_t) s->flat_z[1]*s->desc->flat->b[2]);
499 x = v >> 15;
500 v += ((int32_t) s->flat_z[0]*s->desc->flat->a[1])
501 + ((int32_t) s->flat_z[1]*s->desc->flat->a[2]);
502 s->flat_z[1] = s->flat_z[0];
503 s->flat_z[0] = x;
504 bandpass_signal = v >> s->desc->flat->postscale;
505#else
506 v = amp[i]*s->desc->flat->a[0]
507 + s->flat_z[0]*s->desc->flat->b[1]
508 + s->flat_z[1]*s->desc->flat->b[2];
509 x = v;
510 v += s->flat_z[0]*s->desc->flat->a[1]
511 + s->flat_z[1]*s->desc->flat->a[2];
512 s->flat_z[1] = s->flat_z[0];
513 s->flat_z[0] = x;
514 bandpass_signal = v;
515#endif
516 }
517 flat_power = power_meter_update(&s->flat_power, bandpass_signal);
518
519 /* For the flat receiver we use a simple power threshold! */
520 if ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
521 {
522 if (flat_power < s->flat_detection_threshold)
523 {
524 s->signalling_state &= ~tone_present_bits[0];
525 s->signalling_state |= tone_change_bits[0];
526 }
527 /*endif*/
528 }
529 else
530 {
531 if (flat_power > s->flat_detection_threshold)
532 s->signalling_state |= (tone_present_bits[0] | tone_change_bits[0]);
533 /*endif*/
534 }
535 /*endif*/
536
537 /* Notch insertion logic */
538 /* tone_present and tone_on are equivalent in flat mode */
539 if ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
540 {
541 s->notch_insertion_timeout = s->desc->notch_lag_time;
542 }
543 else
544 {
545 if (s->notch_insertion_timeout)
546 s->notch_insertion_timeout--;
547 /*endif*/
548 }
549 /*endif*/
550 }
551 else
552 {
553 /* Sharp mode */
554 flat_power = power_meter_update(&s->flat_power, amp[i]);
555
556 /* Persistence checking and notch insertion logic */
557 if (flat_power >= s->sharp_detection_threshold)
10
Taking false branch
21
Taking false branch
32
Taking false branch
43
Taking true branch
558 {
559 /* Which is the better of the single tone responses? */
560 m = (notch_power[0] < notch_power[1]) ? 0 : 1;
44
The left operand of '<' is a garbage value
561 /* Single tone has precedence. If the better one fails to detect, try
562 for a dual tone signal. */
563 if ((notch_power[m] >> 6)*s->detection_ratio < (flat_power >> 6))
564 immediate = m;
565 else if ((notch_power[2] >> 6)*s->detection_ratio < (flat_power >> 7))
566 immediate = 2;
567 }
568 //printf("Immediate = %d %d %d\n", immediate, s->signalling_state, s->tone_persistence_timeout);
569 if ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
11
Taking false branch
22
Taking false branch
33
Taking false branch
570 {
571 if (immediate != s->current_notch_filter)
572 {
573 /* No tone is detected this sample */
574 if (--s->tone_persistence_timeout == 0)
575 {
576 /* Tone off is confirmed */
577 s->tone_persistence_timeout = s->desc->tone_on_check_time;
578 s->signalling_state |= ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)) << 1);
579 s->signalling_state &= ~(SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT);
580 }
581 /*endif*/
582 }
583 else
584 {
585 s->tone_persistence_timeout = s->desc->tone_off_check_time;
586 }
587 /*endif*/
588 }
589 else
590 {
591 if (s->notch_insertion_timeout)
12
Taking false branch
23
Taking false branch
34
Taking false branch
592 s->notch_insertion_timeout--;
593 /*endif*/
594 if (immediate >= 0 && immediate == s->last_sample_tone_present)
595 {
596 /* Consistent tone detected this sample */
597 if (--s->tone_persistence_timeout == 0)
598 {
599 /* Tone on is confirmed */
600 s->tone_persistence_timeout = s->desc->tone_off_check_time;
601 s->notch_insertion_timeout = s->desc->notch_lag_time;
602 s->signalling_state |= (tone_present_bits[immediate] | tone_change_bits[immediate]);
603 s->current_notch_filter = immediate;
604 }
605 /*endif*/
606 }
607 else
608 {
609 s->tone_persistence_timeout = s->desc->tone_on_check_time;
610 }
611 /*endif*/
612 }
613 /*endif*/
614 //printf("XXX %d %d %d %d %d %d\n", nnn++, notch_power[0], notch_power[1], notch_power[2], flat_power, immediate*10000000);
615 }
616 /*endif*/
617 if ((s->signalling_state & (SIG_TONE_1_CHANGE | SIG_TONE_2_CHANGE)))
13
Taking false branch
24
Taking false branch
35
Taking false branch
618 {
619 if (s->sig_update)
620 s->sig_update(s->user_data, s->signalling_state, 0, s->signalling_state_duration);
621 /*endif*/
622 s->signalling_state &= ~(SIG_TONE_1_CHANGE | SIG_TONE_2_CHANGE);
623 s->signalling_state_duration = 0;
624 }
625 /*endif*/
626
627 if ((s->current_rx_tone & SIG_TONE_RX_PASSTHROUGH))
14
Taking false branch
25
Taking false branch
36
Taking false branch
628 {
629 if ((s->current_rx_tone & SIG_TONE_RX_FILTER_TONE) || s->notch_insertion_timeout)
630#if defined(SPANDSP_USE_FIXED_POINT)
631 amp[i] = saturate16(notched_signal[s->current_notch_filter]);
632#else
633 amp[i] = fsaturatef(notched_signal[s->current_notch_filter]);
634#endif
635 /*endif*/
636 }
637 else
638 {
639 /* Simply mute the media path */
640 amp[i] = 0;
641 }
642 /*endif*/
643 s->last_sample_tone_present = immediate;
644 }
645 /*endfor*/
646 return len;
647}
648/*- End of function --------------------------------------------------------*/
649
650SPAN_DECLARE(void)__attribute__((visibility("default"))) void sig_tone_rx_set_mode(sig_tone_rx_state_t *s, int mode, int duration)
651{
652 s->current_rx_tone = mode;
653}
654/*- End of function --------------------------------------------------------*/
655
656SPAN_DECLARE(sig_tone_rx_state_t *)__attribute__((visibility("default"))) sig_tone_rx_state_t * sig_tone_rx_init(sig_tone_rx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data)
657{
658 int i;
659#if !defined(SPANDSP_USE_FIXED_POINT)
660 int j;
661#endif
662
663 if (sig_update == NULL((void*)0) || tone_type < 1 || tone_type > 3)
664 return NULL((void*)0);
665 /*endif*/
666
667 if (s == NULL((void*)0))
668 {
669 if ((s = (sig_tone_rx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0))
670 return NULL((void*)0);
671 }
672 memset(s, 0, sizeof(*s));
673#if !defined(SPANDSP_USE_FIXED_POINT)
674 for (j = 0; j < 3; j++)
675 {
676 for (i = 0; i < 2; i++)
677 {
678 s->tone[j].notch_z1[i] = 0.0f;
679 s->tone[j].notch_z2[i] = 0.0f;
680 }
681 }
682 for (i = 0; i < 2; i++)
683 s->flat_z[i] = 0.0f;
684#endif
685 s->last_sample_tone_present = -1;
686
687 s->sig_update = sig_update;
688 s->user_data = user_data;
689
690 s->desc = &sig_tones[tone_type - 1];
691
692 for (i = 0; i < 3; i++)
693 power_meter_init(&s->tone[i].power, 5);
694 power_meter_init(&s->flat_power, 5);
695
696 s->flat_detection_threshold = power_meter_level_dbm0(s->desc->flat_detection_threshold);
697 s->sharp_detection_threshold = power_meter_level_dbm0(s->desc->sharp_detection_threshold);
698 s->detection_ratio = powf(10.0f, s->desc->detection_ratio/10.0f) + 1.0f;
699
700 return s;
701}
702/*- End of function --------------------------------------------------------*/
703
704SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_rx_release(sig_tone_rx_state_t *s)
705{
706 return 0;
707}
708/*- End of function --------------------------------------------------------*/
709
710SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_rx_free(sig_tone_rx_state_t *s)
711{
712 if (s)
713 span_free(s);
714 return 0;
715}
716/*- End of function --------------------------------------------------------*/
717/*- End of file ------------------------------------------------------------*/