From 4707a2e026e78a586038fa58614f3697e4daa558 Mon Sep 17 00:00:00 2001 From: Fabricio Santolin da Silva Date: Mon, 4 Apr 2022 15:27:49 +0200 Subject: [PATCH] TT#169904 Activate g729 Codec [gjover@sipwise.com: Adapted from sems-pbx. ] Signed-off-by: Guillem Jover Change-Id: I29c83dbb227eaef12a4ade9d5446d65db4c4a9c4 --- Makefile.defs | 2 +- core/plug-in/CMakeLists.txt | 2 +- core/plug-in/g729/CMakeLists.txt | 2 +- core/plug-in/g729/Makefile | 16 +- core/plug-in/g729/Readme.g729.txt | 56 +---- core/plug-in/g729/g729.c | 342 ++++-------------------------- debian/control | 1 + 7 files changed, 50 insertions(+), 371 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 49814477..3eb81085 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -79,7 +79,7 @@ USE_INTERNAL_RESAMPLER = yes # exclude some modules from compilation? # e.g. python modules: -exclude_core_modules = g729 silk +exclude_core_modules = silk #exclude_apps_modules = py_sems ivr mailbox pin_collect conf_auth mp3 examples # build in support for monitoring? diff --git a/core/plug-in/CMakeLists.txt b/core/plug-in/CMakeLists.txt index 1d3662de..6ce90fe0 100644 --- a/core/plug-in/CMakeLists.txt +++ b/core/plug-in/CMakeLists.txt @@ -3,7 +3,7 @@ ADD_SUBDIRECTORY (echo) IF(SEMS_USE_SPANDSP) ADD_SUBDIRECTORY (g722) ENDIF(SEMS_USE_SPANDSP) -#ADD_SUBDIRECTORY (g729) +ADD_SUBDIRECTORY (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 1d60ba9e..571b1564 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_LIBRARIES}) 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/Makefile b/core/plug-in/g729/Makefile index 1c8fb816..f12981f9 100644 --- a/core/plug-in/g729/Makefile +++ b/core/plug-in/g729/Makefile @@ -1,21 +1,7 @@ plug_in_name = g729 COREPATH =../.. -# adapt these paths to version/arch -IPPROOT?=/opt/intel/ipp/6.1.2.051/ia32/ -IPP_SAMPLES_PATH?=/opt/intel/ipp/ipp-samples/ -IPP_SAMPLES_ARCH?=linux32_gcc4 - -###### - -IPP_LIB_PATH=$(IPPROOT)sharedlib/ - -IPP_INC = -I$(IPP_SAMPLES_PATH)speech-codecs/core/usc/include -IPP_LIB ?= -L$(IPP_SAMPLES_PATH)speech-codecs/_bin/$(IPP_SAMPLES_ARCH)/lib -lspeech -lcore \ - -L$(IPP_LIB_PATH) -lippsc -lipps - -module_ldflags = $(IPP_LIB) -module_cflags = $(IPP_INC) +module_ldflags = -lbcg729 ifdef NOFPU module_cflags += -DNOFPU diff --git a/core/plug-in/g729/Readme.g729.txt b/core/plug-in/g729/Readme.g729.txt index cbd44b93..175151fd 100644 --- a/core/plug-in/g729/Readme.g729.txt +++ b/core/plug-in/g729/Readme.g729.txt @@ -1,56 +1,2 @@ - Intel IPP G.729 codec wrapper - ----------------------------- - - Copyright (c) 2007, Vadim Lebedev - Copyright (c) 2010, Stefan Sayer - - This is a wrapper for Intel IPP 0.6 G729 codec. - - How to build g729 module - ------------------------ - - 1. Get and install Intel IPP from: - http://software.intel.com/en-us/intel-ipp/ - (at least 3G disk space required) - - 2. Get IPP Code Samples (including USC) from - http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/ - Extract (preferably to /opt/intel/ipp/ipp-samples) - - 3. Build USC library - run build script in ipp-samples/speech-codecs - - 4. adapt paths in Makefile (especially IPP_SAMPLES_PATH/IPP_SAMPLES_ARCH) - or pass paths to make as in - $ IPP_SAMPLES_PATH=/path/to/ipp-samples/ \ - IPP_SAMPLES_ARCH=linux64_gcc4 \ - IPPROOT=/path/to/ipp/version/arch \ - make - - About Licensing - --------------- - - There is two distinct parts to G.729 licensing: The software licensing - and the codec (patents) licensing. - - A. Software licensing - - 1. The g729 codec wrapper code is licensed under simplified BSD license (see g729.c). - - 2. Intel IPP license is required to use Intel IPP software. - - 3. SEMS is licensed under GPL; the Intel IPP license is not a GPL compatible - license. Under the GPL, you may use (modify, compile, link, run, etc) SEMS code - included by the g729 module, but the GPL does NOT allow redistribution of - binaries linked with code licensed under the IPP license terms. - - If you are interested in distributing SEMS binaries with the g729 module - (g729.so), please contact info@iptel.org to obtain a commercial license (see - doc/COPYING for details). - - B. Codec licensing - - To use G.729 codec, in many countries you need to get a license to use the - patents (at least until 2016 or so). The G.729 patent pool is managed by - Sipro: http://www.sipro.com/ +Bcg729 codec wrapper for the opensource implementation of Belledonne Communications' ITU G729 Annex A/B speech codec. diff --git a/core/plug-in/g729/g729.c b/core/plug-in/g729/g729.c index d83f2709..63c3050d 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 ); @@ -63,7 +52,7 @@ static void g729_destroy(long h_codec); static unsigned int g729_bytes2samples(long, unsigned int); static unsigned int g729_samples2bytes(long, unsigned int); -static amci_codec_fmt_info_t[] gsm_fmt_description = { { AMCI_FMT_FRAME_LENGTH, 20 }, +static amci_codec_fmt_info_t g729_fmt_description[] = { { AMCI_FMT_FRAME_LENGTH, 20 }, { AMCI_FMT_FRAME_SIZE, 160 }, { AMCI_FMT_ENCODED_FRAME_SIZE, 33 }, { 0, 0 } @@ -72,8 +61,8 @@ static amci_codec_fmt_info_t[] gsm_fmt_description = { { AMCI_FMT_FRAME_LENGTH, #define G729_PAYLOAD_ID 18 #define G729_BYTES_PER_FRAME 10 #define G729_SAMPLES_PER_FRAME 10 +#define PCM_BYTES_PER_FRAME 160 -#ifndef TEST BEGIN_EXPORTS( "g729", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY) BEGIN_CODECS @@ -82,7 +71,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 @@ -92,136 +81,24 @@ 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, const char** format_parameters_out, 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(0 /* no VAT/DTX detection */); + 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; - } + *format_description = g729_fmt_description; - codec->pInfo = pInfo; return (long) codec; } @@ -234,8 +111,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); } @@ -244,98 +121,55 @@ 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; + unsigned int out_size = 0; 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 % PCM_BYTES_PER_FRAME != 0){ + ERROR("pcm16_2_g729: number of blocks should be integral (block size = %u)\n", PCM_BYTES_PER_FRAME); + 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 >= PCM_BYTES_PER_FRAME){ + /* Encode a frame */ + uint8_t olen; + bcg729Encoder(codec->enc, (int16_t*)in_buf, (uint8_t*)out_buf, &olen); - /* Set output buffer */ - out.pBuffer = (char*)out_buf; + size -= PCM_BYTES_PER_FRAME; + in_buf += PCM_BYTES_PER_FRAME; - /* 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 += olen; + out_size += olen; + } 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; + unsigned int out_size = 0; 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 % G729_BYTES_PER_FRAME != 0){ + ERROR("g729_2_pcm16: number of blocks should be integral (block size = %u)\n", G729_BYTES_PER_FRAME); + return -1; + } + + while(size >= G729_BYTES_PER_FRAME){ + /* Decode a frame */ + bcg729Decoder(codec->dec, in_buf, G729_BYTES_PER_FRAME, 0 /* no erasure */, 0 /* not SID */, 0 /* not RFC3389 */, (int16_t*)out_buf); + + size -= G729_BYTES_PER_FRAME; + in_buf += G729_BYTES_PER_FRAME; + + out_buf += PCM_BYTES_PER_FRAME; + out_size += PCM_BYTES_PER_FRAME; } return out_size; @@ -346,93 +180,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 diff --git a/debian/control b/debian/control index 2f774e5b..1ff00839 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Rules-Requires-Root: no Build-Depends: debhelper-compat (= 13), flite-dev, + libbcg729-dev, libcurl4-openssl-dev | libcurl4-gnutls-dev, libev-dev, libevent-dev (>= 2.1.12),