Blob Blame Raw
From e6fa8fa4578175314eddd8a48dd4f19c9fa1e5b6 Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov@gmail.com>
Date: Tue, 20 Nov 2012 12:50:24 +0400
Subject: [PATCH 18/18] Use bcg729 as a underlying library for g.729 plugin

Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
---
 CMakeLists.txt                   |   8 +
 cmake/FindBcg729.cmake           |  17 ++
 core/plug-in/CMakeLists.txt      |   4 +-
 core/plug-in/g729/CMakeLists.txt |   2 +-
 core/plug-in/g729/g729.c         | 334 +++++----------------------------------
 5 files changed, 67 insertions(+), 298 deletions(-)
 create mode 100644 cmake/FindBcg729.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e4d81e..3723648 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ OPTION(SEMS_USE_LIBSAMPLERATE "Build with libsamplerate" OFF)
 OPTION(SEMS_USE_ZRTP          "Build with ZRTP" OFF)
 OPTION(SEMS_USE_MP3           "Build with Lame MP3" OFF)
 OPTION(SEMS_USE_ILBC          "Build with iLBC library (fallback to bundled)" ON)
+OPTION(SEMS_USE_G729          "Build with bcg729 library" OFF)
 OPTION(SEMS_USE_TTS           "Build with Text-to-speech support (requires Flite)" OFF)
 OPTION(SEMS_USE_OPENSSL       "Build with OpenSSL" OFF)
 OPTION(SEMS_USE_MONITORING    "Build with monitoring support" OFF)
@@ -125,6 +126,13 @@ ELSE(SEMS_USE_ILBC)
 	MESSAGE(STATUS "Uusing iLBC library: NO")
 ENDIF(SEMS_USE_ILBC)
 
+IF(SEMS_USE_G729)
+	FIND_PACKAGE(Bcg729)
+	MESSAGE(STATUS "Using bcg729 library: YES")
+ELSE(SEMS_USE_G729)
+	MESSAGE(STATUS "Using bcg729 library: NO (default)")
+ENDIF(SEMS_USE_G729)
+
 # build in support for monitoring?
 IF(SEMS_USE_MONITORING)
 	MESSAGE(STATUS "Enable monitoring: YES")
diff --git a/cmake/FindBcg729.cmake b/cmake/FindBcg729.cmake
new file mode 100644
index 0000000..31dbfb7
--- /dev/null
+++ b/cmake/FindBcg729.cmake
@@ -0,0 +1,17 @@
+FIND_PATH(BCG729_INCLUDE_DIR bcg729/decoder.h)
+FIND_LIBRARY(BCG729_LIBRARIES NAMES bcg729)
+
+IF(BCG729_INCLUDE_DIR AND BCG729_LIBRARIES)
+	SET(BCG729_FOUND TRUE)
+ENDIF(BCG729_INCLUDE_DIR AND BCG729_LIBRARIES)
+
+IF(BCG729_FOUND)
+	IF (NOT Bcg729_FIND_QUIETLY)
+		MESSAGE(STATUS "Found bcg729 includes:	${BCG729_INCLUDE_DIR}/bcg729/decoder.h")
+		MESSAGE(STATUS "Found bcg729 library: ${BCG729_LIBRARIES}")
+	ENDIF (NOT Bcg729_FIND_QUIETLY)
+ELSE(BCG729_FOUND)
+	IF (Bcg729_FIND_REQUIRED)
+		MESSAGE(FATAL_ERROR "Could NOT find bcg729 development files")
+	ENDIF (Bcg729_FIND_REQUIRED)
+ENDIF(BCG729_FOUND)
diff --git a/core/plug-in/CMakeLists.txt b/core/plug-in/CMakeLists.txt
index aff103c..a490b74 100644
--- a/core/plug-in/CMakeLists.txt
+++ b/core/plug-in/CMakeLists.txt
@@ -3,7 +3,9 @@ ADD_SUBDIRECTORY (echo)
 IF(SEMS_USE_SPANDSP)
 	ADD_SUBDIRECTORY (g722)
 ENDIF(SEMS_USE_SPANDSP)
-#ADD_SUBDIRECTORY (g729)
+IF(SEMS_USE_G729)
+	ADD_SUBDIRECTORY (g729)
+ENDIF(SEMS_USE_G729)
 IF(GSM_FOUND)
 	ADD_SUBDIRECTORY (gsm)
 ENDIF(GSM_FOUND)
