codec_a_mu.c 6.4 KB

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