dahdi_echocan_oslec.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * DAHDI Telephony Interface to the Open Source Line Echo Canceller (OSLEC)
  3. *
  4. * Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
  5. * Copyright (C) 2008 Xorcom, Inc.
  6. *
  7. * All rights reserved.
  8. *
  9. * Based on dahdi_echocan_hpec.c, Copyright (C) 2006-2008 Digium, Inc.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. */
  24. #include <linux/kernel.h>
  25. #include <linux/slab.h>
  26. #include <linux/errno.h>
  27. #include <linux/module.h>
  28. #include <linux/init.h>
  29. #include <linux/ctype.h>
  30. #include <linux/moduleparam.h>
  31. /* Fix this if OSLEC is elsewhere */
  32. #include "../staging/echo/oslec.h"
  33. //#include <linux/oslec.h>
  34. #include <dahdi/kernel.h>
  35. #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
  36. static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
  37. struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
  38. static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
  39. static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
  40. static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
  41. static const struct dahdi_echocan_factory my_factory = {
  42. .name = "OSLEC",
  43. .owner = THIS_MODULE,
  44. .echocan_create = echo_can_create,
  45. };
  46. static const struct dahdi_echocan_ops my_ops = {
  47. .name = "OSLEC",
  48. .echocan_free = echo_can_free,
  49. .echocan_process = echo_can_process,
  50. .echocan_traintap = echo_can_traintap,
  51. };
  52. struct ec_pvt {
  53. struct oslec_state *oslec;
  54. struct dahdi_echocan_state dahdi;
  55. };
  56. #define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
  57. static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
  58. {
  59. struct ec_pvt *pvt = dahdi_to_pvt(ec);
  60. oslec_free(pvt->oslec);
  61. kfree(pvt);
  62. }
  63. static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
  64. {
  65. struct ec_pvt *pvt = dahdi_to_pvt(ec);
  66. u32 SampleNum;
  67. for (SampleNum = 0; SampleNum < size; SampleNum++, iref++) {
  68. short iCleanSample;
  69. iCleanSample = oslec_update(pvt->oslec, *iref, *isig);
  70. *isig++ = iCleanSample;
  71. }
  72. }
  73. static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
  74. struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
  75. {
  76. struct ec_pvt *pvt;
  77. if (ecp->param_count > 0) {
  78. printk(KERN_WARNING "OSLEC does not support parameters; failing request\n");
  79. return -EINVAL;
  80. }
  81. pvt = kzalloc(sizeof(*pvt), GFP_KERNEL);
  82. if (!pvt)
  83. return -ENOMEM;
  84. pvt->dahdi.ops = &my_ops;
  85. pvt->oslec = oslec_create(ecp->tap_length, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CLIP | ECHO_CAN_USE_TX_HPF | ECHO_CAN_USE_RX_HPF);
  86. if (!pvt->oslec) {
  87. kfree(pvt);
  88. *ec = NULL;
  89. return -ENOTTY;
  90. } else {
  91. *ec = &pvt->dahdi;
  92. return 0;
  93. }
  94. }
  95. static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
  96. {
  97. return 1;
  98. }
  99. static int __init mod_init(void)
  100. {
  101. if (dahdi_register_echocan_factory(&my_factory)) {
  102. module_printk(KERN_ERR, "could not register with DAHDI core\n");
  103. return -EPERM;
  104. }
  105. module_printk(KERN_INFO, "Registered echo canceler '%s'\n", my_factory.name);
  106. return 0;
  107. }
  108. static void __exit mod_exit(void)
  109. {
  110. dahdi_unregister_echocan_factory(&my_factory);
  111. }
  112. MODULE_DESCRIPTION("DAHDI OSLEC wrapper");
  113. MODULE_AUTHOR("Tzafrir Cohen <tzafrir.cohen@xorcom.com>");
  114. MODULE_LICENSE("GPL");
  115. module_init(mod_init);
  116. module_exit(mod_exit);