diff --git a/core/plug-in/g729/CMakeLists.txt b/core/plug-in/g729/CMakeLists.txt
index 1d60ba9..b70cd6e 100644
--- a/core/plug-in/g729/CMakeLists.txt
+++ b/core/plug-in/g729/CMakeLists.txt
@@ -3,7 +3,7 @@ g729.c
 )
 
 SET(sems_module_name g729)
-SET(sems_module_libs speech core)
+SET(sems_module_libs bcg729)
 SET(g729_doc_files Readme.g729.txt)
 INCLUDE(${CMAKE_SOURCE_DIR}/cmake/module.rules.txt)
 INCLUDE(${CMAKE_SOURCE_DIR}/cmake/doc.rules.txt)
diff --git a/core/plug-in/g729/g729.c b/core/plug-in/g729/g729.c
index a850345..bd2c973 100644
--- a/core/plug-in/g729/g729.c
+++ b/core/plug-in/g729/g729.c
@@ -28,27 +28,16 @@
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
- Notes:
-
- This is a wrapper for Intel IPP 0.6 G729 codec.
-
 */
 
-#ifndef TEST
 #include "../../log.h"
 #include <stdio.h>
 #include "amci.h"
 #include "codecs.h"
-#else
-#include <stdio.h>
-#define ERROR  printf
-#endif
-
 
 #include <stdlib.h>
-#include <usc.h>
-
+#include <bcg729/decoder.h>
+#include <bcg729/encoder.h>
 
 static int pcm16_2_g729(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, 
 			unsigned int channels, unsigned int rate, long h_codec );
@@ -66,7 +55,6 @@ static unsigned int g729_samples2bytes(long, unsigned int);
 #define G729_BYTES_PER_FRAME     10
 #define G729_SAMPLES_PER_FRAME   10
 
-#ifndef TEST 
 BEGIN_EXPORTS( "g729", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY)
 
     BEGIN_CODECS
@@ -75,7 +63,7 @@ BEGIN_EXPORTS( "g729", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY)
             g729_bytes2samples, g729_samples2bytes
           )
     END_CODECS
-    
+
     BEGIN_PAYLOADS
       PAYLOAD( G729_PAYLOAD_ID, "G729", 8000, 1, CODEC_G729, AMCI_PT_AUDIO_FRAME )
     END_PAYLOADS
@@ -85,135 +73,21 @@ BEGIN_EXPORTS( "g729", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY)
 
 END_EXPORTS
 
-#endif
-
-struct stream
-{
-  USC_Handle  handle;
-  int nBanks;
-  USC_MemBank*  banks;
-};
-
-struct G729_codec 
+struct G729_codec
 {
-  struct  stream  dec, enc;
-  USC_CodecInfo pInfo;  
+  bcg729DecoderChannelContextStruct* dec;
+  bcg729EncoderChannelContextStruct* enc;
 };
 
 
