1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
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 | |
66 | #define PI3.14159265358979323 3.14159265358979323 |
67 | |
68 | enum |
69 | { |
70 | NOTCH_COEFF_SET_2280HZ = 0, |
71 | NOTCH_COEFF_SET_2400HZ, |
72 | NOTCH_COEFF_SET_2600HZ |
73 | }; |
74 | |
75 | |
76 | |
77 | static const sig_tone_notch_coeffs_t notch_coeffs[3] = |
78 | { |
79 | { |
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 | { |
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 | { |
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 | |
123 | static 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 | |
137 | static const sig_tone_descriptor_t sig_tones[3] = |
138 | { |
139 | { |
140 | |
141 | {2280, 0}, |
142 | {{-10, -20}, {0, 0}}, |
143 | ms_to_samples(400)((400)*(8000/1000)), |
144 | ms_to_samples(225)((225)*(8000/1000)), |
145 | ms_to_samples(225)((225)*(8000/1000)), |
146 | |
147 | ms_to_samples(3)((3)*(8000/1000)), |
148 | ms_to_samples(8)((8)*(8000/1000)), |
149 | |
150 | 1, |
151 | { |
152 | ¬ch_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 | |
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 | ¬ch_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 | |
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 | ¬ch_coeffs[NOTCH_COEFF_SET_2400HZ], |
209 | ¬ch_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 | |
225 | static 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 | |
232 | static 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 | |
239 | static const int coeff_sets[3] = |
240 | { |
241 | 0, |
242 | 1, |
243 | 0 |
244 | }; |
245 | |
246 | SPAN_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(&[i], n); |
279 | |
280 | if ((s->current_tx_tone & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT))) |
281 | { |
282 | |
283 | |
284 | |
285 | |
286 | |
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 | |
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 | |
309 | } |
310 | |
311 | } |
312 | } |
313 | |
314 | if (need_update && s->sig_update) |
315 | s->sig_update(s->user_data, SIG_TONE_TX_UPDATE_REQUEST, 0, 0); |
316 | |
317 | } |
318 | |
319 | return len; |
320 | } |
321 | |
322 | |
323 | SPAN_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 | |
333 | |
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 | |
342 | |
343 | SPAN_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 | |
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 | |
375 | |
376 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_tx_release(sig_tone_tx_state_t *s) |
377 | { |
378 | return 0; |
379 | } |
380 | |
381 | |
382 | SPAN_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 | |
389 | |
390 | int nnn = 0; |
391 | |
392 | SPAN_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 | |
|
| |
418 | l = 3; |
419 | notch_power[1] = |
420 | notch_power[2] = INT32_MAX(2147483647); |
421 | for (i = 0; i < len; i++) |
| |
| 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) |
| |
| |
| |
| |
424 | s->signalling_state_duration++; |
425 | |
426 | signal = amp[i]; |
427 | for (j = 0; j < l; j++) |
| |
| 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 | |
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 | |
467 | |
468 | |
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))) |
| |
| |
| |
| |
474 | { |
475 | if (s->flat_mode_timeout && --s->flat_mode_timeout == 0) |
476 | s->flat_mode = true1; |
477 | |
478 | } |
479 | else |
480 | { |
481 | s->flat_mode_timeout = s->desc->sharp_flat_timeout; |
482 | s->flat_mode = false0; |
483 | } |
484 | |
485 | |
486 | immediate = -1; |
487 | if (s->flat_mode) |
| |
| |
| |
| |
488 | { |
489 | |
490 | |
491 | bandpass_signal = amp[i]; |
492 | if (s->desc->flat) |
493 | { |
494 | |
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 | |
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 | |
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 | |
534 | } |
535 | |
536 | |
537 | |
538 | |
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 | |
548 | } |
549 | |
550 | } |
551 | else |
552 | { |
553 | |
554 | flat_power = power_meter_update(&s->flat_power, amp[i]); |
555 | |
556 | |
557 | if (flat_power >= s->sharp_detection_threshold) |
| |
| |
| |
| |
558 | { |
559 | |
560 | m = (notch_power[0] < notch_power[1]) ? 0 : 1; |
| 44 | | The left operand of '<' is a garbage value |
|
561 | |
562 | |
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 | |
569 | if ((s->signalling_state & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT))) |
| |
| |
| |
570 | { |
571 | if (immediate != s->current_notch_filter) |
572 | { |
573 | |
574 | if (--s->tone_persistence_timeout == 0) |
575 | { |
576 | |
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 | |
582 | } |
583 | else |
584 | { |
585 | s->tone_persistence_timeout = s->desc->tone_off_check_time; |
586 | } |
587 | |
588 | } |
589 | else |
590 | { |
591 | if (s->notch_insertion_timeout) |
| |
| |
| |
592 | s->notch_insertion_timeout--; |
593 | |
594 | if (immediate >= 0 && immediate == s->last_sample_tone_present) |
595 | { |
596 | |
597 | if (--s->tone_persistence_timeout == 0) |
598 | { |
599 | |
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 | |
606 | } |
607 | else |
608 | { |
609 | s->tone_persistence_timeout = s->desc->tone_on_check_time; |
610 | } |
611 | |
612 | } |
613 | |
614 | |
615 | } |
616 | |
617 | if ((s->signalling_state & (SIG_TONE_1_CHANGE | SIG_TONE_2_CHANGE))) |
| |
| |
| |
618 | { |
619 | if (s->sig_update) |
620 | s->sig_update(s->user_data, s->signalling_state, 0, s->signalling_state_duration); |
621 | |
622 | s->signalling_state &= ~(SIG_TONE_1_CHANGE | SIG_TONE_2_CHANGE); |
623 | s->signalling_state_duration = 0; |
624 | } |
625 | |
626 | |
627 | if ((s->current_rx_tone & SIG_TONE_RX_PASSTHROUGH)) |
| |
| |
| |
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 | |
636 | } |
637 | else |
638 | { |
639 | |
640 | amp[i] = 0; |
641 | } |
642 | |
643 | s->last_sample_tone_present = immediate; |
644 | } |
645 | |
646 | return len; |
647 | } |
648 | |
649 | |
650 | SPAN_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 | |
655 | |
656 | SPAN_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 | |
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 | |
703 | |
704 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int sig_tone_rx_release(sig_tone_rx_state_t *s) |
705 | { |
706 | return 0; |
707 | } |
708 | |
709 | |
710 | SPAN_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 | |
717 | |