codec_a_mu.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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 codec_a_mu.c - translate between alaw and ulaw directly
  21. *
  22. * \ingroup codecs
  23. */
  24. #include <fcntl.h>
  25. #include <netinet/in.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include "asterisk.h"
  31. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  32. #include "asterisk/lock.h"
  33. #include "asterisk/logger.h"
  34. #include "asterisk/module.h"
  35. #include "asterisk/translate.h"
  36. #include "asterisk/channel.h"
  37. #include "asterisk/alaw.h"
  38. #include "asterisk/ulaw.h"
  39. #define BUFFER_SIZE 8096 /* size for the translation buffers */
  40. AST_MUTEX_DEFINE_STATIC(localuser_lock);
  41. static int localusecnt = 0;
  42. static char *tdesc = "A-law and Mulaw direct Coder/Decoder";
  43. static unsigned char mu2a[256];
  44. static unsigned char a2mu[256];
  45. /* Sample frame data (Mu data is okay) */
  46. #include "ulaw_slin_ex.h"
  47. /*
  48. * Private workspace for translating signed linear signals to alaw.
  49. */
  50. struct alaw_encoder_pvt
  51. {
  52. struct ast_frame f;
  53. char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
  54. unsigned char outbuf[BUFFER_SIZE]; /* Encoded alaw, two nibbles to a word */
  55. int tail;
  56. };
  57. /*
  58. * Private workspace for translating laws.
  59. */
  60. struct ulaw_encoder_pvt
  61. {
  62. struct ast_frame f;
  63. char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
  64. unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw values */
  65. int tail;
  66. };
  67. static struct ast_translator_pvt *
  68. alawtoulaw_new (void)
  69. {
  70. struct ulaw_encoder_pvt *tmp;
  71. tmp = malloc (sizeof (struct ulaw_encoder_pvt));
  72. if (tmp)
  73. {
  74. memset(tmp, 0, sizeof(*tmp));
  75. tmp->tail = 0;
  76. localusecnt++;
  77. ast_update_use_count ();
  78. }
  79. return (struct ast_translator_pvt *) tmp;
  80. }
  81. static struct ast_translator_pvt *
  82. ulawtoalaw_new (void)
  83. {
  84. struct alaw_encoder_pvt *tmp;
  85. tmp = malloc (sizeof (struct alaw_encoder_pvt));
  86. if (tmp)
  87. {
  88. memset(tmp, 0, sizeof(*tmp));
  89. localusecnt++;
  90. ast_update_use_count ();
  91. tmp->tail = 0;
  92. }
  93. return (struct ast_translator_pvt *) tmp;
  94. }
  95. static int
  96. alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
  97. {
  98. struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
  99. int x;
  100. unsigned char *b;
  101. if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) {
  102. ast_log(LOG_WARNING, "Out of buffer space\n");
  103. return -1;
  104. }
  105. /* Reset ssindex and signal to frame's specified values */
  106. b = f->data;
  107. for (x=0;x<f->datalen;x++)
  108. tmp->outbuf[tmp->tail + x] = a2mu[b[x]];
  109. tmp->tail += f->datalen;
  110. return 0;
  111. }
  112. static struct ast_frame *
  113. alawtoulaw_frameout (struct ast_translator_pvt *pvt)
  114. {
  115. struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
  116. if (!tmp->tail)
  117. return NULL;
  118. tmp->f.frametype = AST_FRAME_VOICE;
  119. tmp->f.subclass = AST_FORMAT_ULAW;
  120. tmp->f.datalen = tmp->tail;
  121. tmp->f.samples = tmp->tail;
  122. tmp->f.mallocd = 0;
  123. tmp->f.offset = AST_FRIENDLY_OFFSET;
  124. tmp->f.src = __PRETTY_FUNCTION__;
  125. tmp->f.data = tmp->outbuf;
  126. tmp->tail = 0;
  127. return &tmp->f;
  128. }
  129. static int
  130. ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
  131. {
  132. struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
  133. int x;
  134. unsigned char *s;
  135. if (tmp->tail + f->datalen >= sizeof(tmp->outbuf))
  136. {
  137. ast_log (LOG_WARNING, "Out of buffer space\n");
  138. return -1;
  139. }
  140. s = f->data;
  141. for (x=0;x<f->datalen;x++)
  142. tmp->outbuf[x+tmp->tail] = mu2a[s[x]];
  143. tmp->tail += f->datalen;
  144. return 0;
  145. }
  146. /*
  147. * LinToalaw_FrameOut
  148. * Convert a buffer of raw 16-bit signed linear PCM to a buffer
  149. * of 4-bit alaw packed two to a byte (Big Endian).
  150. *
  151. * Results:
  152. * Foo
  153. *
  154. * Side effects:
  155. * Leftover inbuf data gets packed, tail gets updated.
  156. */
  157. static struct ast_frame *
  158. ulawtoalaw_frameout (struct ast_translator_pvt *pvt)
  159. {
  160. struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
  161. if (tmp->tail) {
  162. tmp->f.frametype = AST_FRAME_VOICE;
  163. tmp->f.subclass = AST_FORMAT_ALAW;
  164. tmp->f.samples = tmp->tail;
  165. tmp->f.mallocd = 0;
  166. tmp->f.offset = AST_FRIENDLY_OFFSET;
  167. tmp->f.src = __PRETTY_FUNCTION__;
  168. tmp->f.data = tmp->outbuf;
  169. tmp->f.datalen = tmp->tail;
  170. tmp->tail = 0;
  171. return &tmp->f;
  172. } else return NULL;
  173. }
  174. /*
  175. * alawToLin_Sample
  176. */
  177. static struct ast_frame *
  178. alawtoulaw_sample (void)
  179. {
  180. static struct ast_frame f;
  181. f.frametype = AST_FRAME_VOICE;
  182. f.subclass = AST_FORMAT_ALAW;
  183. f.datalen = sizeof (ulaw_slin_ex);
  184. f.samples = sizeof(ulaw_slin_ex);
  185. f.mallocd = 0;
  186. f.offset = 0;
  187. f.src = __PRETTY_FUNCTION__;
  188. f.data = ulaw_slin_ex;
  189. return &f;
  190. }
  191. static struct ast_frame *
  192. ulawtoalaw_sample (void)
  193. {
  194. static struct ast_frame f;
  195. f.frametype = AST_FRAME_VOICE;
  196. f.subclass = AST_FORMAT_ULAW;
  197. f.datalen = sizeof (ulaw_slin_ex);
  198. f.samples = sizeof(ulaw_slin_ex);
  199. f.mallocd = 0;
  200. f.offset = 0;
  201. f.src = __PRETTY_FUNCTION__;
  202. f.data = ulaw_slin_ex;
  203. return &f;
  204. }
  205. /*
  206. * alaw_Destroy
  207. * Destroys a private workspace.
  208. *
  209. * Results:
  210. * It's gone!
  211. *
  212. * Side effects:
  213. * None.
  214. */
  215. static void
  216. alaw_destroy (struct ast_translator_pvt *pvt)
  217. {
  218. free (pvt);
  219. localusecnt--;
  220. ast_update_use_count ();
  221. }
  222. /*
  223. * The complete translator for alawToLin.
  224. */
  225. static struct ast_translator alawtoulaw = {
  226. "alawtoulaw",
  227. AST_FORMAT_ALAW,
  228. AST_FORMAT_ULAW,
  229. alawtoulaw_new,
  230. alawtoulaw_framein,
  231. alawtoulaw_frameout,
  232. alaw_destroy,
  233. /* NULL */
  234. alawtoulaw_sample
  235. };
  236. /*
  237. * The complete translator for LinToalaw.
  238. */
  239. static struct ast_translator ulawtoalaw = {
  240. "ulawtoalaw",
  241. AST_FORMAT_ULAW,
  242. AST_FORMAT_ALAW,
  243. ulawtoalaw_new,
  244. ulawtoalaw_framein,
  245. ulawtoalaw_frameout,
  246. alaw_destroy,
  247. /* NULL */
  248. ulawtoalaw_sample
  249. };
  250. int
  251. unload_module (void)
  252. {
  253. int res;
  254. ast_mutex_lock (&localuser_lock);
  255. res = ast_unregister_translator (&ulawtoalaw);
  256. if (!res)
  257. res = ast_unregister_translator (&alawtoulaw);
  258. if (localusecnt)
  259. res = -1;
  260. ast_mutex_unlock (&localuser_lock);
  261. return res;
  262. }
  263. int
  264. load_module (void)
  265. {
  266. int res;
  267. int x;
  268. for (x=0;x<256;x++) {
  269. mu2a[x] = AST_LIN2A(AST_MULAW(x));
  270. a2mu[x] = AST_LIN2MU(AST_ALAW(x));
  271. }
  272. res = ast_register_translator (&alawtoulaw);
  273. if (!res)
  274. res = ast_register_translator (&ulawtoalaw);
  275. else
  276. ast_unregister_translator (&alawtoulaw);
  277. return res;
  278. }
  279. /*
  280. * Return a description of this module.
  281. */
  282. char *
  283. description (void)
  284. {
  285. return tdesc;
  286. }
  287. int
  288. usecount (void)
  289. {
  290. int res;
  291. STANDARD_USECOUNT (res);
  292. return res;
  293. }
  294. char *
  295. key ()
  296. {
  297. return ASTERISK_GPL_KEY;
  298. }