dsp_ecdis.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * SpanDSP - a series of DSP components for telephony
  4. *
  5. * ec_disable_detector.h - A detector which should eventually meet the
  6. * G.164/G.165 requirements for detecting the
  7. * 2100Hz echo cancellor disable tone.
  8. *
  9. * Written by Steve Underwood <[email protected]>
  10. *
  11. * Copyright (C) 2001 Steve Underwood
  12. *
  13. * All rights reserved.
  14. */
  15. #include "dsp_biquad.h"
  16. struct ec_disable_detector_state {
  17. struct biquad2_state notch;
  18. int notch_level;
  19. int channel_level;
  20. int tone_present;
  21. int tone_cycle_duration;
  22. int good_cycles;
  23. int hit;
  24. };
  25. #define FALSE 0
  26. #define TRUE (!FALSE)
  27. static inline void
  28. echo_can_disable_detector_init(struct ec_disable_detector_state *det)
  29. {
  30. /* Elliptic notch */
  31. /* This is actually centred at 2095Hz, but gets the balance we want, due
  32. to the asymmetric walls of the notch */
  33. biquad2_init(&det->notch,
  34. (int32_t)(-0.7600000 * 32768.0),
  35. (int32_t)(-0.1183852 * 32768.0),
  36. (int32_t)(-0.5104039 * 32768.0),
  37. (int32_t)(0.1567596 * 32768.0),
  38. (int32_t)(1.0000000 * 32768.0));
  39. det->channel_level = 0;
  40. det->notch_level = 0;
  41. det->tone_present = FALSE;
  42. det->tone_cycle_duration = 0;
  43. det->good_cycles = 0;
  44. det->hit = 0;
  45. }
  46. /*- End of function --------------------------------------------------------*/
  47. static inline int
  48. echo_can_disable_detector_update(struct ec_disable_detector_state *det,
  49. int16_t amp)
  50. {
  51. int16_t notched;
  52. notched = biquad2(&det->notch, amp);
  53. /* Estimate the overall energy in the channel, and the energy in
  54. the notch (i.e. overall channel energy - tone energy => noise).
  55. Use abs instead of multiply for speed (is it really faster?).
  56. Damp the overall energy a little more for a stable result.
  57. Damp the notch energy a little less, so we don't damp out the
  58. blip every time the phase reverses */
  59. det->channel_level += ((abs(amp) - det->channel_level) >> 5);
  60. det->notch_level += ((abs(notched) - det->notch_level) >> 4);
  61. if (det->channel_level > 280) {
  62. /* There is adequate energy in the channel.
  63. Is it mostly at 2100Hz? */
  64. if (det->notch_level * 6 < det->channel_level) {
  65. /* The notch says yes, so we have the tone. */
  66. if (!det->tone_present) {
  67. /* Do we get a kick every 450+-25ms? */
  68. if (det->tone_cycle_duration >= 425 * 8
  69. && det->tone_cycle_duration <= 475 * 8) {
  70. det->good_cycles++;
  71. if (det->good_cycles > 2)
  72. det->hit = TRUE;
  73. }
  74. det->tone_cycle_duration = 0;
  75. }
  76. det->tone_present = TRUE;
  77. } else
  78. det->tone_present = FALSE;
  79. det->tone_cycle_duration++;
  80. } else {
  81. det->tone_present = FALSE;
  82. det->tone_cycle_duration = 0;
  83. det->good_cycles = 0;
  84. }
  85. return det->hit;
  86. }
  87. /*- End of function --------------------------------------------------------*/
  88. /*- End of file ------------------------------------------------------------*/