[Freeswitch-svn] [commit] r2448 - freeswitch/trunk/src/mod/codecs/mod_g726

Freeswitch SVN anthm at freeswitch.org
Wed Aug 30 10:49:14 EDT 2006


Author: anthm
Date: Wed Aug 30 10:49:13 2006
New Revision: 2448

Modified:
   freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c

Log:
wip

Modified: freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c
==============================================================================
--- freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c	(original)
+++ freeswitch/trunk/src/mod/codecs/mod_g726/mod_g726.c	Wed Aug 30 10:49:13 2006
@@ -31,6 +31,7 @@
  */  
 #include "switch.h"
 #include "g72x.h"
+#define BITS_IN_A_BYTE 8
 
 static const char modname[] = "mod_g726";
 
@@ -38,8 +39,14 @@
 typedef struct {
 	g726_state context;
 	uint8_t buf[5];
+	uint8_t *ptr;
 	uint8_t bits_per_frame;
 	uint8_t bits;
+	uint8_t bbits;
+	uint8_t d_bits;
+	uint8_t d_bbits;
+	uint8_t dcount;
+	uint8_t save;
 } g726_handle_t;
 
 static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag_t flags,
@@ -57,6 +64,7 @@
 		g726_init_state(&handle->context);
 		codec->private_info = handle;
 		handle->bits_per_frame = codec->implementation->bits_per_second / (codec->implementation->samples_per_second);
+		handle->ptr = handle->buf;
 		return SWITCH_STATUS_SUCCESS;
 	}
 }
@@ -117,19 +125,49 @@
 	if (decoded_data_len % len == 0) {
 		uint32_t new_len = 0;
 		int16_t *ddp = decoded_data;
-		//int8_t *edp = encoded_data;
+		uint8_t *edp = encoded_data;
 		int x;
 		uint32_t loops = decoded_data_len / (sizeof(*ddp));
 
 		for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
-#if 0
-			if (handle->buf & 0x80) {
-				edp[new_len++] = ((handle->buf & 0xf) << handle->bits_per_frame) | encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
-				handle->buf = 0;
+			int edata = encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
+
+			if (!handle->bbits) {
+				*handle->ptr = edata;
+			} else if ((handle->bbits + handle->bits_per_frame) <= BITS_IN_A_BYTE) {
+				*handle->ptr <<= handle->bits_per_frame;
+				*handle->ptr |= edata;
 			} else {
-				handle->buf = 0x80 | encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
+				int remain, next, rdata, ndata;
+
+				remain = BITS_IN_A_BYTE - handle->bits_per_frame;
+				next = handle->bits_per_frame - remain;
+				rdata = edata;
+				ndata = edata;
+
+				rdata >>= remain;
+				*handle->ptr <<= remain;
+				*handle->ptr |= rdata;
+
+				handle->ptr++;
+				
+				ndata &= (1 << next) - 1;
+				*handle->ptr = ndata;
+
+				handle->bbits = 0;
 			}
-#endif
+			handle->bits += handle->bits_per_frame;
+			handle->bbits += handle->bits_per_frame;
+
+			if ((handle->bits % BITS_IN_A_BYTE) == 0) {
+				int bytes = handle->bits / BITS_IN_A_BYTE, count;
+				for(count = 0; count < bytes; count++) {
+					edp[new_len++] = handle->buf[count];
+				}
+				handle->bits = handle->bbits = 0;
+				handle->ptr = handle->buf;
+				memset(handle->buf, 0, sizeof(handle->buf));
+			}
 			ddp++;
 		}
 
@@ -159,26 +197,28 @@
 										unsigned int *flag) 
 {
 
-	g726_state *context = codec->private_info;
-	uint32_t len = codec->implementation->bytes_per_frame;
+	g726_handle_t *handle = codec->private_info;
+	g726_state *context = &handle->context;
+	//uint32_t len = codec->implementation->bytes_per_frame;
 	uint32_t elen = codec->implementation->encoded_bytes_per_frame;
 	decoder_t decoder;
 
+
 	switch(elen) {
-	case 40:
+	case 100:
 		decoder = g726_40_decoder;
 		break;
-	case 32:
+	case 80:
 		decoder = g726_32_decoder;
 		break;
-	case 24:
+	case 60:
 		decoder = g726_24_decoder;
 		break;
-	case 16:
+	case 40:
 		decoder = g726_16_decoder;
 		break;
 	default:
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size!\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size %d!\n", elen);
 		return SWITCH_STATUS_FALSE;
 		break;
 	}
@@ -189,18 +229,54 @@
 	}
 
 
-	if (encoded_data_len % elen == 0) {
-		int loops = (int) encoded_data_len / elen;
-		char *edp = encoded_data;
+	{
+
+		int loops = ((int)encoded_data_len * BITS_IN_A_BYTE) / handle->bits_per_frame;
+		int8_t *edp = encoded_data;
 		int16_t *ddp = decoded_data;
 		int x;
 		uint32_t new_len = 0;
 
 		for (x = 0; x < loops && new_len < *decoded_data_len; x++) {
-			*(int16_t *)ddp = decoder(*(int *)edp, AUDIO_ENCODING_LINEAR, context);
-			ddp += len;
-			edp += elen;
-			new_len += len;
+			int in = 0;
+			int bits = 0;
+			int8_t over = 0;
+			int8_t under = 0;
+
+			if (handle->save) {
+				in = handle->save;
+				handle->save = 0;
+			}
+			
+			handle->d_bits += handle->bits_per_frame;
+			bits = handle->d_bbits + handle->bits_per_frame;
+
+			if (bits > BITS_IN_A_BYTE) {
+				int tmp;
+				over = bits - BITS_IN_A_BYTE;
+				under = handle->bits_per_frame - over;
+				handle->dcount = 0;
+				tmp = *edp >> (BITS_IN_A_BYTE - (handle->bits_per_frame * handle->dcount));
+				in = tmp >> over;
+				handle->save = tmp;
+				handle->save  &= (1 << under) - 1;
+				edp++;
+			} else if (bits == BITS_IN_A_BYTE) {
+				handle->d_bbits = 0;
+				in = *edp;
+				edp++;
+				handle->dcount = 0;
+			} else {
+				in |= *edp >> (BITS_IN_A_BYTE - (handle->bits_per_frame * handle->dcount));
+				handle->d_bbits = bits;
+			}
+
+			
+
+			handle->dcount++;
+
+			*ddp++ = decoder(in, AUDIO_ENCODING_LINEAR, context);
+			new_len += 2;
 		}
 
 		if (new_len <= *decoded_data_len) {
@@ -209,6 +285,7 @@
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!!\n");
 			return SWITCH_STATUS_FALSE;
 		}
+
 	}
 
 	return SWITCH_STATUS_SUCCESS;



More information about the Freeswitch-svn mailing list