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/config.h"
00041 #include "asterisk/options.h"
00042 #include "asterisk/translate.h"
00043 #include "asterisk/channel.h"
00044 #include "asterisk/ulaw.h"
00045
00046 #define BUFFER_SIZE 8096
00047
00048 AST_MUTEX_DEFINE_STATIC(localuser_lock);
00049 static int localusecnt = 0;
00050
00051 static char *tdesc = "Mu-law Coder/Decoder";
00052
00053 static int useplc = 0;
00054
00055
00056
00057 #include "slin_ulaw_ex.h"
00058 #include "ulaw_slin_ex.h"
00059
00060
00061
00062
00063
00064 struct ulaw_encoder_pvt
00065 {
00066 struct ast_frame f;
00067 char offset[AST_FRIENDLY_OFFSET];
00068 unsigned char outbuf[BUFFER_SIZE];
00069 int tail;
00070 };
00071
00072
00073
00074
00075
00076 struct ulaw_decoder_pvt
00077 {
00078 struct ast_frame f;
00079 char offset[AST_FRIENDLY_OFFSET];
00080 short outbuf[BUFFER_SIZE];
00081 int tail;
00082 plc_state_t plc;
00083 };
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static struct ast_translator_pvt *
00097 ulawtolin_new (void)
00098 {
00099 struct ulaw_decoder_pvt *tmp;
00100 tmp = malloc (sizeof (struct ulaw_decoder_pvt));
00101 if (tmp)
00102 {
00103 memset(tmp, 0, sizeof(*tmp));
00104 tmp->tail = 0;
00105 plc_init(&tmp->plc);
00106 localusecnt++;
00107 ast_update_use_count ();
00108 }
00109 return (struct ast_translator_pvt *) tmp;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 static struct ast_translator_pvt *
00124 lintoulaw_new (void)
00125 {
00126 struct ulaw_encoder_pvt *tmp;
00127 tmp = malloc (sizeof (struct ulaw_encoder_pvt));
00128 if (tmp)
00129 {
00130 memset(tmp, 0, sizeof(*tmp));
00131 localusecnt++;
00132 ast_update_use_count ();
00133 tmp->tail = 0;
00134 }
00135 return (struct ast_translator_pvt *) tmp;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static int
00151 ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
00152 {
00153 struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
00154 int x;
00155 unsigned char *b;
00156
00157 if(f->datalen == 0) {
00158 if((tmp->tail + 160) * 2 > sizeof(tmp->outbuf)) {
00159 ast_log(LOG_WARNING, "Out of buffer space\n");
00160 return -1;
00161 }
00162 if(useplc) {
00163 plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160);
00164 tmp->tail += 160;
00165 }
00166 return 0;
00167 }
00168
00169 if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) {
00170 ast_log(LOG_WARNING, "Out of buffer space\n");
00171 return -1;
00172 }
00173
00174
00175 b = f->data;
00176 for (x=0;x<f->datalen;x++)
00177 tmp->outbuf[tmp->tail + x] = AST_MULAW(b[x]);
00178
00179 if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail, f->datalen);
00180
00181 tmp->tail += f->datalen;
00182 return 0;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 static struct ast_frame *
00198 ulawtolin_frameout (struct ast_translator_pvt *pvt)
00199 {
00200 struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
00201
00202 if (!tmp->tail)
00203 return NULL;
00204
00205 tmp->f.frametype = AST_FRAME_VOICE;
00206 tmp->f.subclass = AST_FORMAT_SLINEAR;
00207 tmp->f.datalen = tmp->tail *2;
00208 tmp->f.samples = tmp->tail;
00209 tmp->f.mallocd = 0;
00210 tmp->f.offset = AST_FRIENDLY_OFFSET;
00211 tmp->f.src = __PRETTY_FUNCTION__;
00212 tmp->f.data = tmp->outbuf;
00213 tmp->tail = 0;
00214 return &tmp->f;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 static int
00229 lintoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
00230 {
00231 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
00232 int x;
00233 short *s;
00234 if (tmp->tail + f->datalen/2 >= sizeof(tmp->outbuf))
00235 {
00236 ast_log (LOG_WARNING, "Out of buffer space\n");
00237 return -1;
00238 }
00239 s = f->data;
00240 for (x=0;x<f->datalen/2;x++)
00241 tmp->outbuf[x+tmp->tail] = AST_LIN2MU(s[x]);
00242 tmp->tail += f->datalen/2;
00243 return 0;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static struct ast_frame *
00259 lintoulaw_frameout (struct ast_translator_pvt *pvt)
00260 {
00261 struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
00262
00263 if (tmp->tail) {
00264 tmp->f.frametype = AST_FRAME_VOICE;
00265 tmp->f.subclass = AST_FORMAT_ULAW;
00266 tmp->f.samples = tmp->tail;
00267 tmp->f.mallocd = 0;
00268 tmp->f.offset = AST_FRIENDLY_OFFSET;
00269 tmp->f.src = __PRETTY_FUNCTION__;
00270 tmp->f.data = tmp->outbuf;
00271 tmp->f.datalen = tmp->tail;
00272 tmp->tail = 0;
00273 return &tmp->f;
00274 } else return NULL;
00275 }
00276
00277
00278
00279
00280
00281
00282 static struct ast_frame *
00283 ulawtolin_sample (void)
00284 {
00285 static struct ast_frame f;
00286 f.frametype = AST_FRAME_VOICE;
00287 f.subclass = AST_FORMAT_ULAW;
00288 f.datalen = sizeof (ulaw_slin_ex);
00289 f.samples = sizeof(ulaw_slin_ex);
00290 f.mallocd = 0;
00291 f.offset = 0;
00292 f.src = __PRETTY_FUNCTION__;
00293 f.data = ulaw_slin_ex;
00294 return &f;
00295 }
00296
00297
00298
00299
00300
00301 static struct ast_frame *
00302 lintoulaw_sample (void)
00303 {
00304 static struct ast_frame f;
00305 f.frametype = AST_FRAME_VOICE;
00306 f.subclass = AST_FORMAT_SLINEAR;
00307 f.datalen = sizeof (slin_ulaw_ex);
00308
00309 f.samples = sizeof (slin_ulaw_ex) / 2;
00310 f.mallocd = 0;
00311 f.offset = 0;
00312 f.src = __PRETTY_FUNCTION__;
00313 f.data = slin_ulaw_ex;
00314 return &f;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 static void
00329 ulaw_destroy (struct ast_translator_pvt *pvt)
00330 {
00331 free (pvt);
00332 localusecnt--;
00333 ast_update_use_count ();
00334 }
00335
00336
00337
00338
00339
00340 static struct ast_translator ulawtolin = {
00341 "ulawtolin",
00342 AST_FORMAT_ULAW,
00343 AST_FORMAT_SLINEAR,
00344 ulawtolin_new,
00345 ulawtolin_framein,
00346 ulawtolin_frameout,
00347 ulaw_destroy,
00348
00349 ulawtolin_sample
00350 };
00351
00352
00353
00354
00355
00356 static struct ast_translator lintoulaw = {
00357 "lintoulaw",
00358 AST_FORMAT_SLINEAR,
00359 AST_FORMAT_ULAW,
00360 lintoulaw_new,
00361 lintoulaw_framein,
00362 lintoulaw_frameout,
00363 ulaw_destroy,
00364
00365 lintoulaw_sample
00366 };
00367
00368 static void
00369 parse_config(void)
00370 {
00371 struct ast_config *cfg;
00372 struct ast_variable *var;
00373 if ((cfg = ast_config_load("codecs.conf"))) {
00374 if ((var = ast_variable_browse(cfg, "plc"))) {
00375 while (var) {
00376 if (!strcasecmp(var->name, "genericplc")) {
00377 useplc = ast_true(var->value) ? 1 : 0;
00378 if (option_verbose > 2)
00379 ast_verbose(VERBOSE_PREFIX_3 "codec_ulaw: %susing generic PLC\n", useplc ? "" : "not ");
00380 }
00381 var = var->next;
00382 }
00383 }
00384 ast_config_destroy(cfg);
00385 }
00386 }
00387
00388 int
00389 reload(void)
00390 {
00391 parse_config();
00392 return 0;
00393 }
00394
00395
00396 int
00397 unload_module (void)
00398 {
00399 int res;
00400 ast_mutex_lock (&localuser_lock);
00401 res = ast_unregister_translator (&lintoulaw);
00402 if (!res)
00403 res = ast_unregister_translator (&ulawtolin);
00404 if (localusecnt)
00405 res = -1;
00406 ast_mutex_unlock (&localuser_lock);
00407 return res;
00408 }
00409
00410 int
00411 load_module (void)
00412 {
00413 int res;
00414 parse_config();
00415 res = ast_register_translator (&ulawtolin);
00416 if (!res)
00417 res = ast_register_translator (&lintoulaw);
00418 else
00419 ast_unregister_translator (&ulawtolin);
00420 return res;
00421 }
00422
00423
00424
00425
00426
00427 char *
00428 description (void)
00429 {
00430 return tdesc;
00431 }
00432
00433 int
00434 usecount (void)
00435 {
00436 int res;
00437 STANDARD_USECOUNT (res);
00438 return res;
00439 }
00440
00441 char *
00442 key ()
00443 {
00444 return ASTERISK_GPL_KEY;
00445 }