codec_ulaw.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /* codec_ulaw.c - translate between signed linear and ulaw
  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/ulaw.h>
  18. #include <fcntl.h>
  19. #include <netinet/in.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #define BUFFER_SIZE 8096 /* size for the translation buffers */
  25. AST_MUTEX_DEFINE_STATIC(localuser_lock);
  26. static int localusecnt = 0;
  27. static char *tdesc = "Mu-law Coder/Decoder";
  28. /* Sample frame data */
  29. #include "slin_ulaw_ex.h"
  30. #include "ulaw_slin_ex.h"
  31. /*
  32. * Private workspace for translating signed linear signals to ulaw.
  33. */
  34. struct ulaw_encoder_pvt
  35. {
  36. struct ast_frame f;
  37. char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
  38. unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw, two nibbles to a word */
  39. int tail;
  40. };
  41. /*
  42. * Private workspace for translating ulaw signals to signed linear.
  43. */
  44. struct ulaw_decoder_pvt
  45. {
  46. struct ast_frame f;
  47. char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
  48. short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */
  49. int tail;
  50. };
  51. /*
  52. * ulawToLin_New
  53. * Create a new instance of ulaw_decoder_pvt.
  54. *
  55. * Results:
  56. * Returns a pointer to the new instance.
  57. *
  58. * Side effects:
  59. * None.
  60. */
  61. static struct ast_translator_pvt *
  62. ulawtolin_new (void)
  63. {
  64. struct ulaw_decoder_pvt *tmp;
  65. tmp = malloc (sizeof (struct ulaw_decoder_pvt));
  66. if (tmp)
  67. {
  68. memset(tmp, 0, sizeof(*tmp));
  69. tmp->tail = 0;
  70. localusecnt++;
  71. ast_update_use_count ();
  72. }
  73. return (struct ast_translator_pvt *) tmp;
  74. }
  75. /*
  76. * LinToulaw_New
  77. * Create a new instance of ulaw_encoder_pvt.
  78. *
  79. * Results:
  80. * Returns a pointer to the new instance.
  81. *
  82. * Side effects:
  83. * None.
  84. */
  85. static struct ast_translator_pvt *
  86. lintoulaw_new (void)
  87. {
  88. struct ulaw_encoder_pvt *tmp;
  89. tmp = malloc (sizeof (struct ulaw_encoder_pvt));
  90. if (tmp)
  91. {
  92. memset(tmp, 0, sizeof(*tmp));
  93. localusecnt++;
  94. ast_update_use_count ();
  95. tmp->tail = 0;
  96. }
  97. return (struct ast_translator_pvt *) tmp;
  98. }
  99. /*
  100. * ulawToLin_FrameIn
  101. * Fill an input buffer with packed 4-bit ulaw values if there is room
  102. * left.
  103. *
  104. * Results:
  105. * Foo
  106. *
  107. * Side effects:
  108. * tmp->tail is the number of packed values in the buffer.
  109. */
  110. static int
  111. ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
  112. {
  113. struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
  114. int x;
  115. unsigned char *b;
  116. if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) {
  117. ast_log(LOG_WARNING, "Out of buffer space\n");
  118. return -1;
  119. }
  120. /* Reset ssindex and signal to frame's specified values */
  121. b = f->data;
  122. for (x=0;x<f->datalen;x++)
  123. tmp->outbuf[tmp->tail + x] = AST_MULAW(b[x]);
  124. tmp->tail += f->datalen;
  125. return 0;
  126. }
  127. /*
  128. * ulawToLin_FrameOut
  129. * Convert 4-bit ulaw encoded signals to 16-bit signed linear.
  130. *
  131. * Results:
  132. * Converted signals are placed in tmp->f.data, tmp->f.datalen
  133. * and tmp->f.samples are calculated.
  134. *
  135. * Side effects:
  136. * None.
  137. */
  138. static struct ast_frame *
  139. ulawtolin_frameout (struct ast_translator_pvt *pvt)
  140. {
  141. struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
  142. if (!tmp->tail)
  143. return NULL;
  144. tmp->f.frametype = AST_FRAME_VOICE;
  145. tmp->f.subclass = AST_FORMAT_SLINEAR;
  146. tmp->f.datalen = tmp->tail *2;
  147. tmp->f.samples = tmp->tail;
  148. tmp->f.mallocd = 0;
  149. tmp->f.offset = AST_FRIENDLY_OFFSET;
  150. tmp->f.src = __PRETTY_FUNCTION__;
  151. tmp->f.data = tmp->outbuf;
  152. tmp->tail = 0;
  153. return &tmp->f;
  154. }
  155. /*
  156. * LinToulaw_FrameIn
  157. * Fill an input buffer with 16-bit signed linear PCM values.
  158. *
  159. * Results:
  160. * None.
  161. *
  162. * Side effects:
  163. * tmp->tail is number of signal values in the input buffer.
  164. */
  165. static int
  166. lintoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
  167. {
  168. struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
  169. int x;
  170. short *s;
  171. if (tmp->tail + f->datalen/2 >= sizeof(tmp->outbuf))
  172. {
  173. ast_log (LOG_WARNING, "Out of buffer space\n");
  174. return -1;
  175. }
  176. s = f->data;
  177. for (x=0;x<f->datalen/2;x++)
  178. tmp->outbuf[x+tmp->tail] = AST_LIN2MU(s[x]);
  179. tmp->tail += f->datalen/2;
  180. return 0;
  181. }
  182. /*
  183. * LinToulaw_FrameOut
  184. * Convert a buffer of raw 16-bit signed linear PCM to a buffer
  185. * of 4-bit ulaw packed two to a byte (Big Endian).
  186. *
  187. * Results:
  188. * Foo
  189. *
  190. * Side effects:
  191. * Leftover inbuf data gets packed, tail gets updated.
  192. */
  193. static struct ast_frame *
  194. lintoulaw_frameout (struct ast_translator_pvt *pvt)
  195. {
  196. struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
  197. if (tmp->tail) {
  198. tmp->f.frametype = AST_FRAME_VOICE;
  199. tmp->f.subclass = AST_FORMAT_ULAW;
  200. tmp->f.samples = tmp->tail;
  201. tmp->f.mallocd = 0;
  202. tmp->f.offset = AST_FRIENDLY_OFFSET;
  203. tmp->f.src = __PRETTY_FUNCTION__;
  204. tmp->f.data = tmp->outbuf;
  205. tmp->f.datalen = tmp->tail;
  206. tmp->tail = 0;
  207. return &tmp->f;
  208. } else return NULL;
  209. }
  210. /*
  211. * ulawToLin_Sample
  212. */
  213. static struct ast_frame *
  214. ulawtolin_sample (void)
  215. {
  216. static struct ast_frame f;
  217. f.frametype = AST_FRAME_VOICE;
  218. f.subclass = AST_FORMAT_ULAW;
  219. f.datalen = sizeof (ulaw_slin_ex);
  220. f.samples = sizeof(ulaw_slin_ex);
  221. f.mallocd = 0;
  222. f.offset = 0;
  223. f.src = __PRETTY_FUNCTION__;
  224. f.data = ulaw_slin_ex;
  225. return &f;
  226. }
  227. /*
  228. * LinToulaw_Sample
  229. */
  230. static struct ast_frame *
  231. lintoulaw_sample (void)
  232. {
  233. static struct ast_frame f;
  234. f.frametype = AST_FRAME_VOICE;
  235. f.subclass = AST_FORMAT_SLINEAR;
  236. f.datalen = sizeof (slin_ulaw_ex);
  237. /* Assume 8000 Hz */
  238. f.samples = sizeof (slin_ulaw_ex) / 2;
  239. f.mallocd = 0;
  240. f.offset = 0;
  241. f.src = __PRETTY_FUNCTION__;
  242. f.data = slin_ulaw_ex;
  243. return &f;
  244. }
  245. /*
  246. * ulaw_Destroy
  247. * Destroys a private workspace.
  248. *
  249. * Results:
  250. * It's gone!
  251. *
  252. * Side effects:
  253. * None.
  254. */
  255. static void
  256. ulaw_destroy (struct ast_translator_pvt *pvt)
  257. {
  258. free (pvt);
  259. localusecnt--;
  260. ast_update_use_count ();
  261. }
  262. /*
  263. * The complete translator for ulawToLin.
  264. */
  265. static struct ast_translator ulawtolin = {
  266. "ulawtolin",
  267. AST_FORMAT_ULAW,
  268. AST_FORMAT_SLINEAR,
  269. ulawtolin_new,
  270. ulawtolin_framein,
  271. ulawtolin_frameout,
  272. ulaw_destroy,
  273. /* NULL */
  274. ulawtolin_sample
  275. };
  276. /*
  277. * The complete translator for LinToulaw.
  278. */
  279. static struct ast_translator lintoulaw = {
  280. "lintoulaw",
  281. AST_FORMAT_SLINEAR,
  282. AST_FORMAT_ULAW,
  283. lintoulaw_new,
  284. lintoulaw_framein,
  285. lintoulaw_frameout,
  286. ulaw_destroy,
  287. /* NULL */
  288. lintoulaw_sample
  289. };
  290. int
  291. unload_module (void)
  292. {
  293. int res;
  294. ast_mutex_lock (&localuser_lock);
  295. res = ast_unregister_translator (&lintoulaw);
  296. if (!res)
  297. res = ast_unregister_translator (&ulawtolin);
  298. if (localusecnt)
  299. res = -1;
  300. ast_mutex_unlock (&localuser_lock);
  301. return res;
  302. }
  303. int
  304. load_module (void)
  305. {
  306. int res;
  307. res = ast_register_translator (&ulawtolin);
  308. if (!res)
  309. res = ast_register_translator (&lintoulaw);
  310. else
  311. ast_unregister_translator (&ulawtolin);
  312. return res;
  313. }
  314. /*
  315. * Return a description of this module.
  316. */
  317. char *
  318. description (void)
  319. {
  320. return tdesc;
  321. }
  322. int
  323. usecount (void)
  324. {
  325. int res;
  326. STANDARD_USECOUNT (res);
  327. return res;
  328. }
  329. char *
  330. key ()
  331. {
  332. return ASTERISK_GPL_KEY;
  333. }