audiodtmf.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "precompile.h"
  2. #include "audiodtmf.h"
  3. #include "audiocontext.h"
  4. #include "audiolog.h"
  5. #include "audiostream.h"
  6. #define TX_DTMF_INTERVAL 320
  7. static void process_frame(void *self)
  8. {
  9. audiodtmf_t *dtmf = CONTAINING_RECORD(self, audiodtmf_t, base);
  10. apr_status_t status;
  11. if (!dtmf->binitialized)
  12. return;
  13. if (dtmf->fin)
  14. return;
  15. dtmf->progress += FRAME_TIME;
  16. if (dtmf->bsender) { /* act as sender */
  17. if (dtmf->progress >= TX_DTMF_INTERVAL) {
  18. if (dtmf->tx_digits_offset < dtmf->tx_digits_len) { /* send one digit */
  19. status = audiortp_send_dtmf(dtmf->rtp, dtmf->tx_digits + dtmf->tx_digits_offset, 1);
  20. if (status == APR_SUCCESS) {
  21. dtmf->tx_digits_offset ++;
  22. if (dtmf->tx_digits_offset == dtmf->tx_digits_len) {
  23. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_SENT, 0, 0);
  24. dtmf->fin = 1;
  25. }
  26. } else {
  27. AUDIO_LOG_ERROR("send dtmf to rtp stream failed!");
  28. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_SENT, status, 0);
  29. dtmf->fin = 1;
  30. }
  31. }
  32. dtmf->progress -= TX_DTMF_INTERVAL;
  33. }
  34. } else { /* act as receiver */
  35. char tmp[MAX_DTMF];
  36. unsigned int tmp_cnt = MAX_DTMF;
  37. if (dtmf->rx_timeout != -1) {
  38. dtmf->rx_ellapsed += FRAME_TIME;
  39. if (dtmf->rx_ellapsed >= dtmf->rx_timeout) {
  40. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_RECV, -1, (int)&dtmf->rx_digits[0]);
  41. dtmf->fin = 1;
  42. return;
  43. }
  44. }
  45. status = audiortp_recv_dtmf(dtmf->rtp, &tmp[0], &tmp_cnt);
  46. if (status == APR_SUCCESS) {
  47. unsigned int i;
  48. for (i = 0; i < tmp_cnt; ++i) {
  49. char ch = tmp[i];
  50. if (ch == dtmf->rx_interdigit) {
  51. dtmf->rx_digits[dtmf->rx_digits_len] = 0;
  52. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_RECV, 0, (int)&dtmf->rx_digits[0]);
  53. dtmf->fin = 1;
  54. } else {
  55. dtmf->rx_digits[dtmf->rx_digits_len++] = ch;
  56. if (dtmf->rx_digits_len == dtmf->rx_maxdigits) {
  57. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_RECV, 0, (int)&dtmf->rx_digits[0]);
  58. dtmf->fin = 1;
  59. }
  60. }
  61. }
  62. } else {
  63. AUDIO_LOG_ERROR("recv dtmf from rtp stream failed!");
  64. audiodriver_raise_event(&dtmf->base, DRIVER_EVT_DTMF_RECV, status, 0);
  65. dtmf->fin = 1;
  66. }
  67. }
  68. }
  69. static audiodriver_vtbl_t g_driver_vtbl = {
  70. &process_frame,
  71. };
  72. apr_status_t audiodtmf_create(apr_pool_t *pool, audioengine_t *engine, audiodtmf_t **p_dtmf)
  73. {
  74. audiodtmf_t *dtmf;
  75. dtmf = apr_palloc(pool, sizeof(audiodtmf_t));
  76. memset(dtmf, 0, sizeof(audiodtmf_t));
  77. dtmf->rtp = NULL;
  78. dtmf->bsender = 0;
  79. dtmf->tx_digits = NULL;
  80. dtmf->tx_digits_len = 0;
  81. dtmf->tx_digits_offset = 0;
  82. dtmf->rx_maxdigits = MAX_DTMF;
  83. dtmf->rx_interval = 100; // 100ms
  84. dtmf->rx_timeout = -1;
  85. dtmf->rx_interdigit = 0;
  86. dtmf->binitialized = FALSE;
  87. dtmf->progress = 0;
  88. audiodriver_init(engine, &g_driver_vtbl, &dtmf->base);
  89. *p_dtmf = dtmf;
  90. return APR_SUCCESS;
  91. }
  92. void audiodtmf_destroy(audiodtmf_t *dtmf)
  93. {
  94. if (dtmf->tx_digits)
  95. free(dtmf->tx_digits);
  96. }
  97. apr_status_t audiodtmf_set_rtpstream(audiodtmf_t *dtmf, audiortp_t* rtp)
  98. {
  99. dtmf->rtp = rtp;
  100. return APR_SUCCESS;
  101. }
  102. apr_status_t audiodtmf_set_sender(audiodtmf_t *dtmf, int on)
  103. {
  104. dtmf->bsender = !!on;
  105. return APR_SUCCESS;
  106. }
  107. apr_status_t audiodtmf_set_txparam(audiodtmf_t *dtmf, const char *digits, int n)
  108. {
  109. if (n == -1)
  110. n = strlen(digits);
  111. dtmf->tx_digits_len = n;
  112. dtmf->tx_digits_offset = 0;
  113. dtmf->tx_digits = realloc(dtmf->tx_digits, n + 1);
  114. strncpy(dtmf->tx_digits, digits, n);
  115. return APR_SUCCESS;
  116. }
  117. apr_status_t audiodtmf_set_rxparam(audiodtmf_t *dtmf, int maxdigit, int interval, int interdigit, int timeout)
  118. {
  119. dtmf->rx_interdigit = interdigit;
  120. dtmf->rx_interval = interval;
  121. dtmf->rx_maxdigits = maxdigit;
  122. dtmf->rx_timeout = timeout;
  123. return APR_SUCCESS;
  124. }
  125. apr_status_t audiodtmf_init(audiodtmf_t *dtmf)
  126. {
  127. if (dtmf->binitialized)
  128. return APR_EAGAIN;
  129. if (!dtmf->rtp)
  130. return APR_EGENERAL;
  131. if (dtmf->bsender) {
  132. if (!dtmf->tx_digits)
  133. return APR_EGENERAL;
  134. }
  135. dtmf->binitialized = TRUE;
  136. dtmf->progress = 0;
  137. dtmf->rx_digits_len = 0;
  138. dtmf->rx_ellapsed = 0;
  139. dtmf->fin = 0;
  140. return APR_SUCCESS;
  141. }
  142. apr_status_t audiodtmf_term(audiodtmf_t *dtmf)
  143. {
  144. if (dtmf->binitialized) {
  145. dtmf->binitialized = FALSE;
  146. return APR_SUCCESS;
  147. }
  148. return APR_EGENERAL;
  149. }