-extern USC_Fxns USC_G729I_Fxns;
-USC_Fxns *fns = &USC_G729I_Fxns; 
-
-static int 
-stream_alloc(USC_CodecInfo *info, struct stream *md, const char *name)  
-{
-  
-  int i;
-
-  if (USC_NoError != fns->std.NumAlloc(&info->params, &md->nBanks))
-    {
-      ERROR("g729_stream_alloc: can't query memory reqirements for %s\n", name);
-      return -1;
-    }
-
-  /* allocate memory for memory bank table */
-  md->banks  =  (USC_MemBank*)malloc(sizeof(USC_MemBank)*md->nBanks);
-  
-  /* Query how big has to be each block */
-  if (USC_NoError != fns->std.MemAlloc(&info->params, md->banks))
-    {
-      ERROR("g729_stream_alloc: can't query memory bank size for %s\n", name);
-      return -1;
-    }
- 
-
-    /* allocate memory for each block */
-  for(i=0; i<md->nBanks; i++)
-    {
-        md->banks[i].pMem = (char*)malloc(md->banks[i].nbytes);
-    }
-   
-  return 0;
-}
-
-static void
-stream_free(struct stream *st)
-{
-  int i;
-
-  for(i = 0; i < st->nBanks; i++)
-    free(st->banks[i].pMem);
-
-  free(st->banks);
-
-}
-
-
-static int
-stream_create(USC_CodecInfo *info, struct stream *st, const char *name)
-{
-   if (stream_alloc(info, st, name))
-      {
-	return -1;
-      }
-
-    /* Create encoder instance */
-    if(USC_NoError != fns->std.Init(&info->params, st->banks, &st->handle))
-      {
-	ERROR("g729_stream_create: can't intialize stream %s\n", name);
-	stream_free(st);
-	return -1;
-      }
-
-    return 0;
-}
-
-
-static void
-stream_destroy(struct stream *st)
-{
-  stream_free(st);
-}
-
-
 long g729_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
 {
-    USC_CodecInfo pInfo;  
     struct G729_codec *codec;
 
-
-    if (USC_NoError != fns->std.GetInfo((USC_Handle)NULL, &pInfo))
-      {
-	ERROR("g729: Can't query codec info\n");
-	return (0);
-      }
-  
-
-    pInfo.params.direction = 0;             /* Direction: encode */
-    pInfo.params.modes.vad = 0;         /* Suppress a silence compression */
-    pInfo.params.law = 0;                    /* Linear PCM input */
-    pInfo.params.modes.bitrate = 8000; /* pInfo.pRateTbl[pInfo.nRates-1].bitrate; */     /* Set highest bitrate */
-
-
     codec = calloc(sizeof(struct G729_codec), 1);
+    codec->enc = initBcg729EncoderChannel();
+    codec->dec = initBcg729DecoderChannel();
 
-    if (stream_create(&pInfo, &codec->enc, "encoder"))
-      {
-	free(codec);
-	return 0;
-      }
-     
-
-    pInfo.params.direction = 1;             /* Direction:  decode */
-  
-    if (stream_create(&pInfo, &codec->dec, "decoder"))
-      {
-	stream_destroy(&codec->enc);
-	free(codec);
-	return 0;
-      }
-
-    codec->pInfo = pInfo;
     return (long) codec;
 }
 
@@ -226,8 +100,8 @@ g729_destroy(long h_codec)
     if (!h_codec)
       return;
 
-    stream_destroy(&codec->dec);
-    stream_destroy(&codec->enc);
+    closeBcg729DecoderChannel(codec->dec);
+    closeBcg729EncoderChannel(codec->enc);
     free(codec);
 }
 
@@ -236,98 +110,54 @@ g729_destroy(long h_codec)
 static int pcm16_2_g729(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, 
 			unsigned int channels, unsigned int rate, long h_codec )
 {
-    div_t blocks;
     struct G729_codec *codec = (struct G729_codec *) h_codec;
     int out_size = 0;
-    int err;
 
     if (!h_codec)
       return -1;
-    
-    blocks = div(size, codec->pInfo.params.framesize);
-
-    if (blocks.rem)
-      {
-	ERROR("pcm16_2_G729: number of blocks should be integral (block size = %d)\n",
-	      codec->pInfo.params.framesize);
-	return -1;
-      }
 
-   
-
-    while(size >= codec->pInfo.params.framesize) 
-      {
-        USC_PCMStream in;
-        USC_Bitstream out;
-   
+    if (size % 160 != 0){
+       ERROR("pcm16_2_g729: number of blocks should be integral (block size = 160)\n");
+       return -1;
+    }
 
-        /* Set input stream params */
-        in.bitrate = codec->pInfo.params.modes.bitrate;
-        in.nbytes = size;
-        in.pBuffer = (char*)in_buf;
-        in.pcmType = codec->pInfo.params.pcmType;
+    while(size >= 160){
+        /* Encode a frame  */
+        bcg729Encoder(codec->enc, in_buf, out_buf);
 
-        /* Set output buffer */
-        out.pBuffer = (char*)out_buf;
+	size -= 160;
+	in_buf += 160;
 
-        /* Encode a frame  */
-	err = fns->Encode (codec->enc.handle, &in, &out);
-        if (USC_NoError != err)
-	  {
-	    ERROR("pcm16_2_G729: error %d encoding\n", err);
-	    return -1;
-	  }
-    
-	size -= in.nbytes;
-	in_buf += in.nbytes;
-
-	out_buf += out.nbytes;
-	out_size += out.nbytes;
-      }
+	out_buf += 10;
+	out_size += 10;
+    }
 
     return out_size;
 }
 
