From a7b345c3fd2de4767b1494d33fcba264ed7ffdfc Mon Sep 17 00:00:00 2001 From: markster Date: Sun, 9 Dec 2001 07:08:11 +0000 Subject: Version 0.1.10 from FTP git-svn-id: http://svn.digium.com/svn/asterisk/trunk@393 f38db490-d61c-443f-a65b-d21fe96a405b --- codecs/codec_a_mu.c | 325 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100755 codecs/codec_a_mu.c (limited to 'codecs/codec_a_mu.c') diff --git a/codecs/codec_a_mu.c b/codecs/codec_a_mu.c new file mode 100755 index 000000000..96fa2acfc --- /dev/null +++ b/codecs/codec_a_mu.c @@ -0,0 +1,325 @@ +/* codec_a_mu.c - translate between alaw and ulaw directly + * + * Asterisk -- A telephony toolkit for Linux. + * + * Copyright (c) 2001 Linux Support Services, Inc. All rights reserved. + * + * Mark Spencer +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 8096 /* size for the translation buffers */ + +static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER; +static int localusecnt = 0; + +static char *tdesc = "A-law and Mulaw direct Coder/Decoder"; + +static unsigned char mu2a[256]; +static unsigned char a2mu[256]; + +/* Sample frame data (Mu data is okay) */ + +#include "ulaw_slin_ex.h" + +/* + * Private workspace for translating signed linear signals to alaw. + */ + +struct alaw_encoder_pvt +{ + struct ast_frame f; + char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ + unsigned char outbuf[BUFFER_SIZE]; /* Encoded alaw, two nibbles to a word */ + int tail; +}; + +/* + * Private workspace for translating laws. + */ + +struct ulaw_encoder_pvt +{ + struct ast_frame f; + char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ + unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw values */ + int tail; +}; + +static struct ast_translator_pvt * +alawtoulaw_new () +{ + struct ulaw_encoder_pvt *tmp; + tmp = malloc (sizeof (struct ulaw_encoder_pvt)); + if (tmp) + { + memset(tmp, 0, sizeof(*tmp)); + tmp->tail = 0; + localusecnt++; + ast_update_use_count (); + } + return (struct ast_translator_pvt *) tmp; +} + +static struct ast_translator_pvt * +ulawtoalaw_new () +{ + struct alaw_encoder_pvt *tmp; + tmp = malloc (sizeof (struct alaw_encoder_pvt)); + if (tmp) + { + memset(tmp, 0, sizeof(*tmp)); + localusecnt++; + ast_update_use_count (); + tmp->tail = 0; + } + return (struct ast_translator_pvt *) tmp; +} + +static int +alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) +{ + struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt; + int x; + unsigned char *b; + + if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + + /* Reset ssindex and signal to frame's specified values */ + b = f->data; + for (x=0;xdatalen;x++) + tmp->outbuf[tmp->tail + x] = a2mu[b[x]]; + + tmp->tail += f->datalen; + return 0; +} + +static struct ast_frame * +alawtoulaw_frameout (struct ast_translator_pvt *pvt) +{ + struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt; + + if (!tmp->tail) + return NULL; + + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_ULAW; + tmp->f.datalen = tmp->tail; + tmp->f.timelen = tmp->tail / 8; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->outbuf; + tmp->tail = 0; + return &tmp->f; +} + +static int +ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) +{ + struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt; + int x; + unsigned char *s; + if (tmp->tail + f->datalen >= sizeof(tmp->outbuf)) + { + ast_log (LOG_WARNING, "Out of buffer space\n"); + return -1; + } + s = f->data; + for (x=0;xdatalen;x++) + tmp->outbuf[x+tmp->tail] = mu2a[s[x]]; + tmp->tail += f->datalen; + return 0; +} + +/* + * LinToalaw_FrameOut + * Convert a buffer of raw 16-bit signed linear PCM to a buffer + * of 4-bit alaw packed two to a byte (Big Endian). + * + * Results: + * Foo + * + * Side effects: + * Leftover inbuf data gets packed, tail gets updated. + */ + +static struct ast_frame * +ulawtoalaw_frameout (struct ast_translator_pvt *pvt) +{ + struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt; + + if (tmp->tail) { + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_ALAW; + tmp->f.timelen = tmp->tail / 8; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->outbuf; + tmp->f.datalen = tmp->tail; + tmp->tail = 0; + return &tmp->f; + } else return NULL; +} + + +/* + * alawToLin_Sample + */ + +static struct ast_frame * +alawtoulaw_sample () +{ + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_ALAW; + f.datalen = sizeof (ulaw_slin_ex); + f.timelen = sizeof(ulaw_slin_ex) / 8; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = ulaw_slin_ex; + return &f; +} + +static struct ast_frame * +ulawtoalaw_sample () +{ + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_ULAW; + f.datalen = sizeof (ulaw_slin_ex); + f.timelen = sizeof(ulaw_slin_ex) / 8; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = ulaw_slin_ex; + return &f; +} + + +/* + * alaw_Destroy + * Destroys a private workspace. + * + * Results: + * It's gone! + * + * Side effects: + * None. + */ + +static void +alaw_destroy (struct ast_translator_pvt *pvt) +{ + free (pvt); + localusecnt--; + ast_update_use_count (); +} + +/* + * The complete translator for alawToLin. + */ + +static struct ast_translator alawtoulaw = { + "alawtoulaw", + AST_FORMAT_ALAW, + AST_FORMAT_ULAW, + alawtoulaw_new, + alawtoulaw_framein, + alawtoulaw_frameout, + alaw_destroy, + /* NULL */ + alawtoulaw_sample +}; + +/* + * The complete translator for LinToalaw. + */ + +static struct ast_translator ulawtoalaw = { + "ulawtoalaw", + AST_FORMAT_ULAW, + AST_FORMAT_ALAW, + ulawtoalaw_new, + ulawtoalaw_framein, + ulawtoalaw_frameout, + alaw_destroy, + /* NULL */ + ulawtoalaw_sample +}; + +int +unload_module (void) +{ + int res; + ast_pthread_mutex_lock (&localuser_lock); + res = ast_unregister_translator (&ulawtoalaw); + if (!res) + res = ast_unregister_translator (&alawtoulaw); + if (localusecnt) + res = -1; + ast_pthread_mutex_unlock (&localuser_lock); + return res; +} + +int +load_module (void) +{ + int res; + int x; + for (x=0;x<256;x++) { + mu2a[x] = AST_LIN2A(AST_MULAW(x)); + a2mu[x] = AST_LIN2MU(AST_ALAW(x)); + } + res = ast_register_translator (&alawtoulaw); + if (!res) + res = ast_register_translator (&ulawtoalaw); + else + ast_unregister_translator (&alawtoulaw); + return res; +} + +/* + * Return a description of this module. + */ + +char * +description (void) +{ + return tdesc; +} + +int +usecount (void) +{ + int res; + STANDARD_USECOUNT (res); + return res; +} + +char * +key () +{ + return ASTERISK_GPL_KEY; +} -- cgit v1.2.3