00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <fcntl.h>
00027 #include <netinet/in.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032
00033 #include "asterisk.h"
00034
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00036
00037 #include "asterisk/lock.h"
00038 #include "asterisk/logger.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/translate.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/alaw.h"
00043 #include "asterisk/ulaw.h"
00044
00045 #define BUFFER_SIZE 8096
00046
00047 AST_MUTEX_DEFINE_STATIC(localuser_lock);
00048 static int localusecnt = 0;
00049
00050 static char *tdesc = "A-law and Mulaw direct Coder/Decoder";
00051
00052 static unsigned char mu2a[256];
00053 static unsigned char a2mu[256];
00054
00055
00056
00057 #include "ulaw_slin_ex.h"
00058
00059
00060
00061
00062
00063 struct alaw_encoder_pvt
00064 {
00065 struct ast_frame f;
00066 char offset[AST_FRIENDLY_OFFSET];
00067 unsigned char outbuf[BUFFER_SIZE];
00068 int tail;
00069 };
00070
00071
00072
00073
00074
00075 struct ulaw_encoder_pvt
00076 {
00077 struct ast_frame f;
00078 char offset[AST_FRIENDLY_OFFSET];
00079 unsigned char outbuf[BUFFER_SIZE];
00080 int tail;
00081 };
00082
00083 static struct ast_translator_pvt *
00084 alawtoulaw_new (void)
00085 {
00086 struct ulaw_encoder_pvt *tmp;
00087 tmp = malloc (sizeof (struct ulaw_encoder_pvt));
00088 if (tmp)
00089 {
00090 memset(tmp, 0, sizeof(*tmp));
00091 tmp->tail = 0;
00092 localusecnt++;
00093 ast_update_use_count ();
00094 }
00095 return (struct ast_translator_pvt *) tmp;
00096 }
00097
00098 static struct ast_translator_pvt *
00099 ulawtoalaw_new (void)
00100 {
00101 struct alaw_encoder_pvt *tmp;
00102 tmp = malloc (sizeof (struct alaw_encoder_pvt));
00103 if (tmp)
00104 {
00105 memset(tmp, 0, sizeof(*tmp));
00106 localusecnt++;
00107 ast_update_use_count ();
00108 tmp->tail = 0;
00109 }
00110 return (struct ast_translator_pvt *) tmp;
00111 }
00112
00113 static int
00114 alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
00115 {
00116 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
00117 int x;
00118 unsigned char *b;
00119
00120 if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) {
00121 ast_log(LOG_WARNING, "Out of buffer space\n");
00122 return -1;
00123 }
00124
00125
00126 b = f->data;
00127 for (x=0;x<f->datalen;x++)
00128 tmp->outbuf[tmp->tail + x] = a2mu[b[x]];
00129
00130 tmp->tail += f->datalen;
00131 return 0;
00132 }
00133
00134 static struct ast_frame *
00135 alawtoulaw_frameout (struct ast_translator_pvt *pvt)
00136 {
00137 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
00138
00139 if (!tmp->tail)
00140 return NULL;
00141
00142 tmp->f.frametype = AST_FRAME_VOICE;
00143 tmp->f.subclass = AST_FORMAT_ULAW;
00144 tmp->f.datalen = tmp->tail;
00145 tmp->f.samples = tmp->tail;
00146 tmp->f.mallocd = 0;
00147 tmp->f.offset = AST_FRIENDLY_OFFSET;
00148 tmp->f.src = __PRETTY_FUNCTION__;
00149 tmp->f.data = tmp->outbuf;
00150 tmp->tail = 0;
00151 return &tmp->f;
00152 }
00153
00154 static int
00155 ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
00156 {
00157 struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
00158 int x;
00159 unsigned char *s;
00160 if (tmp->tail + f->datalen >= sizeof(tmp->outbuf))
00161 {
00162 ast_log (LOG_WARNING, "Out of buffer space\n");
00163 return -1;
00164 }
00165 s = f->data;
00166 for (x=0;x<f->datalen;x++)
00167 tmp->outbuf[x+tmp->tail] = mu2a[s[x]];
00168 tmp->tail += f->datalen;
00169 return 0;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 static struct ast_frame *
00185 ulawtoalaw_frameout (struct ast_translator_pvt *pvt)
00186 {
00187 struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
00188
00189 if (tmp->tail) {
00190 tmp->f.frametype = AST_FRAME_VOICE;
00191 tmp->f.subclass = AST_FORMAT_ALAW;
00192 tmp->f.samples = tmp->tail;
00193 tmp->f.mallocd = 0;
00194 tmp->f.offset = AST_FRIENDLY_OFFSET;
00195 tmp->f.src = __PRETTY_FUNCTION__;
00196 tmp->f.data = tmp->outbuf;
00197 tmp->f.datalen = tmp->tail;
00198 tmp->tail = 0;
00199 return &tmp->f;
00200 } else return NULL;
00201 }
00202
00203
00204
00205
00206
00207
00208 static struct ast_frame *
00209 alawtoulaw_sample (void)
00210 {
00211 static struct ast_frame f;
00212 f.frametype = AST_FRAME_VOICE;
00213 f.subclass = AST_FORMAT_ALAW;
00214 f.datalen = sizeof (ulaw_slin_ex);
00215 f.samples = sizeof(ulaw_slin_ex);
00216 f.mallocd = 0;
00217 f.offset = 0;
00218 f.src = __PRETTY_FUNCTION__;
00219 f.data = ulaw_slin_ex;
00220 return &f;
00221 }
00222
00223 static struct ast_frame *
00224 ulawtoalaw_sample (void)
00225 {
00226 static struct ast_frame f;
00227 f.frametype = AST_FRAME_VOICE;
00228 f.subclass = AST_FORMAT_ULAW;
00229 f.datalen = sizeof (ulaw_slin_ex);
00230 f.samples = sizeof(ulaw_slin_ex);
00231 f.mallocd = 0;
00232 f.offset = 0;
00233 f.src = __PRETTY_FUNCTION__;
00234 f.data = ulaw_slin_ex;
00235 return &f;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static void
00251 alaw_destroy (struct ast_translator_pvt *pvt)
00252 {
00253 free (pvt);
00254 localusecnt--;
00255 ast_update_use_count ();
00256 }
00257
00258
00259
00260
00261
00262 static struct ast_translator alawtoulaw = {
00263 "alawtoulaw",
00264 AST_FORMAT_ALAW,
00265 AST_FORMAT_ULAW,
00266 alawtoulaw_new,
00267 alawtoulaw_framein,
00268 alawtoulaw_frameout,
00269 alaw_destroy,
00270
00271 alawtoulaw_sample
00272 };
00273
00274
00275
00276
00277
00278 static struct ast_translator ulawtoalaw = {
00279 "ulawtoalaw",
00280 AST_FORMAT_ULAW,
00281 AST_FORMAT_ALAW,
00282 ulawtoalaw_new,
00283 ulawtoalaw_framein,
00284 ulawtoalaw_frameout,
00285 alaw_destroy,
00286
00287 ulawtoalaw_sample
00288 };
00289
00290 int
00291 unload_module (void)
00292 {
00293 int res;
00294 ast_mutex_lock (&localuser_lock);
00295 res = ast_unregister_translator (&ulawtoalaw);
00296 if (!res)
00297 res = ast_unregister_translator (&alawtoulaw);
00298 if (localusecnt)
00299 res = -1;
00300 ast_mutex_unlock (&localuser_lock);
00301 return res;
00302 }
00303
00304 int
00305 load_module (void)
00306 {
00307 int res;
00308 int x;
00309 for (x=0;x<256;x++) {
00310 mu2a[x] = AST_LIN2A(AST_MULAW(x));
00311 a2mu[x] = AST_LIN2MU(AST_ALAW(x));
00312 }
00313 res = ast_register_translator (&alawtoulaw);
00314 if (!res)
00315 res = ast_register_translator (&ulawtoalaw);
00316 else
00317 ast_unregister_translator (&alawtoulaw);
00318 return res;
00319 }
00320
00321
00322
00323
00324
00325 char *
00326 description (void)
00327 {
00328 return tdesc;
00329 }
00330
00331 int
00332 usecount (void)
00333 {
00334 int res;
00335 STANDARD_USECOUNT (res);
00336 return res;
00337 }
00338
00339 char *
00340 key ()
00341 {
00342 return ASTERISK_GPL_KEY;
00343 }