-static int g729_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, 
+static int g729_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
 		       unsigned int channels, unsigned int rate, long h_codec )
 {
-  /* div_t blocks; */
     unsigned int out_size = 0;
-    int frameSize = 0;
-    int x;
     struct G729_codec *codec = (struct G729_codec *) h_codec;
-    int err;
 
     if (!h_codec)
       return -1;
 
-    for(x = 0; x < size; x += frameSize) 
-      {
-        USC_PCMStream out;
-        USC_Bitstream in;
-	
-	
-	in.pBuffer = (char*)in_buf;
-	in.nbytes = size;
-	in.bitrate = codec->pInfo.params.modes.bitrate;
-	in.frametype = 3;
-
-	out.pcmType = codec->pInfo.params.pcmType;
-	out.pBuffer = (char*)out_buf;
-
-
-	err = fns->Decode (codec->dec.handle, &in, &out);
-	if (USC_NoError != err)
-	  {
-	    ERROR("g729_2_pcm16: error %d decoding data\n", err);
-	    break;
-	  }
-
-	in_buf += in.nbytes;
-	frameSize = in.nbytes;
-
-	out_buf += out.nbytes;
-	out_size += out.nbytes;
+    if (size % 10 != 0){
+       ERROR("g729_2_pcm16: number of blocks should be integral (block size = 10)\n");
+       return -1;
+    }
+
+    while(size >= 10){
+        /* Encode a frame  */
+        bcg729Decoder(codec->dec, in_buf, 0, out_buf);
+
+	in_buf += 10;
+	size -= 10;
+
+	out_buf += 160;
+	out_size += 160;
       }
 
     return out_size;
@@ -338,93 +168,5 @@ static unsigned int g729_bytes2samples(long h_codec, unsigned int num_bytes) {
 }
 
 static unsigned int g729_samples2bytes(long h_codec, unsigned int num_samples) {
-  return G729_BYTES_PER_FRAME * num_samples /  G729_SAMPLES_PER_FRAME; 
-}
-
-#ifdef TEST
-#define N 160
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int inpcm[N];
-unsigned char outg729[1024];
-int outpcm[N];
-
-
-void encodeFile(const char *iname, const char *oname)
-{
-  int ifd = open(iname, O_RDONLY);
-  int ofd = open(oname, O_WRONLY|O_CREAT, 0666);
-  short  ibuf[ 2 * 8000/100 ];
-  unsigned char obuf[1024];
-  int h = g729_create();
-
-  int ilen, olen;
-
-  while(0 <= (ilen = read(ifd, ibuf, sizeof(ibuf))))
-    {
-      olen = pcm16_2_g729(obuf, ibuf, ilen, 1, 8000, h);
-
-      if (olen <= 0)
-	break;
-
-      write(ofd, obuf, olen);
-    }
-
-  g729_destroy(h);
-  close(ofd);
-  close(ifd);
-}
-	
-	      
-
-  
-void decodeFile(const char *iname, const char *oname)
-{
-  int ifd = open(iname, O_RDONLY);
-  int ofd = open(oname, O_WRONLY|O_CREAT, 0666);
-  short  obuf[ 2 * 8000/100 ];
-  unsigned char ibuf[20];
-  int h = g729_create();
-
-  int ilen, olen;
-
-  while(0 <= (ilen = read(ifd, ibuf, sizeof(ibuf))))
-    {
-      olen = g729_2_pcm16(obuf, ibuf, ilen, 1, 8000, h);
-
-      if (olen <= 0)
-	break;
-
-      write(ofd, obuf, olen);
-    }
-
-  g729_destroy(h);
-  close(ofd);
-  close(ifd);
+  return G729_BYTES_PER_FRAME * num_samples /  G729_SAMPLES_PER_FRAME;
 }
-  
-
-int main(int argc, char *argv[])
-{
-
-  if (!strcmp(argv[1], "-e"))
-    {
-      printf("encoding %s to %s\n", argv[2], argv[3]);
-      encodeFile(argv[2], argv[3]);
-    }
-  else if (!strcmp(argv[1], "-d"))
-    {
-      printf("decoding %s to %s\n", argv[2], argv[3]);
-      decodeFile(argv[2], argv[3]);
-    }
-
-   
-   return(0);
-  
-
-
-} 
-#endif
-- 
1.8.0