From e6fa8fa4578175314eddd8a48dd4f19c9fa1e5b6 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov 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 --- 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 #include "amci.h" #include "codecs.h" -#else -#include -#define ERROR printf -#endif - #include -#include - +#include +#include 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; inBanks; 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 -#include -#include - -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