From: Peter Lemenkov <lemenkov@gmail.com>
Date: Tue, 20 Nov 2012 12:50:24 +0400
Subject: [PATCH] Use bcg729 as a underlying library for g.729 plugin
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 45afb91..d098fc4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,6 +34,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)
@@ -129,6 +130,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 1d3662d..1ef710d 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 4e0131e..65a4708 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, 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