1 /* codec_a_mu.c - translate between alaw and ulaw directly
3 * Asterisk -- A telephony toolkit for Linux.
5 * Copyright (c) 2001 Linux Support Services, Inc. All rights reserved.
7 * Mark Spencer <markster@linux-support.net
9 * This program is free software, distributed under the terms of
10 * the GNU General Public License
14 #include <netinet/in.h>
22 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
24 #include "asterisk/lock.h"
25 #include "asterisk/logger.h"
26 #include "asterisk/module.h"
27 #include "asterisk/translate.h"
28 #include "asterisk/channel.h"
29 #include "asterisk/alaw.h"
30 #include "asterisk/ulaw.h"
32 #define BUFFER_SIZE 8096 /* size for the translation buffers */
34 AST_MUTEX_DEFINE_STATIC(localuser_lock);
35 static int localusecnt = 0;
37 static char *tdesc = "A-law and Mulaw direct Coder/Decoder";
39 static unsigned char mu2a[256];
40 static unsigned char a2mu[256];
42 /* Sample frame data (Mu data is okay) */
44 #include "ulaw_slin_ex.h"
47 * Private workspace for translating signed linear signals to alaw.
50 struct alaw_encoder_pvt
53 char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
54 unsigned char outbuf[BUFFER_SIZE]; /* Encoded alaw, two nibbles to a word */
59 * Private workspace for translating laws.
62 struct ulaw_encoder_pvt
65 char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
66 unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw values */
70 static struct ast_translator_pvt *
73 struct ulaw_encoder_pvt *tmp;
74 tmp = malloc (sizeof (struct ulaw_encoder_pvt));
77 memset(tmp, 0, sizeof(*tmp));
80 ast_update_use_count ();
82 return (struct ast_translator_pvt *) tmp;
85 static struct ast_translator_pvt *
88 struct alaw_encoder_pvt *tmp;
89 tmp = malloc (sizeof (struct alaw_encoder_pvt));
92 memset(tmp, 0, sizeof(*tmp));
94 ast_update_use_count ();
97 return (struct ast_translator_pvt *) tmp;
101 alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
103 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
107 if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) {
108 ast_log(LOG_WARNING, "Out of buffer space\n");
112 /* Reset ssindex and signal to frame's specified values */
114 for (x=0;x<f->datalen;x++)
115 tmp->outbuf[tmp->tail + x] = a2mu[b[x]];
117 tmp->tail += f->datalen;
121 static struct ast_frame *
122 alawtoulaw_frameout (struct ast_translator_pvt *pvt)
124 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
129 tmp->f.frametype = AST_FRAME_VOICE;
130 tmp->f.subclass = AST_FORMAT_ULAW;
131 tmp->f.datalen = tmp->tail;
132 tmp->f.samples = tmp->tail;
134 tmp->f.offset = AST_FRIENDLY_OFFSET;
135 tmp->f.src = __PRETTY_FUNCTION__;
136 tmp->f.data = tmp->outbuf;
142 ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
144 struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
147 if (tmp->tail + f->datalen >= sizeof(tmp->outbuf))
149 ast_log (LOG_WARNING, "Out of buffer space\n");
153 for (x=0;x<f->datalen;x++)
154 tmp->outbuf[x+tmp->tail] = mu2a[s[x]];
155 tmp->tail += f->datalen;
161 * Convert a buffer of raw 16-bit signed linear PCM to a buffer
162 * of 4-bit alaw packed two to a byte (Big Endian).
168 * Leftover inbuf data gets packed, tail gets updated.
171 static struct ast_frame *
172 ulawtoalaw_frameout (struct ast_translator_pvt *pvt)
174 struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
177 tmp->f.frametype = AST_FRAME_VOICE;
178 tmp->f.subclass = AST_FORMAT_ALAW;
179 tmp->f.samples = tmp->tail;
181 tmp->f.offset = AST_FRIENDLY_OFFSET;
182 tmp->f.src = __PRETTY_FUNCTION__;
183 tmp->f.data = tmp->outbuf;
184 tmp->f.datalen = tmp->tail;
195 static struct ast_frame *
196 alawtoulaw_sample (void)
198 static struct ast_frame f;
199 f.frametype = AST_FRAME_VOICE;
200 f.subclass = AST_FORMAT_ALAW;
201 f.datalen = sizeof (ulaw_slin_ex);
202 f.samples = sizeof(ulaw_slin_ex);
205 f.src = __PRETTY_FUNCTION__;
206 f.data = ulaw_slin_ex;
210 static struct ast_frame *
211 ulawtoalaw_sample (void)
213 static struct ast_frame f;
214 f.frametype = AST_FRAME_VOICE;
215 f.subclass = AST_FORMAT_ULAW;
216 f.datalen = sizeof (ulaw_slin_ex);
217 f.samples = sizeof(ulaw_slin_ex);
220 f.src = __PRETTY_FUNCTION__;
221 f.data = ulaw_slin_ex;
228 * Destroys a private workspace.
238 alaw_destroy (struct ast_translator_pvt *pvt)
242 ast_update_use_count ();
246 * The complete translator for alawToLin.
249 static struct ast_translator alawtoulaw = {
262 * The complete translator for LinToalaw.
265 static struct ast_translator ulawtoalaw = {
281 ast_mutex_lock (&localuser_lock);
282 res = ast_unregister_translator (&ulawtoalaw);
284 res = ast_unregister_translator (&alawtoulaw);
287 ast_mutex_unlock (&localuser_lock);
296 for (x=0;x<256;x++) {
297 mu2a[x] = AST_LIN2A(AST_MULAW(x));
298 a2mu[x] = AST_LIN2MU(AST_ALAW(x));
300 res = ast_register_translator (&alawtoulaw);
302 res = ast_register_translator (&ulawtoalaw);
304 ast_unregister_translator (&alawtoulaw);
309 * Return a description of this module.
322 STANDARD_USECOUNT (res);
329 return ASTERISK_GPL_KEY;