| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-10-14 05:15:48 +00:00
										 |  |  |  * The iLBC code is from The IETF code base and is copyright The Internet Society (2004) | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-01-21 07:06:25 +00:00
										 |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-10-14 05:15:48 +00:00
										 |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-26 13:03:17 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-26 13:03:17 +00:00
										 |  |  |  * \brief Translate between signed linear and Internet Low Bitrate Codec | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * \ingroup codecs | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 17:10:28 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<defaultenabled>no</defaultenabled> | 
					
						
							|  |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:12:19 +00:00
										 |  |  | #include "asterisk/translate.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							| 
									
										
										
										
											2006-01-21 08:45:39 +00:00
										 |  |  | #include "asterisk/utils.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:12:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | #include "ilbc/iLBC_encode.h"
 | 
					
						
							|  |  |  | #include "ilbc/iLBC_decode.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define USE_ILBC_ENHANCER	0
 | 
					
						
							| 
									
										
										
										
											2004-10-14 05:15:48 +00:00
										 |  |  | #define ILBC_MS 			30
 | 
					
						
							|  |  |  | /* #define ILBC_MS			20 */ | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | #define	ILBC_FRAME_LEN	50	/* apparently... */
 | 
					
						
							|  |  |  | #define	ILBC_SAMPLES	240	/* 30ms at 8000 hz */
 | 
					
						
							|  |  |  | #define	BUFFER_SAMPLES	8000
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-17 21:35:23 +00:00
										 |  |  | /* Sample frame data */ | 
					
						
							|  |  |  | #include "asterisk/slin.h"
 | 
					
						
							|  |  |  | #include "ex_ilbc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | struct ilbc_coder_pvt { | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	iLBC_Enc_Inst_t enc; | 
					
						
							|  |  |  | 	iLBC_Dec_Inst_t dec; | 
					
						
							|  |  |  | 	/* Enough to store a full second */ | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	int16_t buf[BUFFER_SAMPLES]; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-24 19:43:31 +00:00
										 |  |  | static int lintoilbc_new(struct ast_trans_pvt *pvt) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	struct ilbc_coder_pvt *tmp = pvt->pvt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	initEncode(&tmp->enc, ILBC_MS); | 
					
						
							| 
									
										
										
										
											2006-06-24 19:43:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-24 19:43:31 +00:00
										 |  |  | static int ilbctolin_new(struct ast_trans_pvt *pvt) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	struct ilbc_coder_pvt *tmp = pvt->pvt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER); | 
					
						
							| 
									
										
										
										
											2006-06-24 19:43:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | /*! \brief decode a frame and store in outbuf */ | 
					
						
							|  |  |  | static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	struct ilbc_coder_pvt *tmp = pvt->pvt; | 
					
						
							|  |  |  | 	int plc_mode = 1; /* 1 = normal data, 0 = plc */ | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	/* Assuming there's space left, decode into the current buffer at
 | 
					
						
							|  |  |  | 	   the tail location.  Read in as many frames as there are */ | 
					
						
							|  |  |  | 	int x,i; | 
					
						
							| 
									
										
										
										
											2008-06-26 17:06:17 +00:00
										 |  |  | 	int16_t *dst = pvt->outbuf.i16; | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	float tmpf[ILBC_SAMPLES]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-06 17:22:31 +00:00
										 |  |  | 	if (!f->data.ptr && f->datalen) { | 
					
						
							| 
									
										
										
										
											2009-11-06 17:09:01 +00:00
										 |  |  | 		ast_log(LOG_DEBUG, "issue 16070, ILIB ERROR. data = NULL datalen = %d src = %s\n", f->datalen, f->src ? f->src : "no src set"); | 
					
						
							|  |  |  | 		f->datalen = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	if (f->datalen == 0) { /* native PLC, set fake f->datalen and clear plc_mode */ | 
					
						
							|  |  |  | 		f->datalen = ILBC_FRAME_LEN; | 
					
						
							|  |  |  | 		f->samples = ILBC_SAMPLES; | 
					
						
							|  |  |  | 		plc_mode = 0;	/* do native plc */ | 
					
						
							|  |  |  | 		pvt->samples += ILBC_SAMPLES; | 
					
						
							| 
									
										
										
										
											2005-03-17 21:30:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	if (f->datalen % ILBC_FRAME_LEN) { | 
					
						
							| 
									
										
										
										
											2003-04-17 14:51:49 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Huh?  An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen); | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	for (x=0; x < f->datalen ; x += ILBC_FRAME_LEN) { | 
					
						
							|  |  |  | 		if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) {	 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Out of buffer space\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		}		 | 
					
						
							| 
									
										
										
										
											2008-06-10 19:03:11 +00:00
										 |  |  | 		iLBC_decode(tmpf, plc_mode ? f->data.ptr + x : NULL, &tmp->dec, plc_mode); | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 		for ( i=0; i < ILBC_SAMPLES; i++) | 
					
						
							|  |  |  | 			dst[pvt->samples + i] = tmpf[i]; | 
					
						
							|  |  |  | 		pvt->samples += ILBC_SAMPLES; | 
					
						
							|  |  |  | 		pvt->datalen += 2*ILBC_SAMPLES; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | /*! \brief store a frame into a temporary buffer, for later decoding */ | 
					
						
							|  |  |  | static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	struct ilbc_coder_pvt *tmp = pvt->pvt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	/* Just add the frames to our stream */ | 
					
						
							|  |  |  | 	/* XXX We should look at how old the rest of our stream is, and if it
 | 
					
						
							|  |  |  | 	   is too old, then we should overwrite it entirely, otherwise we can | 
					
						
							|  |  |  | 	   get artifacts of earlier talk that do not belong */ | 
					
						
							| 
									
										
										
										
											2008-06-10 19:03:11 +00:00
										 |  |  | 	memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen); | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	pvt->samples += f->samples; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | /*! \brief encode the temporary buffer and generate a frame */ | 
					
						
							|  |  |  | static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	struct ilbc_coder_pvt *tmp = pvt->pvt; | 
					
						
							|  |  |  | 	int datalen = 0; | 
					
						
							|  |  |  | 	int samples = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	/* We can't work on anything less than a frame in size */ | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	if (pvt->samples < ILBC_SAMPLES) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	while (pvt->samples >= ILBC_SAMPLES) { | 
					
						
							|  |  |  | 		float tmpf[ILBC_SAMPLES]; | 
					
						
							|  |  |  | 		int i; | 
					
						
							| 
									
										
										
										
											2006-09-08 21:33:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 		/* Encode a frame of data */ | 
					
						
							| 
									
										
										
										
											2006-09-08 21:33:32 +00:00
										 |  |  | 		for (i = 0 ; i < ILBC_SAMPLES ; i++) | 
					
						
							|  |  |  | 			tmpf[i] = tmp->buf[samples + i]; | 
					
						
							| 
									
										
										
										
											2008-06-26 17:06:17 +00:00
										 |  |  | 		iLBC_encode( pvt->outbuf.uc + datalen, tmpf, &tmp->enc); | 
					
						
							| 
									
										
										
										
											2006-09-08 21:33:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 		datalen += ILBC_FRAME_LEN; | 
					
						
							|  |  |  | 		samples += ILBC_SAMPLES; | 
					
						
							|  |  |  | 		pvt->samples -= ILBC_SAMPLES; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-08 21:33:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Move the data at the end of the buffer to the front */ | 
					
						
							|  |  |  | 	if (pvt->samples) | 
					
						
							|  |  |  | 		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	return ast_trans_frameout(pvt, datalen, samples); | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | static struct ast_translator ilbctolin = { | 
					
						
							|  |  |  | 	.name = "ilbctolin",  | 
					
						
							|  |  |  | 	.srcfmt = AST_FORMAT_ILBC, | 
					
						
							|  |  |  | 	.dstfmt = AST_FORMAT_SLINEAR, | 
					
						
							|  |  |  | 	.newpvt = ilbctolin_new, | 
					
						
							|  |  |  | 	.framein = ilbctolin_framein, | 
					
						
							| 
									
										
										
										
											2008-10-17 21:35:23 +00:00
										 |  |  | 	.sample = ilbc_sample, | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	.desc_size = sizeof(struct ilbc_coder_pvt), | 
					
						
							|  |  |  | 	.buf_size = BUFFER_SAMPLES * 2, | 
					
						
							| 
									
										
										
										
											2007-05-24 15:28:29 +00:00
										 |  |  | 	.native_plc = 1, | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_translator lintoilbc = { | 
					
						
							|  |  |  | 	.name = "lintoilbc",  | 
					
						
							|  |  |  | 	.srcfmt = AST_FORMAT_SLINEAR, | 
					
						
							|  |  |  | 	.dstfmt = AST_FORMAT_ILBC, | 
					
						
							|  |  |  | 	.newpvt = lintoilbc_new, | 
					
						
							|  |  |  | 	.framein = lintoilbc_framein, | 
					
						
							|  |  |  | 	.frameout = lintoilbc_frameout, | 
					
						
							| 
									
										
										
										
											2008-10-17 21:35:23 +00:00
										 |  |  | 	.sample = slin8_sample, | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	.desc_size = sizeof(struct ilbc_coder_pvt), | 
					
						
							|  |  |  | 	.buf_size = (BUFFER_SAMPLES * ILBC_FRAME_LEN + ILBC_SAMPLES - 1) / ILBC_SAMPLES, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	res = ast_unregister_translator(&lintoilbc); | 
					
						
							| 
									
										
										
										
											2006-04-08 21:40:57 +00:00
										 |  |  | 	res |= ast_unregister_translator(&ilbctolin); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	res = ast_register_translator(&ilbctolin); | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	if (!res)  | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 		res=ast_register_translator(&lintoilbc); | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ast_unregister_translator(&ilbctolin); | 
					
						
							| 
									
										
										
										
											2007-10-31 19:24:29 +00:00
										 |  |  | 	if (res) | 
					
						
							|  |  |  | 		return AST_MODULE_LOAD_FAILURE; | 
					
						
							|  |  |  | 	return AST_MODULE_LOAD_SUCCESS; | 
					
						
							| 
									
										
										
										
											2003-04-15 04:36:52 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-14 14:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "iLBC Coder/Decoder"); |