smoother.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Frame smoother manipulation routines
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include "asterisk/_private.h"
  30. #include "asterisk/frame.h"
  31. #include "asterisk/astobj2.h"
  32. #include "asterisk/time.h"
  33. #include "asterisk/utils.h"
  34. #include "asterisk/format.h"
  35. #include "asterisk/codec.h"
  36. #include "asterisk/smoother.h"
  37. #define SMOOTHER_SIZE 8000
  38. struct ast_smoother {
  39. int size;
  40. struct ast_format *format;
  41. int flags;
  42. float samplesperbyte;
  43. unsigned int opt_needs_swap:1;
  44. struct ast_frame f;
  45. struct timeval delivery;
  46. char data[SMOOTHER_SIZE];
  47. char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
  48. struct ast_frame *opt;
  49. int len;
  50. };
  51. static int smoother_frame_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
  52. {
  53. if (s->flags & AST_SMOOTHER_FLAG_G729) {
  54. if (s->len % 10) {
  55. ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
  56. return 0;
  57. }
  58. }
  59. if (swap) {
  60. ast_swapcopy_samples(s->data + s->len, f->data.ptr, f->samples);
  61. } else {
  62. memcpy(s->data + s->len, f->data.ptr, f->datalen);
  63. }
  64. /* If either side is empty, reset the delivery time */
  65. if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) { /* XXX really ? */
  66. s->delivery = f->delivery;
  67. }
  68. s->len += f->datalen;
  69. return 0;
  70. }
  71. void ast_smoother_reset(struct ast_smoother *s, int bytes)
  72. {
  73. ao2_cleanup(s->format);
  74. memset(s, 0, sizeof(*s));
  75. s->size = bytes;
  76. }
  77. void ast_smoother_reconfigure(struct ast_smoother *s, int bytes)
  78. {
  79. /* if there is no change, then nothing to do */
  80. if (s->size == bytes) {
  81. return;
  82. }
  83. /* set the new desired output size */
  84. s->size = bytes;
  85. /* if there is no 'optimized' frame in the smoother,
  86. * then there is nothing left to do
  87. */
  88. if (!s->opt) {
  89. return;
  90. }
  91. /* there is an 'optimized' frame here at the old size,
  92. * but it must now be put into the buffer so the data
  93. * can be extracted at the new size
  94. */
  95. smoother_frame_feed(s, s->opt, s->opt_needs_swap);
  96. s->opt = NULL;
  97. }
  98. struct ast_smoother *ast_smoother_new(int size)
  99. {
  100. struct ast_smoother *s;
  101. if (size < 1)
  102. return NULL;
  103. if ((s = ast_calloc(1, sizeof(*s))))
  104. ast_smoother_reset(s, size);
  105. return s;
  106. }
  107. int ast_smoother_get_flags(struct ast_smoother *s)
  108. {
  109. return s->flags;
  110. }
  111. void ast_smoother_set_flags(struct ast_smoother *s, int flags)
  112. {
  113. s->flags = flags;
  114. }
  115. int ast_smoother_test_flag(struct ast_smoother *s, int flag)
  116. {
  117. return (s->flags & flag);
  118. }
  119. int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
  120. {
  121. if (f->frametype != AST_FRAME_VOICE) {
  122. ast_log(LOG_WARNING, "Huh? Can't smooth a non-voice frame!\n");
  123. return -1;
  124. }
  125. if (!s->format) {
  126. s->format = ao2_bump(f->subclass.format);
  127. s->samplesperbyte = (float)f->samples / (float)f->datalen;
  128. } else if (ast_format_cmp(s->format, f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
  129. ast_log(LOG_WARNING, "Smoother was working on %s format frames, now trying to feed %s?\n",
  130. ast_format_get_name(s->format), ast_format_get_name(f->subclass.format));
  131. return -1;
  132. }
  133. if (s->len + f->datalen > SMOOTHER_SIZE) {
  134. ast_log(LOG_WARNING, "Out of smoother space\n");
  135. return -1;
  136. }
  137. if (((f->datalen == s->size) ||
  138. ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729))) &&
  139. !s->opt &&
  140. !s->len &&
  141. (f->offset >= AST_MIN_OFFSET)) {
  142. /* Optimize by sending the frame we just got
  143. on the next read, thus eliminating the douple
  144. copy */
  145. if (swap)
  146. ast_swapcopy_samples(f->data.ptr, f->data.ptr, f->samples);
  147. s->opt = f;
  148. s->opt_needs_swap = swap ? 1 : 0;
  149. return 0;
  150. }
  151. return smoother_frame_feed(s, f, swap);
  152. }
  153. struct ast_frame *ast_smoother_read(struct ast_smoother *s)
  154. {
  155. struct ast_frame *opt;
  156. int len;
  157. /* IF we have an optimization frame, send it */
  158. if (s->opt) {
  159. if (s->opt->offset < AST_FRIENDLY_OFFSET)
  160. ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).\n",
  161. s->opt->offset);
  162. opt = s->opt;
  163. s->opt = NULL;
  164. return opt;
  165. }
  166. /* Make sure we have enough data */
  167. if (s->len < s->size) {
  168. /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */
  169. if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->len % 10)))
  170. return NULL;
  171. }
  172. len = s->size;
  173. if (len > s->len)
  174. len = s->len;
  175. /* Make frame */
  176. s->f.frametype = AST_FRAME_VOICE;
  177. s->f.subclass.format = s->format;
  178. s->f.data.ptr = s->framedata + AST_FRIENDLY_OFFSET;
  179. s->f.offset = AST_FRIENDLY_OFFSET;
  180. s->f.datalen = len;
  181. /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
  182. s->f.samples = len * s->samplesperbyte; /* XXX rounding */
  183. s->f.delivery = s->delivery;
  184. /* Fill Data */
  185. memcpy(s->f.data.ptr, s->data, len);
  186. s->len -= len;
  187. /* Move remaining data to the front if applicable */
  188. if (s->len) {
  189. /* In principle this should all be fine because if we are sending
  190. G.729 VAD, the next timestamp will take over anyawy */
  191. memmove(s->data, s->data + len, s->len);
  192. if (!ast_tvzero(s->delivery)) {
  193. /* If we have delivery time, increment it, otherwise, leave it at 0 */
  194. s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples,
  195. ast_format_get_sample_rate(s->format)));
  196. }
  197. }
  198. /* Return frame */
  199. return &s->f;
  200. }
  201. void ast_smoother_free(struct ast_smoother *s)
  202. {
  203. ao2_cleanup(s->format);
  204. ast_free(s);
  205. }