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