TT#169904 Activate g729 Codec

[gjover@sipwise.com: Adapted from sems-pbx. ]

Signed-off-by: Guillem Jover <gjover@sipwise.com>
Change-Id: I29c83dbb227eaef12a4ade9d5446d65db4c4a9c4
mr13.5
Fabricio Santolin da Silva 4 years ago committed by Guillem Jover
parent 19a6502f16
commit 4707a2e026

@ -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?

@ -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)

@ -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)

@ -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

@ -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.

@ -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 );
@ -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; 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, 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 <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
debian/control vendored

@ -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),

Loading…
Cancel
Save