codec_alaw.c 8.9 KB

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