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