codec_ulaw.c 8.7 KB

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