codec_a_mu.c 6.5 KB

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